前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >一文读懂 Shiro 登录认证全流程

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

作者头像
六月的雨在Tencent
发布2024-03-29 09:05:48
1080
发布2024-03-29 09:05:48
举报
文章被收录于专栏:CSDNCSDN
一文读懂 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 中返回

代码语言:javascript
复制
    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 中,到此认证过程结束。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2024-03-28,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一文读懂 Shiro 登录认证全流程 Apache Shiro 是 Java 的一个安全框架。Shiro 可以帮助我们完成:认证、授权、加密、会话管理、与 Web 集成、缓存等。其不仅可以用在 JavaSE 环境,也可以用在 JavaEE 环境。那么关于 Shiro 登录认证的执行流程是怎样的呢?下面我们来一起跟者源码看 Shiro 的登录认证流程。
  • 登录入口
  • 执行登录
  • UserRealm
相关产品与服务
数据库
云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档