SpringSecurity的登录授权流程分析

本文解析了SpringSecurity结合JWT的登录授权流程,详细介绍了UsernamePasswordAuthenticationFilter的作用及位置,阐述了ProviderManager如何通过DaoAuthenticationProvider进行身份验证,以及具体的验证过程。
摘要由CSDN通过智能技术生成

最近用SpringSecurity结合Jwt、在此记录一下SpringSecurity的登录授权过程、(只是略懂了冰山一角、还有很多配置都未涉及、现在了解的只是最常见最常用的配置)、SpringSecurity的验证方式有很多、不过大部分使用的还是UserDetailsService的方式

1、UsernamePasswordAuthenticationFilter 位于SecuritySecurity Filter Chain链的第4位、该类主要作用身份验证处理机制-用户名密码身份验证筛选器-以便可以修改SecurityContextHolder以包含有效的身份验证请求令牌、该类继承AbstractAuthenticationProcessingFilter、在AbstractAuthenticationProcessingFilter的doFilter中代码如下在这里插入图片描述
3、UsernamePasswordAuthenticationFilter 会对其进行判断、抽取usernamepassword以及封装成身份验证令牌
在这里插入图片描述
4、ProviderManager调用authenticate方法、进行身份验证

5、ProviderManager获取所拥有的AuthenticationProvider进行验证、一般我们使用的是DaoAuthenticationProvider验证类、该类继承 AbstractUserDetailsAuthenticationProvider 类、在AbstractUserDetailsAuthenticationProviderauthenticate方法中封装了具体的验证过程、具体如下

public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        Assert.isInstanceOf(UsernamePasswordAuthenticationToken.class, authentication, () -> {
            return this.messages.getMessage("AbstractUserDetailsAuthenticationProvider.onlySupports", "Only UsernamePasswordAuthenticationToken is supported");
        });
        String username = authentication.getPrincipal() == null ? "NONE_PROVIDED" : authentication.getName();
        boolean cacheWasUsed = true;
        UserDetails user = this.userCache.getUserFromCache(username);//获取缓存的
        if (user == null) { //如过user为空则调用DaoAuthenticationProvider的retrieveUser方法获取用户信息
            cacheWasUsed = false;

            try {
                //获取用户信息、一般是调用自定义的 UserDetailsService
                user = this.retrieveUser(username, (UsernamePasswordAuthenticationToken)authentication); 
            } catch (UsernameNotFoundException var6) {
                this.logger.debug("User '" + username + "' not found");
                if (this.hideUserNotFoundExceptions) {
                    throw new BadCredentialsException(this.messages.getMessage("AbstractUserDetailsAuthenticationProvider.badCredentials", "Bad credentials"));
                }

                throw var6;
            }

            Assert.notNull(user, "retrieveUser returned null - a violation of the interface contract");
        }

        try {
            //UserDetails接口下有几个返回 boolean的方法是在这里效验的、例如:账户停用等
            this.preAuthenticationChecks.check(user);
            //这个是验证密码是否正确的、和`retrieveUser`方法一样都是调用DaoAuthenticationProvider去处理
            this.additionalAuthenticationChecks(user, (UsernamePasswordAuthenticationToken)authentication);
        } catch (AuthenticationException var7) {
            if (!cacheWasUsed) {
                throw var7;
            }

            cacheWasUsed = false;
            user = this.retrieveUser(username, (UsernamePasswordAuthenticationToken)authentication);
            this.preAuthenticationChecks.check(user);
            this.additionalAuthenticationChecks(user, (UsernamePasswordAuthenticationToken)authentication);
        }

        this.postAuthenticationChecks.check(user);
        if (!cacheWasUsed) {
            this.userCache.putUserInCache(user);
        }

        Object principalToReturn = user;
        if (this.forcePrincipalAsString) {
            principalToReturn = user.getUsername();
        }

        return this.createSuccessAuthentication(principalToReturn, authentication, user);
    }

6、处理流程图如下
在这里插入图片描述

等有时间在写 登录成功处理登录失败处理流程、以及匿名访问受保护资源异常认证过的用户访问无权限资源的异常的自定义处理方式、另附上官方文档SpringSecurity文档

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值