spring boot 整合security权限登录

原文参考:

http://wiki.jikexueyuan.com/project/spring-security/core-classes.html(组件介绍)

https://blog.csdn.net/code__code/article/details/53885510

https://blog.csdn.net/u012702547/article/details/54319508

在进行之前,首先要知道什么是 spring security 权限框架:

简介 ---- Spring Security是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架。它提供了一组可以在Spring应用上下文中配置的Bean,充分利用了Spring IoC,DI(控制反转Inversion of Control ,DI:Dependency Injection 依赖注入)和AOP(面向切面编程)功能,为应用系统提供声明式的安全访问控制功能,减少了为企业系统安全控制编写大量重复代码的工作。

优点 ----人们使用Spring Security有很多种原因,不过通常吸引他们的是在J2EE Servlet规范或EJB规范中找不到典型企业应用场景的解决方案。

特别要指出的是他们不能在WAR 或 EAR 级别进行移植。

这样,如果更换服务器环境,就要,在新的目标环境进行大量的工作,对应用系统进行重新配置安全。

使用Spring Security 解决了这些问题,也提供很多有用的,完全可以指定的其他安全特性。

可能知道,安全包括两个主要操作。

第一个被称为“认证”,是为用户建立一个他所声明的主体。主体一般是指用户,设备或可以在系统中执行动作的其他系统。

第二个叫“授权”,指的是一个用户能否在应用中执行某个操作,在到达授权判断之前,身份的主体已经由身份验证过程建立。

这些概念是通用的,不是Spring Security特有的。

身份验证层面,Spring Security广泛支持各种身份验证模式,这些验证模型绝大多数都由第三方提供,或者正在开发的有关标准机构提供的,例如 Internet Engineering Task Force.

作为补充,Spring Security 也提供了自己的一套验证功能。

Spring Security 目前支持认证一体化如下认证技术:

HTTP BASIC authentication headers (一个基于IEFT RFC 的标准)

HTTP Digest authentication headers (一个基于IEFT RFC 的标准)

HTTP X.509 client certificate exchange (一个基于IEFT RFC 的标准)

LDAP (一个非常常见的跨平台认证需要做法,特别是在大环境)

Form-based authentication (提供简单用户接口的需求)

OpenID authentication

Computer Associates Siteminder

JA-SIG Central Authentication Service (CAS,这是一个流行的开源单点登录系统)

Transparent authentication context propagation for Remote Method Invocation and HttpInvoker (一个Spring远程调用协议)

 

进入正题

ssh可以参考:http://www.blogjava.net/SpartaYew/archive/2011/06/15/350630.html

springboot参考:

https://blog.csdn.net/u283056051/article/details/55803855

https://www.jianshu.com/p/e6655328b211

 

今天使用 spring boot 整合 spring security

使用环境:

项目中使用:

第一步:导入pom,只要加入security的pom,拦截就会生效

org.springframework.boot

spring-boot-starter-security

org.springframework.security.oauth

spring-security-oauth2

(这里只要有红色这个主要的就可以用)

 

第二步:配置核心文件WebSecurityConfig(java文件就可以,要加入@Configuration启动注解,并继承WebSecurityConfigurerAdapter)

package com.mozi.hip.empi.web.config;

 

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.context.annotation.Configuration;

import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;

import org.springframework.security.config.annotation.web.builders.HttpSecurity;

import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;

import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

import org.springframework.security.core.userdetails.UserDetailsService;

import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

 

 

 

@Configuration

@EnableWebSecurity

//@EnableGlobalMethodSecurity(prePostEnabled = true)//开启security注解

