zoukankan      html  css  js  c++  java
  • shiro-认证

      认证最常见的形式及用户名密码登录。

    一、 认证流程:

      1. 首先调用Subject.login(AuthenticationToken)进行登录,其会自动委托给SecutityManager;

      2.org.apache.shiro.mgt.SecurityManager(安全管理员)负责真正的身份验证逻辑,它会委托Authenticator进行身份验证;

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

      4.Authenticator可能会委托给相应的AuthenticationStategy进行多Realm身份验证,默认ModularRealmAuthorizer会调用AuthenticationStategy进行多个Realm身份验证;

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

          // 获取当前的 Subject. 调用 SecurityUtils.getSubject();
          Subject currentUser = SecurityUtils.getSubject();

         // 测试当前的用户是否已经被认证. 即是否已经登录. 
            // 调动 Subject 的 isAuthenticated() 
            if (!currentUser.isAuthenticated()) {
                // 把用户名和密码封装为 UsernamePasswordToken 对象
                UsernamePasswordToken token = new UsernamePasswordToken("lonestarr", "vespa");
                // rememberme(记住我)
                token.setRememberMe(true);
                try {
                    // 执行登录. 
                    currentUser.login(token);
                } 
                // 若没有指定的账户, 则 shiro 将会抛出 UnknownAccountException 异常. 
                catch (UnknownAccountException uae) {
                    log.info("----> There is no user with username of " + token.getPrincipal());
                    return; 
                } 
                // 若账户存在, 但密码不匹配, 则 shiro 会抛出 IncorrectCredentialsException 异常。 
                catch (IncorrectCredentialsException ice) {
                    log.info("----> Password for account " + token.getPrincipal() + " was incorrect!");
                    return; 
                } 
                // 用户被锁定的异常 LockedAccountException
                catch (LockedAccountException lae) {
                    log.info("The account for username " + token.getPrincipal() + " is locked.  " +
                            "Please contact your administrator to unlock it.");
                }// 所有认证时异常的父类. 
                catch (AuthenticationException ae) {
                    //unexpected condition?  error?
                }
            }

    二、认证异常:

      1. org.apache.shiro.authc.AuthenticationException :认证异常

        |- org.apache.shiro.authc.UnknownAccountException:没有指定的账户异常

        |- org.apache.shiro.authc.IncorrectCredentialsException :不正确的密码异常

        |- org.apache.shiro.authc.LockedAccountException:账户锁定异常

     三、Realm:安全验证信息来源

      1. org.apache.shiro.realm.Realm接口: 

      Shiro从Realm获取安全数据(如:角色、用户、权限),即SecutityManager要验证用户身份,那么它需要从Realm获取相应的用户进行比较,确定是否合法;也需要从Realm得到用户相应的角色/权限进行验证用户是否可以进行操作;   

    String getName();    //返回唯一的Realm名称
    boolean supports(AuthenticationToken token);    //判断此 Realm是否支持Token
    AuthenticationInfo getAuthenticationInfo(AuthenticationToken token) throws AuthenticationException; //根据Token获取认证信息 

      2. org.apache.shiro.realm.AuthorizingRealm实现类:授权Realm

        一般基层AuthorizingRealm(授权)即可;其继承了AuthenticatingRealm(身份验证),而且也间接继承了CachingRealm(带缓存实现);

    四、验证器:进行验证

      1. org.apache.shiro.authc.Authenticator接口:验证器

        》单个Realm验证:Authenticator的职责是验证用户账号,是Shiro API中身份验证核心的入口点:如果验证成功,则返回“org.apache.shiro.authc.AuthenticationInfo”验证信息,此信息中包含了身份及凭证;如果验证失败则抛出AuthenticationException认证异常。

        》多个Realm验证:org.apache.shiro.mgt.SecurityManager接口继承了Authenticator接口,另外还有一个“org.apache.shiro.authc.pam.ModularRealmAuthenticator”实现,其委托多个Realm进行验证,验证规则通过AuthenticationStrategy接口指定。

    //Authenticator方法
    public AuthenticationInfo authenticate(AuthenticationToken authenticationToken) throws AuthenticationException;  //进行验证

      2. org.apache.shiro.authc.AuthenticationInfo接口:身份验证信息

    public Object getCredentials();                //获取凭据
    public PrincipalCollection getPrincipals();    //获取相关的主体

    五、token:令牌,用户提交的信息

      1. org.apache.shiro.authc.AuthenticationToken接口:用于收集用户提交的身份(如用户名)及凭据(如密码)

    public Object getPrincipal();          //获取用户名
    public Object getCredentials();        //获取认证信息(密码),返回字符数组

        |- org.apache.shiro.authc.UsernamePasswordToken实现类:用户名和密码令牌

    public String getUsername();                    //获取用户名
    public char[] getPassword();                    //获取密码
    public void setRememberMe(boolean rememberMe);    //记住我
    public boolean isRememberMe();                    //获取记住我

    六、Subject:主题,用户的行为

      org.apache.shiro.subject.Subject:代表着用户,用户所拥有的行为包括:登录、退出、校验权限、获得Session等,符合面向对象,任何与系统交互的行为都可以由Subject完成。

    SecurityUtils.getSubject();               //获取当前正在执行的subject
    //认证方法
    public
    Object getPrincipal(); //获取登录id,如果没有则返回null(尚未登录) public Session getSession(); //获取Session public Session getSession(boolean create); //创建Sessoion public boolean isAuthenticated(); //是否通过认证 public boolean isRemembered(); //是否使用记住我 public void login(AuthenticationToken token) throws AuthenticationException; //登录 public void logout(); //注销
  • 相关阅读:
    关于MySQL慢日志,你想知道的都在这
    h5 唤起app或跳转appStore
    ios 报错 Invalid row height provided by table delegate. Value must be at least 0.0, or UITableViewAutomaticDi......
    url的长度问题
    CUICatalog: Invalid asset name supplied:
    -[UITableView copyWithZone:]: unrecognized selector sent to instance 0x7XXXXXX00
    iOS项目运行出现:[__NSPlaceholderDictionary initWithObjects:forKeys:count:]: attempt to insert nil object
    UICachedDeviceRGBColor CGImage]: unrecognized selector sent to instance 0xxxxxxxxxxx'
    iOS Xcode 10: Multiple commands produce
    2019 开篇
  • 原文地址:https://www.cnblogs.com/luliang888/p/11161486.html
Copyright © 2011-2022 走看看