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方法: