springSecurity -------AnonymousAuthenticationFilter

描述: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;
    }

。。。。。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值