public class WebSecurityConfig extends WebSecurityConfigurerAdapter{

@Autowired

private UserDetailsService userDetailsService;

 

@Autowired

LoginSuccessHandler loginSuccessHandler;

@Autowired

LoginFailureHandler loginFailureHandler;

 

@Override

protected void configure(HttpSecurity http) throws Exception {

http.csrf()

.disable()

.authorizeRequests()

//指定放开的路径,包括登录页面,样式路径,登录请求路径

.antMatchers("/login","/css/**","/images/**","/plugins/**","/scripts/**").permitAll()

//其他地址的访问均需验证权限

.anyRequest().authenticated()

.and()

.formLogin()

// 指定登陆页是login

.loginPage("/login")

.permitAll()

.successHandler(loginSuccessHandler)

.failureHandler(loginFailureHandler)

.and()

.logout()

.logoutUrl("/logout")

.logoutSuccessUrl("/login")

.permitAll()

.deleteCookies("remember-me")

// 数据库中必须存在名为persistence_logins的表

//.invalidateHttpSession(false)

.and()

// 登陆以后记住用户,下次自动登陆

.rememberMe()

// 两周有效

.tokenValiditySeconds(1209600);

// 指定登陆信息所使用的数据源

// .tokenRepository(tokenRepository);

}

@Autowired

public void configureGlobal(AuthenticationManagerBuilder auth)

throws Exception { //用户认证与密码认证

auth.userDetailsService(userDetailsService).passwordEncoder(

new BCryptPasswordEncoder());

auth.eraseCredentials(false);

}

}

上面我们用到了LoginSuccessHandler和LoginFailureHandler(自定义的)和粉色标注的自定义登录页面,这个页面要加入个启动类:

自定义跳转页面启动类MvcConfig:

package com.mozi.hip.empi.web.config;

 

import org.springframework.context.annotation.Configuration;

import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;

import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

 

@Configuration

public class MvcConfig extends WebMvcConfigurerAdapter{

@Override

public void addViewControllers(ViewControllerRegistry registry){

registry.addViewController("/login").setViewName("login");

}

}

LoginSuccessHandler:

package com.mozi.hip.empi.web.config;

 

import java.io.IOException;

 

 

import javax.servlet.ServletException;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

 

import org.springframework.security.core.Authentication;

import org.springframework.security.core.context.SecurityContextHolder;

import org.springframework.security.web.authentication.AuthenticationSuccessHandler;

import org.springframework.stereotype.Component;

 

import com.mozi.hip.core.domain.HipUser;

import com.mozi.hip.empi.web.domain.CurrentUser;

 

@Component

public class LoginSuccessHandler implements AuthenticationSuccessHandler{

 

@Override

public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,

Authentication authentication) throws IOException, ServletException {

// 获取当前用户(domain接收)

CurrentUser user = (CurrentUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();

System.out.println(user.toString());

//转发到index页面

response.sendRedirect(request.getContextPath() +"/index");

}

 

}

LoginFailureHandler:

package com.mozi.hip.empi.web.config;

 

import java.io.IOException;

 

import javax.servlet.ServletException;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

 

import org.springframework.security.core.AuthenticationException;

import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler;

import org.springframework.stereotype.Component;

 

 

@Component

public class LoginFailureHandler extends SimpleUrlAuthenticationFailureHandler{

public LoginFailureHandler() {

this.setDefaultFailureUrl("/login");

}

@Override

public void onAuthenticationFailure(HttpServletRequest request,

HttpServletResponse response, AuthenticationException exception)

throws IOException, ServletException {

/*保存登录日志*/

//saveLoginLog(request);

super.onAuthenticationFailure(request, response, exception);

}

}

第三步:(关键的部分)上面的是拦截部分,下面的是认证部分

如果想要上面websecurity的绿色认证部分起作用,我们还需要自定义一个类UserDetailServiceImpl(名字随意),这个类要实现UserDetailsService

package com.mozi.hip.empi.web.service.impl;

 

import java.util.ArrayList;

import java.util.HashSet;

import java.util.List;

import java.util.Set;

 

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.security.core.GrantedAuthority;

import org.springframework.security.core.authority.SimpleGrantedAuthority;

import org.springframework.security.core.userdetails.UserDetails;

import org.springframework.security.core.userdetails.UserDetailsService;

