Spring Security的用法看了不少,就大概来总结总结,找出一套适合直接应用到项目的。
一、为什么要用Spring Security
待补充
二、Spring Security整合中的缺点
Spring Security的主要功能是登录验证、访问控制。然而,由于Remember Me和访问控制自身的缺陷,导致并不适用在实际的项目中。Remember Me的缺陷参考上篇文章:关于记住HTTP请求的状态;访问控制的不足,主要是因为要把权限控制硬编码在代码中。为了解决这两个问题,考虑引入JWT+redis(JWT)和RBAC。
1.引入JWT+redis
1)讲讲JWT的优缺点。2)引入redis解决其刷新的问题有两种方式。①时时更新 ②保存一个上次访问时间,在JWT过期时,比较两次时间的差值来确定,是否需要动态更新JWT。
待补充
2.引入RBAC
RBAC的引入分三步:先设计数据库,再编写增删改查操作,最后将RBAC应用到Spring Security中。前两步就省略了,直接看第三步吧,怎么在Spring Security中使用RBAC。
首先,判断当前用户所拥有的URL是否和当前访问的URL是否匹配
/**
* 返回权限验证的接口
*/
public interface RbacService {
boolean hasPermission(HttpServletRequest request,Authentication authentication);
}
@Component("rbacService")
public class RbacServiceImpl implements RbacService {
private AntPathMatcher antPathMatcher = new AntPathMatcher();
@Override
public boolean hasPermission(HttpServletRequest request, Authentication authentication) {
Object principal = authentication.getPrincipal();
boolean hasPermission = false;
if (principal instanceof UserDetails) { //首先判断先当前用户是否是我们UserDetails对象。
String userName = ((UserDetails) principal).getUsername();
Set<String> urls = new HashSet<>(); // 数据库读取 //读取用户所拥有权限的所有URL
urls.add("/whoim");
// 注意这里不能用equal来判断,因为有些URL是有参数的,所以要用AntPathMatcher来比较
for (String url : urls) {
if (antPathMatcher.match(url, request.getRequestURI())) {
hasPermission = true;
break;
}
}
}
return hasPermission;
}
}
然后将此访问控制配置在Spring Security中
@Override
protected void configure(HttpSecurity http) throws Exception {
http.formLogin() //表单登录
//.loginPage("/evolutionary-loginIn.html")
.loginPage("/logintype") //如果需要身份认证则跳转到这里
.loginProcessingUrl("/login")
.successHandler(evolutionaryAuthenticationHandler)
.failureHandler(evolutionaryAuthenticationFailureHandler)
.and()
.authorizeRequests()
.antMatchers("/logintype",securityProperties.getBrower().getLoginPage())//不校验我们配置的登录页面
.permitAll()
.anyRequest()
.access("@rbacService.hasPermission(request,authentication)") //必须经过认证以后才能访问
.and().csrf().disable().addFilter(new JWTLoginFilter(authenticationManager()))
.addFilter(new JWTAuthenticationFilter(authenticationManager()));
}
网友评论