springboot项目中使用Spring security做安全管理,自定义校验方法。
1. 自定义WebSecurityConfig 继承WebSecurityConfigurerAdapter,重写configure方法,注入自定义校验bean
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
//注入自定义校验类
auth.authenticationProvider(daoAuthenticationProvider());
}
//配置策略
@Override
protected void configure(HttpSecurity http) throws Exception { //配置策略
http.csrf().disable();
http.authorizeRequests().
//不用做拦截的路径
antMatchers("/static/**").permitAll().anyRequest().authenticated().
//使用form表单提交
and().formLogin()
//登录页面,可以自定义
.loginPage("/login").permitAll()
//校验成功后执行
.successHandler(loginSuccessHandler())
.and().logout().permitAll().invalidateHttpSession(true)
.logoutSuccessHandler(logoutSuccessHandler())
.and().sessionManagement().maximumSessions(10).expiredUrl("/login");
//添加自定义拦截器
http.addFilterAt(adminKaptchaAuthenticationProcessingFilter(), UsernamePasswordAuthenticationFilter.class);
}
//自定义校验类
DaoAuthenticationProvider daoAuthenticationProvider(){
DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider();
daoAuthenticationProvider.setUserDetailsService(springSecurityUserDetailsService);
return daoAuthenticationProvider;
}
//注入自定义拦截器属性
private MacAuthenticationProcessingFilter adminKaptchaAuthenticationProcessingFilter(){
MacAuthenticationProcessingFilter mac= new MacAuthenticationProcessingFilter();
mac.setAuthenticationManager(authenticationManagerBean());
mac.setSpringSecurityUserDetailsService(springSecurityUserDetailsService);
mac.setUsernameParameter("j_username");
mac.setPasswordParameter("j_password");
mac.setOsinfoParameter("j_pcosinfo");
mac.setAuthenticationFailureHandler(adminExceptionMappingAuthenticationFailureHandler());
mac.setAuthenticationSuccessHandler(adminSimpleUrlAuthenticationSuccessHandler());
return mac;
}
public SavedRequestAwareAuthenticationSuccessHandler adminSimpleUrlAuthenticationSuccessHandler(){
SavedRequestAwareAuthenticationSuccessHandler save= new SavedRequestAwareAuthenticationSuccessHandler();
//登录成功后页面跳转页面
save.setDefaultTargetUrl("/admin/index");
save.setAlwaysUseDefaultTargetUrl(true);
return save;
}
//错误类型,可以自定义
@Bean(name = {"adminExceptionMappingAuthenticationFailureHandler"})
public ExceptionMappingAuthenticationFailureHandler adminExceptionMappingAuthenticationFailureHandler(){
ExceptionMappingAuthenticationFailureHandler ex= new ExceptionMappingAuthenticationFailureHandler();
Map<String, String> failureUrlMap = new HashMap<>();
failureUrlMap.put("org.springframework.security.core.userdetails.UsernameNotFoundException","/admin/login?error=1");//<!-- 用户不存在 -->
failureUrlMap.put("org.springframework.security.authentication.BadCredentialsException","/admin/login?error=2");//<!-- 凭证错误(密码不正确) -->
failureUrlMap.put("org.springframework.security.authentication.DisabledException","/admin/login?error=3");//<!-- 用户不可用 -->
failureUrlMap.put("com.lymatrix.springmvc.KaptchaException","/admin/login?error=4");//<!-- 图形验证码出错 -->
failureUrlMap.put("org.springframework.security.core.AuthenticationException","/admin/login?error=5");
failureUrlMap.put("com.lymatrix.springmvc.MacException","/admin/login?error=6");//<!--MAC错误 add by lisc-->
ex.setExceptionMappings(failureUrlMap);
return ex;
}
/**
*登录验证
*/
public class MacAuthenticationProcessingFilter extends UsernamePasswordAuthenticationFilter {
....
....
//注入springSecurityUserDetailsService
//重写验证方法
@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
//如果是post请求
if(request.getContentType().startsWith(MediaType.APPLICATION_JSON_VALUE)){
UserDetails userDetails = springSecurityUserDetailsService.loadUserByUsersn(usersn);
UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(
userDetails.getUsername(), userDetails.getPassword());
setDetails(request, authRequest);
return this.getAuthenticationManager().authenticate(authRequest);
}else{
//如果是form表单请求
.....
.....
request.getSession().setAttribute("LoginUserName", username);
return super.attemptAuthentication(request, response);
}
springSecurityUserDetailsService需要实现UserDetailsService
@Service("springSecurityUserDetailsService")
public class SpringSecurityUserDetailsService implements UserDetailsService {
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
if(!StringUtil.isNullOrEmpty(username)){
User u = this.userService.getUserByName(username);
if(u == null){ /** */
int count = this.userService.getUserCount();
if(count == 0){
u = SystemInitialization.getVirtualAdminUser(username);
}
}
if(u != null){
//查询用户权限相关操作
Collection<GrantedAuthority> authorities = generateAuthorities(u);
Collection<GrantedAuthority> authorities1 = getMenutree(u);
authorities.addAll(authorities1);
u.setAuthorities(new HashSet<GrantedAuthority>(authorities));
return u;
}
}
throw new UsernameNotFoundException("找不到参数[username="+username+"]指定的用户信息。");
}
}
通过请求判断需要返回页面或者json
public class SavedRequestAwareAuthenticationSuccessHandler extends SimpleUrlAuthenticationSuccessHandler {
//核心方法
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
Authentication authentication) throws ServletException, IOException {
...
...
if(request.getContentType().startsWith(MediaType.APPLICATION_JSON_VALUE)){
JSONObject res = new JSONObject();
res.put("success",true);
res.put("msg","登录成功");
response.setStatus(200);
response.setContentType("application/json;charset=UTF-8");
response.getWriter().append(res.toString());
response.getWriter().flush();
}
....
....
String targetUrl = savedRequest.getRedirectUrl();
getRedirectStrategy().sendRedirect(request, response, targetUrl);
}
}