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(); //注销
原文地址:https://www.cnblogs.com/luliang888/p/11161486.html