import org.springframework.security.core.userdetails.UsernameNotFoundException;

import org.springframework.stereotype.Component;

 

import com.mozi.hip.core.domain.HipRole;

import com.mozi.hip.core.domain.HipUser;

import com.mozi.hip.core.domain.HipUserRole;

import com.mozi.hip.empi.web.domain.CurrentUser;

import com.mozi.hip.empi.web.service.HipUserRoleService;

import com.mozi.hip.empi.web.service.HipUserService;

 

@Component

public class UserDetailServiceImpl implements UserDetailsService {

 

@Autowired

private HipUserService hipUserService;

@Autowired

private HipUserRoleService hipUserRoleService;

 

@Override

public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {

// 根据用户名查询对象

HipUser user = hipUserService.findLoginName(username);

if (user == null) {

throw new UsernameNotFoundException("没有找到用户,用户登录名: " + username);

} else {

List userRoles = hipUserRoleService.findByUserId(user.getUserId());

List authorities = buildUserAuthority(userRoles);

return (UserDetails) new CurrentUser(user, authorities);

}

}

 

private List buildUserAuthority(List userRoles) {

Set auths = new HashSet();

for (int i = 0; i < userRoles.size(); i++) {

auths.add(new SimpleGrantedAuthority(userRoles.get(i).getUserRoleId().toString()));

}

List result = new ArrayList(auths);

return result;

}

 

}

这里绿色部分需要加入俩个东西:CurrentUser 和 CurrentUserControllerAdvice

 

 

 

 

 

 

 

 

 

CurrentUserControllerAdvice:

package com.mozi.hip.empi.web.controller.advice;

 

import org.springframework.security.core.Authentication;

import org.springframework.web.bind.annotation.ControllerAdvice;

import org.springframework.web.bind.annotation.ModelAttribute;

 

import com.mozi.hip.empi.web.domain.CurrentUser;

 

 

/**

*

* @Title: CurrentUserControllerAdvice.java

* @Package: com.hokai.hiip.web.controller.advice

* @Description: session中用户信息

* @author Zhaoyan

* @date 2016年9月27日

*/

@ControllerAdvice

public class CurrentUserControllerAdvice {

 

@ModelAttribute("currentUser")

public CurrentUser getCurrentUser(Authentication authentication) {

return (authentication == null) ? null : (CurrentUser) authentication

.getPrincipal();

}

}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

CurrentUser :

package com.mozi.hip.empi.web.domain;

 

import java.util.List;

 

import org.springframework.security.core.GrantedAuthority;

 

import com.mozi.hip.core.domain.HipUser;

 

/**

* 当前用户返回到界面信息

* @author tianyp

*

2017年11月24日 下午4:05:30

* @see org.springframework.security.core.GrantedAuthority

* @version 1.0

*/

public class CurrentUser extends

org.springframework.security.core.userdetails.User {

 

private static final long serialVersionUID = 1L;

 

private HipUser hipuser;

 

public CurrentUser(HipUser hipuser, List authorities) {

super(hipuser.getLoginName(), hipuser.getPwd(), authorities);

this.hipuser = hipuser;

}

 

public HipUser getUser() {

return hipuser;

}

 

public Integer getId() {

return hipuser.getUserId();

}

 

public boolean isEnabled() {

return Boolean.parseBoolean(String.valueOf(hipuser.getEnableFlag())) == false;

}

public boolean isAccountNonLocked() {

return Boolean.parseBoolean(hipuser.getLockedFlag()) == false;

}

public boolean isAccountNonExpired() {

return Boolean.parseBoolean(hipuser.getExpiredFlag()) == false;

}

/*

* public Role getRole() { return user.getRole(); }

*/

@Override

public String toString() {

return "CurrentUser{" + "user=" + hipuser + "} " + super.toString();

}

}

以上,关键部分均已完成,所做是根据用户角色控制

整个部分实现与controller和页面基本无关,无页面和控制层也可以实现,这里注意误区

你可能感兴趣的:(开发技术,java,security)