shiro login源码

登录的代码示例为

Subjectsubject=SecurityUtils.getSubject();
UsernamePasswordTokenusernamePasswordToken=newUsernamePasswordToken(
  username,
  password
);
usernamePasswordToken.setRememberMe(rememberMe);
try{
  //进行验证,这里可以捕获异常,然后返回对应信息
  subject.login(usernamePasswordToken);
}catch(AuthenticationExceptione){
  return"error";
}catch(AuthorizationExceptione){
  return"error";
}
return"index";

 


步骤一
SecurityUtils.getSubject();

  会执行响应的实现类的 ThreadContext.getSubject(); 执行ThreadContext.getValue(key),获取出Map<Object,Object>,其中包含两个值:

并取出key值为 org.apache.shiro.util.ThreadContext_SUBJECT_KEY 的 WebDelegatingSubject对象(其中包含 request,response,principals,authenticated,host,session,securityManager(即另一个key)等)

其中的session对象属性如下:

 

步骤二
利用登录的username和password构造 UsernamePasswordToken 对象,此对象包含如下属性:

 

 

步骤三:
执行subject.login(usernamePasswordToken); 会执行WebDelegatingSubject的login方法:
①执行clearRunAsIdentitiesInternal,将session中的attribute移除: org.apache.shiro.subject.support.DelegatingSubject.RUN_AS_PRINCIPALS_SESSION_KEY
②执行securityManager(DefaultWebSecurityManager)的login方法:
  1.执行authenticate;
    AbstractAuthenticator的authenticate
      1.执行实现类ModularRealmAuthenticator的doAuthenticate方法);
        1.获取所有的realm,判断是一个realm还是多个
        2.然后执行doSingleRealmAuthentication或doMultiRealmAuthentication;
          1.执行doSingleRealmAuthentication的话会执行AuthenticatingRealm的getAuthenticationInfo方法
            1.先从cache中获取AuthenticationInfo;
            2.如果为空,再调用用户实现的realm的doGetAuthenticationInfo方法;
            3.成功后进行缓存;
          2.将执行结果通知所有的AuthenticationListener(可自行实现);
      2.执行createSubject;
        1.先创建SubjectContext对象,并赋值:Authenticated、info、token、securityManager、subject等信息;
        2.将SubjectContext对象中的信息包装成为DelegatingSubject对象,即最终创建的Subject对象;
        3.通过反射获取principals为PrincipalCollection对象,并set到session的Attribute中,key为org.apache.shiro.subject.support.DefaultSubjectContext_PRINCIPALS_SESSION_KEY;
        4.设置为AuthenticationState为true,并set到session的Attribute中,key为org.apache.shiro.subject.support.DefaultSubjectContext_AUTHENTICATED_SESSION_KEY;

        

      3.通知RememberMeManager结果,执行rememberMeSuccessfulLogin方法:
        1.获取RememberMeManager对象,并执行其onSuccessfulLogin方法(执行其实现类AbstractRememberMeManager的onSuccessfulLogin方法)
          1.执行forgetIdentity方法,(执行实现类CookieRememberMeManager的forgetIdentity方法)
            1.获取cookie(org.apache.shiro.web.servlet.Cookie)对象,并执行removeFrom方法,执行其实现类SimpleCookie的removeFrom方法

            

          2.如果是记住我,则执行rememberIdentity方法(执行其实现类CookieRememberMeManager的rememberSerializedIdentity方法)
            1.获取cookie(org.apache.shiro.web.servlet.Cookie)对象,将Base64.encodeToString(byte[] serialized)的cookie值写入,执行其实现类SimpleCookie的saveTo方法:
            

③将session包装为StoppingAwareProxiedSession类型,重写其stop方法:

 

posted @ 2020-05-09 18:05  MalcolmFeng  阅读(446)  评论(0编辑  收藏  举报