描述:AnonymousAuthenticationFilter:springsecurity在配置一些url可在未登录未授权的时候默认给他授权通过,可在配置文件中指定一些url赋予permitAll()方法即可使用该过滤器,接下来我们从源码的角度来看看这个过滤器具体是怎么工作的
AnonymousAuthenticationFilter
public class AnonymousAuthenticationFilter extends GenericFilterBean implements InitializingBean {
private AuthenticationDetailsSource<HttpServletRequest, ?> authenticationDetailsSource;
private String key;
private Object principal;
private List<GrantedAuthority> authorities;
public AnonymousAuthenticationFilter(String key) {
this(key, "anonymousUser", AuthorityUtils.createAuthorityList(new String[]{"ROLE_ANONYMOUS"}));
}
public AnonymousAuthenticationFilter(String key, Object principal, List<GrantedAuthority> authorities) {
this.authenticationDetailsSource = new WebAuthenticationDetailsSource();
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 afterPropertiesSet() {
Assert.hasLength(this.key, "key must have length");
Assert.notNull(this.principal, "Anonymous authentication principal must be set");
Assert.notNull(this.authorities, "Anonymous authorities must be set");
}
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
if (SecurityContextHolder.getContext().getAuthentication() == null) {
SecurityContextHolder.getContext().setAuthentication(this.createAuthentication((HttpServletRequest)req));
if (this.logger.isDebugEnabled()) {
this.logger.debug("Populated SecurityContextHolder with anonymous token: '" + SecurityContextHolder.getContext().getAuthentication() + "'");
}
} else if (this.logger.isDebugEnabled()) {
this.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(this.key, this.principal, this.authorities);
auth.setDetails(this.authenticationDetailsSource.buildDetails(request));
return auth;
}
public void setAuthenticationDetailsSource(AuthenticationDetailsSource<HttpServletRequest, ?> authenticationDetailsSource) {
Assert.notNull(authenticationDetailsSource, "AuthenticationDetailsSource required");
this.authenticationDetailsSource = authenticationDetailsSource;
}
public Object getPrincipal() {
return this.principal;
}
public List<GrantedAuthority> getAuthorities() {
return this.authorities;
}
}
1:调用过滤器时会主动给当前对象赋予anonymousUser的用户和权限(假如你实现了动态鉴权,配置了permitAll方法,在你调用配置的资源时会跳转到你自定义的鉴权方法,所以在全歼方法内需要判断是否权限为ROLE_ANONYMOUS,是就放行,否则会出现方法一直报403错误)
public AnonymousAuthenticationFilter(String key) {
this(key, "anonymousUser", AuthorityUtils.createAuthorityList(new String[]{"ROLE_ANONYMOUS"}));
}
2:再看如下过滤器最重要的方法dofilter我们发现,他会先从security上下文中查找是否有登录信息,没有就把构造方法默认的登录信息赋予到security上下文中,方便其他模块能够获取,然后调用**chain.doFilter(req, res);把AnonymousAuthenticationFilter放入过滤器链中。
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
if (SecurityContextHolder.getContext().getAuthentication() == null) {
SecurityContextHolder.getContext().setAuthentication(this.createAuthentication((HttpServletRequest)req));
if (this.logger.isDebugEnabled()) {
this.logger.debug("Populated SecurityContextHolder with anonymous token: '" + SecurityContextHolder.getContext().getAuthentication() + "'");
}
} else if (this.logger.isDebugEnabled()) {
this.logger.debug("SecurityContextHolder not populated with anonymous token, as it already contained: '" + SecurityContextHolder.getContext().getAuthentication() + "'");
}
chain.doFilter(req, res);
}
3:创建Authentication实现类在返回,供其他模块进行调用获取,如AccessDecisionVoter中的vote方法形参Authentication,在配置了permitAll()方法后,获取的Authentication就是AnonymousAuthenticationToken。
而AnonymousAuthenticationToken里面包含了用户名和密码和是否成功授权等等信息
protected Authentication createAuthentication(HttpServletRequest request) {
AnonymousAuthenticationToken auth = new AnonymousAuthenticationToken(this.key, this.principal, this.authorities);
auth.setDetails(this.authenticationDetailsSource.buildDetails(request));
return auth;
}
。。。。。