shiro讲解之 Authentication

来源:互联网 发布:微信淘客软件 百度云 编辑:程序博客网 时间:2024/05/22 19:35

shiro讲解之 Authentication

本章节将详细讲解Shiro的 Authentication 流程。


概念

  • 官方定义:

    • Authentication: Sometimes referred to as ‘login’, this is the act of proving a user is who they say they are.
  • 通常而言:

    • Shiro 认证更大程度上特指用户登录并对用户信息进行校验(这里的信息通常特指principal信息,常见的为用户名/密码组合),如果信息验证成功则顺序执行代码,否则抛出异常。

认证流程(Authentication Flow)

这里写图片描述

  • 身份验证

    • 身份验证

      • 一般需要提供如身份 ID 等一些标识信息来表明登录者的身份,如提供 email,用户名/密码来证明。在 shiro 中,用户需要提供 principals (身份)和 credentials(证明)给 shiro,从而应用能验证用户身份。
    • principals

      • 身份,即主体的标识属性,可以是任何属性,如用户名、邮箱等,唯一即可。一个主体可以有多个 principals,但只有一个Primary principals,一般是用户名/邮箱/手机号。
    • credentials

      • 证明/凭证,即只有主体知道的安全值,如密码/数字证书等。

    最常见的 principals 和 credentials 组合就是用户名/密码了。

  • 身份验证基本流程

  • 收集用户身份/凭证,即如用户名/密码

    • 核心代码

      ```UsernamePasswordToken token = new UsernamePasswordToken(username, password);```

      其中 username 和 password 为用户登录的用户名和密码。

  • 调用 Subject.login 进行登录,如果失败将得到相应的 AuthenticationException 异常,根据异常提示用户错误信息;否则登录成功

    • 核心代码

      try {            Subject subject = SecurityUtils.getSubject();            subject.login(token);        } catch (UnknownAccountException ue) {            // 没有该用户            logger.error("This is no such user with name of " +    token.getPrincipal());            return "erro";        } catch (IncorrectCredentialsException Ie) {            // 密码错误            logger.error("This password for account " + token.getPrincipal() + " is incorrect");            return "erro";        } catch (LockedAccountException Le) {            logger.error("This account was locked!");            return "erro";        } catch (AuthenticationException e) {            //认证过程所有异常的父类异常。也可以直接捕获父类异常。            logger.error("Authentication Failed");            return "erro";        }
  • 创建自定义的 Realm 类,继承 org.apache.shiro.realm.AuthorizingRealm 类,实现
    doGetAuthenticationInfo() 方法

    • 核心代码示例

          protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {        System.out.println("[FirstRealm] doGetAuthenticationInfo");        // 1. 把 AuthenticationToken 转换为 UsernamePasswordToken        UsernamePasswordToken upToken = (UsernamePasswordToken) token;        // 2. 从 UsernamePasswordToken 中来获取 username        String username = upToken.getUsername();        // 3. 调用数据库的方法, 从数据库中查询 username 对应的用户记录,此处用SubjectEntity模拟从数据库中查询出来的数据。        SubjectEntity principals = new SubjectEntity("123456", "Dustyone");        // 4. 若用户不存在, 则可以抛出 UnknownAccountException 异常,亦可在Controller中捕获        if ("unknown".equals(username)) {            throw new UnknownAccountException("用户不存在!");        }        // 5. 根据用户信息的情况, 决定是否需要抛出其他的 AuthenticationException 异常.同上        if ("monster".equals(username)) {            throw new LockedAccountException("用户被锁定");        }        // 6. 根据用户的情况, 来构建 AuthenticationInfo 对象并返回. 通常使用的实现类为:        // SimpleAuthenticationInfo        // 以下信息是从数据库中获取的.        // 1). principal: 认证的实体信息. 可以是 username, 也可以是数据表对应的用户的实体类对象.        Object principal = principals.getUsername();        // 2). credentials: 密码.        Object credentials = principals.getPassword();         // 3). realmName: 当前 realm 对象的 name. 调用父类的 getName() 方法即可        String realmName = getName();        //Shiro封装的校验Principals 和 credentials 的具体实现方法。在后续的学习中我们在深入学习认证策略和加密时将会着重学习这块。        SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(principal, credentials, realmName);        return info;    }

认证异常(AuthenticationException)

AuthenticationException 是在认证过程中所有Shiro 定义的异常的父类,一般直接捕获该父类异常即可,但若想获得 关于 AuthenticationException 的详细信息时(一般我们都是这么做的),我们可以挨个捕获。下面我们列举下AuthenticationException的所有异常。

  • AuthenticationException(所有认证异常父类)

    • AccountException(Account类异常)

      • ConcurrentAccessException(用户重复登录)

      • DisabledAccountException(当前用户不可用)

        • LockedAccountException(当前用户被锁定,禁止登录)
      • ExcessiveAttemptsException(登录重试次数,超限。只允许在一段时间内允许有一定数量的认证尝试)

      • UnknownAccountException(未知账户/没找到帐号,登录失败)

    • CredentialsException(Credentials类异常)

      • ExpiredCredentialsException(口令已过期)

      • IncorrectCredentialsException(口令不匹配错误)

    • UnSupportedTokenException(身份令牌异常,不支持的身份令牌)


小结

  • 认证流程

    这里写图片描述

  • 身份认证流程

    • 首先调用 Subject.login(token) 进行登录,其会自动委托给SecurityManager

    • SecurityManager 负责真正的身份验证逻辑;它会委托给Authenticator 进行身份验证

    • Authenticator 才是真正的身份验证者,Shiro API 中核心的身份认证入口点,此处可以自定义插入自己的实现

    • Authenticator 可能会委托给相应的 AuthenticationStrategy 进行多 Realm 身份验证,默认 ModularRealmAuthenticator 会调用AuthenticationStrategy 进行多 Realm 身份验证

    • Authenticator 会把相应的 token 传入 Realm,从 Realm 获取身份验证信息,如果没有返回/抛出异常表示身份验证失败了。此处可以配置多个Realm,将按照相应的顺序及策略进行访问

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 机动车罚单丢了怎么办 摩托车脱审半年怎么办 摩托车半年没审怎么办 驾照扣分未缴款怎么办 驾驶证过期在外地怎么办 三年驾校过期了怎么办 车年检过期半年怎么办 驾照过期未年检怎么办 驾驶证时间过了怎么办 驾证年审逾期怎么办 驾照a2扣分了怎么办 叉车年检过期了怎么办 部队驾驶证过期了怎么办 车检过期5天怎么办 b2被注销了怎么办 小车逾期未审验怎么办 汽车逾期未审验怎么办 对方无偿还能力怎么办 摩托车驾驶证年审过期怎么办 当兵父亲有前科怎么办 被动态监控了怎么办 学习驾驶证明过期怎么办 a2驾驶证扣分了怎么办 c1驾驶证脱审怎么办 摩托车驾驶证脱审怎么办 行车证到期了怎么办 外省驾驶证掉了怎么办 错过教师证体检怎么办? c3驾驶证怎么办c1证 驾驶证扣分18分怎么办 货车罚款单上没写金额怎么办 报名费驾校不退怎么办 异地学车暂住证怎么办 考驾照老是紧张怎么办 驾照老考不过怎么办 三轮摩托车行驶证怎么办 a2驾驶证附件假背扣怎么办 驾驶证扣分15分怎么办 烟草证副本丢失怎么办 身份证异地丢了怎么办 营业执照正本遗失了怎么办