一文读懂 Shiro 登录认证全流程

一文读懂 Shiro 登录认证全流程


Apache Shiro 是 Java 的一个安全框架。Shiro 可以帮助我们完成:认证、授权、加密、会话管理、与 Web 集成、缓存等。其不仅可以用在 JavaSE 环境,也可以用在 JavaEE 环境。那么关于 Shiro 登录认证的执行流程是怎样的呢?下面我们来一起跟者源码看 Shiro 的登录认证流程。

登录入口

首先我们找到登录执行入口 LoginController.java,找到执行登录逻辑的代码
在这里插入图片描述
可以看到已经获取到了 username、password 和 rememberMe ,为了接下来的认证过程,我们需要获取 subject 对象,也就是代表当前登录用户,并且要将 username 和 password、rememberMe 两个变量设置到 UsernamePasswordToken 对象的 token 中,调用 SecurityUtils.getSubject().login(token)方法,将 token 传入;

执行登录

下面我们来看 subject.login(token),点进去看到源码信息
在这里插入图片描述
主要通过 securityManager 安全管理器调用 securityManager.login(this, token);方法,下面我们继续跟进 securityManager.login(this, token)方法内部来看
securityManager.login(this, token)
点进去 securityManager.login(this, token)方法可以看到 info = this.authenticate(token)
在这里插入图片描述
方法中定义了 AuthenticationInfo 对象来接受从 Realm 传来的认证信息,进入 authenticate(token)方法中
this.authenticate(token)
进入 this.authenticate(token)方法可以看到
在这里插入图片描述
继续跟进去,进入 authenticator.authenticate(token)方法
在这里插入图片描述
可以看到
this.doAuthenticate(token)
继续跟进去看 doAuthenticate(token)方法的实现
在这里插入图片描述
其中,this.assertRealmsConfigured();是判断当前的 realm 是否存在,不存在则抛出异常
在这里插入图片描述
当前项目中只配置了一个 realm,则会进入 doSingleRealmAuthentication((Realm)realms.iterator().next(), authenticationToken)方法,并且会将 realm 和 token 作为参数传入,这里的 realm 其实就是自己定义的 UserRealm,继续进入 doSingleRealmAuthentication 方法
this.doSingleRealmAuthentication
进入 this.doSingleRealmAuthentication 方法可以看到
在这里插入图片描述
这里会先判断 realm 是否支持 token,然后进入 else 方法执行 realm.getAuthenticationInfo(token)方法,继续跟进
在这里插入图片描述
this.getCachedAuthenticationInfo(token)这个方法是从 shiro 缓存中读取用户信息,如果没有,才从 realm 中获取信息。如果是第一次登陆,缓存中肯定没有认证信息,所以会执行 this.doGetAuthenticationInfo(token)这个方法,
在这里插入图片描述

UserRealm

在执行登录认证的时候需要选择我们自己实现的 realm 方法,自定义 UserRealm 实现登录校验
在这里插入图片描述
读取数据库信息进行验证,并封装成 SimpleAuthenticationInfo 中返回

    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException
    {
        UsernamePasswordToken upToken = (UsernamePasswordToken) token;
        String username = upToken.getUsername();
        String password = "*****";
        if (upToken.getPassword() != null)
        {
            password = new String(upToken.getPassword());
        }

        SysUser user = null;
        try
        {
            user = loginService.login(username, password);
        }
        catch (CaptchaException e)
        {
            throw new AuthenticationException(e.getMessage(), e);
        }
        catch (UserNotExistsException e)
        {
            throw new UnknownAccountException(e.getMessage(), e);
        }
        catch (UserPasswordNotMatchException e)
        {
            throw new IncorrectCredentialsException(e.getMessage(), e);
        }
        catch (UserPasswordRetryLimitExceedException e)
        {
            throw new ExcessiveAttemptsException(e.getMessage(), e);
        }
        catch (UserBlockedException e)
        {
            throw new LockedAccountException(e.getMessage(), e);
        }
        catch (RoleBlockedException e)
        {
            throw new LockedAccountException(e.getMessage(), e);
        }
        catch (Exception e)
        {
            log.info("对用户[" + username + "]进行登录验证..验证未通过{}", e.getMessage());
            throw new AuthenticationException(e.getMessage(), e);
        }
        SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user, password, getName());
        return info;
    }

再次查看 AuthenticatingRealm.getAuthenticationInfo(AuthenticationToken token)
AuthenticatingRealm.getAuthenticationInfo(AuthenticationToken token)
在这里插入图片描述
这里 assertCredentialsMatch(token, info)方法用于密码校验,点进去可以看到
在这里插入图片描述
cm.doCredentialsMatch(token, info)执行密码校验
在这里插入图片描述
点进去可以看到
在这里插入图片描述
通过从 token 中取出的密码与从数据库取出的 info 中的密码进行比较,认证相同返回 true;失败就返回 false,并抛出 AuthenticationException,将 info 返回到 defaultSecurityManager 中,到此认证过程结束。

爬虫Python学习是指学习如何使用Python编程语言来进行网络爬取和数据提取的过程。Python是一种简单易学且功能强大的编程语言,因此被广泛用于爬虫开发。爬虫是指通过编写程序自动抓取网页上的信息,可以用于数据采集、数据分析、网站监测等多个领域。 对于想要学习爬虫的新手来说,Python是一个很好的入门语言。Python的语法简洁易懂,而且有丰富的第三方库和工具,如BeautifulSoup、Scrapy等,可以帮助开发者更轻松地进行网页解析和数据提取。此外,Python还有很多优秀的教程和学习资源可供选择,可以帮助新手快速入门并掌握爬虫技能。 如果你对Python编程有一定的基础,那么学习爬虫并不难。你可以通过观看教学视频、阅读教程、参与在线课程等方式来学习。网络上有很多免费和付费的学习资源可供选择,你可以根据自己的需求和学习风格选择适合自己的学习材料。 总之,学习爬虫Python需要一定的编程基础,但并不难。通过选择合适的学习资源和不断实践,你可以逐步掌握爬虫的技能,并在实际项目中应用它们。 #### 引用[.reference_title] - *1* *3* [如何自学Python爬虫? 零基础入门教程](https://blog.csdn.net/zihong523/article/details/122001612)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [新手小白必看 Python爬虫学习路线全面指导](https://blog.csdn.net/weixin_67991858/article/details/128370135)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

csdn565973850

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值