https://blog.csdn.net/fengqingyuebai19/article/details/106428034/
基本原理
- 过滤器链
WebSecurity#performBuild()
FilterChainProxy filterChainProxy = new FilterChainProxy(securityFilterChains);-
securityFilterChains中的过滤器
image.png SecurityContextPersistenceFilter 从session中取securityContext,没有则新建。结束时清空
-
AnonymousAuthenticationFilter为一些不需要认证就能访问的资源定义一个匿名user
public AnonymousAuthenticationFilter(String key) { this(key, "anonymousUser", AuthorityUtils.createAuthorityList("ROLE_ANONYMOUS")); } Authentication auth= SecurityContextHolder.getContext().getAuthentication(); if (auth==null || "anonymousUser".equals(auth.getPrincipal().toString())) {
CsrfFilter用于csrf校验
UsernamePasswordAuthenticationFilter校验认证
public Authentication attemptAuthentication(HttpServletRequest
request, HttpServletResponse response) throws AuthenticationException {
if (this.postOnly && !request.getMethod().equals("POST")) {
throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod());
} else {
String username = this.obtainUsername(request);
username = username != null ? username : "";
username = username.trim();
String password = this.obtainPassword(request);
password = password != null ? password : "";
UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password);
this.setDetails(request, authRequest);
return this.getAuthenticationManager().authenticate(authRequest);
}
}
-
FilterSecurityInterceptor是Filter也是Interceptor,权限认证
springsecurityPreAuthorize流程分析.png
PreInvocationAuthorizationAdviceVoter
微服务权限案例
HttpSessionSecurityContextRepository将session和SecurityContext绑定
getPrincipal一般放userDetails
PreAuthorize方法级权限注解表达式解析
class AbstractSecurityExpressionHandler {
@Override
public final EvaluationContext createEvaluationContext(Authentication authentication, T invocation) {
SecurityExpressionOperations root = createSecurityExpressionRoot(authentication, invocation);
StandardEvaluationContext ctx = createEvaluationContextInternal(authentication, invocation);
ctx.setBeanResolver(this.beanResolver);
ctx.setRootObject(root);
return ctx;
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) {
// beanResolver 注册成applicationContext
this.beanResolver = new BeanFactoryResolver(applicationContext);
}
}