1、前言
目前流行的权限校验框架主要Shori和SpringSecury,这篇主要讲解的是在基于前后端分离的基础上对SpringSecurity的使用,前后端使用JWT进行身份鉴定,使用也比较的简单,主要是配置问题,话不多说,上代码。
主要的校验流程:

2、代码展示
2.1 自定义SpringSecurityConfig 配置类
package com.pzg.chat.config;
import com.pzg.chat.filter.JwtAuthenticationTokenFilter;
import com.pzg.chat.handler.AccessDecisionManagerImpl;
import com.pzg.chat.handler.FilterInvocationSecurityMetadataSourceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.access.AccessDecisionManager;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.ObjectPostProcessor;
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.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.access.AccessDeniedHandler;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
import org.springframework.security.web.access.intercept.FilterSecurityInterceptor;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
@EnableWebSecurity
@Configuration
@SuppressWarnings("all")
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private AuthenticationFailureHandler authenticationFailureHandler;
@Autowired
private AuthenticationSuccessHandler authenticationSuccessHandler;
@Autowired
private AccessDeniedHandler accessDeniedHandler;
@Autowired
private AuthenticationEntryPoint authenticationEntryPoint;
@Autowired
private JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter;
@Bean
public FilterInvocationSecurityMetadataSource securityMetadataSource(){
return new FilterInvocationSecurityMetadataSourceImpl();
}
@Bean()
public AccessDecisionManager accessDecisionManager(){
return new AccessDecisionManagerImpl();
}
@Bean
public PasswordEncoder passwordEncoder(){
return new BCryptPasswordEncoder();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.formLogin()
.loginProcessingUrl("/user/login") //登入接口路径
.usernameParameter("account") //账号
.passwordParameter("password")//密码
.failureHandler(authenticationFailureHandler) //自定义登入验证失败
.successHandler(authenticationSuccessHandler); //自定义成功
http.authorizeRequests()
.withObjectPostProcessor(new ObjectPostProcessor() {
@Override
public O postProcess(O o) {
o.setSecurityMetadataSource(securityMetadataSource());
o.setAccessDecisionManager(accessDecisionManager());
return o;
}
})
.anyRequest().permitAll() //放行所有
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS) //禁用session
.and()
.csrf() //防止CSRF攻击
.disable()
.exceptionHandling()
//定义权限不足失败
.accessDeniedHandler(accessDeniedHandler)
//定义用户未登入
.authenticationEntryPoint(authenticationEntryPoint)
//让jwtAuthenticationTokenFilter在UsernamePasswordAuthenticationFilter之前执行
.and().addFilterBefore(jwtAuthenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);
}
/**
* 暴露认证方法
* @return
* @throws Exception
*/
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
}
通过去继承WebSecurityConfigurerAdapter类 并重写里面的configure()方法和authenticationManagerBean()方法,重写configure()主要就是去配置自己的规则,而重写authenticationManagerBean()方法则是去暴露自定义校验的方法,源码注释有说明。
属性类说明:
1.AuthenticationFailureHandler:登入失败处理类
2.AuthenticationSuccessHandler:登入成功处理类
3.AccessDeniedHandler:权限不足处理类
4.AuthenticationEntryPoint:用户未登入处理类
5.JwtAuthenticationTokenFilter:JWT过滤器
6.FilterInvocationSecurityMetadataSource:获取访问路径需要的权限
7.accessDecisionManager:判断所访问路径权限与当前登入用户所拥有权限是否匹配
3、SpringSecurityConfig 配置类所依赖的类
3.1 AuthenticationFailureHandler类
package com.pzg.chat.handler;
import com.alibaba.fastjson.JSON;
import com.pzg.chat.constant.CommonConstant;
import com.pzg.chat.exception.BusinessException;
import com.pzg.chat.model.vo.ResultVO;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* 登录失败处理
*/
@Component
public class AuthenticationFailHandlerImpl implements AuthenticationFailureHandler {
@Override
public void onAuthenticationFailure(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException {
//设置响应字符集utf-8
httpServletResponse.setContentType(CommonConstant.APPLICATION_JSON);
if (e.getCause()!=null){
if (e.getCause() instanceof BusinessException){
BusinessException businessException = (BusinessException) e.getCause();
ResultVO