作者简介:大家好,我是smart哥,前中兴通讯、美团架构师,现某互联网公司CTO
联系qq:184480602,加我进群,大家一起学习,一起进步,一起对抗互联网寒冬
学习必须往深处挖,挖的越深,基础越扎实!
Spring Security源码解析
spring security的基本原理之前讲解过了。这章主要看后面两个:
-
FilterSecurityInterceptor
决定该用户是否有权限访问指定的资源
-
ExceptionTranslationFilter
异常处理,如果不能访问,则处理FilterSecurityInterceptor中抛出的异常
AnonymousAuthenticationFilter
AnonymousAuthenticationFilter : 匿名过滤器,位置固定,前面所有的都走完之后,会经过该过滤器
该过滤器之前自己也是备受折磨,特别是在调试oath2的时候,在没有正确开始basic登录的时候,
就一直在抱怨,为什么会走这个呢?
看看最主要的源码:
public AnonymousAuthenticationFilter(String key) {
// 固定了用户信息和角色
this(key, "anonymousUser", AuthorityUtils.createAuthorityList("ROLE_ANONYMOUS"));
}
public AnonymousAuthenticationFilter(String key, Object principal,
List<GrantedAuthority> authorities) {
Assert.hasLength(key, "key cannot be null or empty");
Assert.notNull(principal, "Anonymous authentication principal must be set");
Assert.notNull(authorities, "Anonymous authorities must be set");
this.key = key;
this.principal = principal; // 用户信息不是一个对象,是一个字符串
this.authorities = authorities;
}
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
throws IOException, ServletException {
// 如果之前没有身份认证
// 则创建一个 AnonymousAuthenticationToken
// 也就是说到达 FilterSecurityInterceptor 中的时候一定有一个身份信息
if (SecurityContextHolder.getContext().getAuthentication() == null) {
SecurityContextHolder.getContext().setAuthentication(
createAuthentication((HttpServletRequest) req));
if (logger.isDebugEnabled()) {
logger.debug("Populated SecurityContextHolder with anonymous token: '"
+ SecurityContextHolder.getContext().getAuthentication() + "'");
}
}
else {
if (logger.isDebugEnabled()) {
logger.debug("SecurityContextHolder not populated with anonymous token, as it already contained: '"
+ SecurityContextHolder.getContext().getAuthentication() + "'");
}
}
chain.doFilter(req, res);
}
protected Authentication createAuthentication(HttpServletRequest request) {
AnonymousAuthenticationToken auth = new AnonymousAuthenticationToken(key,
principal, authorities);
auth.setDetails(authenticationDetailsSource.buildDetails(request));
return auth;
}
FilterSecurityInterceptor
看源码技巧:找准一个关键入口,然后分析调用关系和类图
-
FilterSecurityInterceptor
-
AccessDecisionManager 管理什么呢?AccessDecisionVoter :投票者
就是用来一系列的判定,是否可以进行访问什么的
-
AffirmativeBased 只要有一票否决则不能访问 (默认使用)
在未登录的时候用的是只要有一个拒绝则不能访问,在登录后,只要有一个允许则放行。。有点懵逼
</
-