spring security

Spring Security原理篇(七) 认证流程

2018-09-19  本文已影响229人  怪诞140819

上文已经说了Spring Security启动bean是怎样被加载到spring容器。也说到了默认情况下的过滤器链里面的11个过滤器。
UsernamePasswordAuthenticationFilter负责的就是对用户名密码进行认证。

1.UsernamePasswordAuthenticationFilter的实现原理

public UsernamePasswordAuthenticationFilter() {
    super(new AntPathRequestMatcher("/login", "POST"));
}

/login的请求进行拦截,我们看到请求类型只能是POST

public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
            throws IOException, ServletException {

        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) res;

        if (!requiresAuthentication(request, response)) {
            chain.doFilter(request, response);

            return;
        }

        if (logger.isDebugEnabled()) {
            logger.debug("Request is to process authentication");
        }

        Authentication authResult;

        try {
            authResult = attemptAuthentication(request, response);
            if (authResult == null) {
                // return immediately as subclass has indicated that it hasn't completed
                // authentication
                return;
            }
            sessionStrategy.onAuthentication(authResult, request, response);
        }
        catch (InternalAuthenticationServiceException failed) {
            logger.error(
                    "An internal error occurred while trying to authenticate the user.",
                    failed);
            unsuccessfulAuthentication(request, response, failed);

            return;
        }
        catch (AuthenticationException failed) {
            // Authentication failed
            unsuccessfulAuthentication(request, response, failed);

            return;
        }

        // Authentication success
        if (continueChainBeforeSuccessfulAuthentication) {
            chain.doFilter(request, response);
        }

        successfulAuthentication(request, response, chain, authResult);
    }

这个方法调用了attemptAuthentication()方法,这个方法定义在子类UsernamePasswordAuthenticationFilter
成功调用sessionStrategy.onAuthentication()方法处理session,然后在调用successfulAuthentication()这个方法处理操作成功
失败调用unsuccessfulAuthentication()方法,处理失败信息

我们看一下attemptAuthentication()这个方法

public Authentication attemptAuthentication(HttpServletRequest request,
            HttpServletResponse response) throws AuthenticationException {
        if (postOnly && !request.getMethod().equals("POST")) {
            throw new AuthenticationServiceException(
                    "Authentication method not supported: " + request.getMethod());
        }

        String username = obtainUsername(request);
        String password = obtainPassword(request);

        if (username == null) {
            username = "";
        }

        if (password == null) {
            password = "";
        }

        username = username.trim();

        UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(
                username, password);

        // Allow subclasses to set the "details" property
        setDetails(request, authRequest);

        return this.getAuthenticationManager().authenticate(authRequest);
    }

其实我们从这段代码可以看到这个方法机会只做了几件事情
1.验证是不是POST类型的请求
2.获取参数
3.调用AuthenticationManager的authenticate()方法进行认证
4.认证成功返回一个Authentication类型变量,认证失败抛出AuthenticationException异常
5.综上所述,认证的处理其实是委托给了AuthenticationManager来做处理的

2.AuthenticationManager怎样处理认证

由于源代码比较简单所以不引入源代码,然而有几个类我们都没有见过,需要好好的看一下

2.1 AuthenticationManager 接口

这个接口值定义了一个方法

Authentication authenticate(Authentication authentication)throws AuthenticationException;

从注释中我们可以知道,一旦验证成功会填充好Authentication对象,包括权限的信息,同时这个方法的实现必须遵循以下约定

2.2 ProviderManager

private List<AuthenticationProvider> providers = Collections.emptyList();

里面存储了需要验证的provider,然后循环利用provider进行验证,稍后我们看一下具体的一个provider的实现

2.3 AuthenticationProvider接口

public interface AuthenticationProvider {
    Authentication authenticate(Authentication authentication)throws AuthenticationException;
    boolean supports(Class<?> authentication);
}

2.4 Authentication

这个是DaoAuthenticationProvider验证成功后创建Authentication

image.png

我们可以看到的是 Authentication里面存放的是主体(简单点就是用户吧)认证或者认证成功后的信息

上一篇 下一篇

猜你喜欢

热点阅读