关于 shiro登录,大多数人应该知道是通过securitymanager调用reaml来实现的。那到底是怎么具体来进行的呢?通过源码来看一哈,这里我是结合spring来做的登录;
shiro-1.2.3:
1.登录代码
2.Subject.login
从代码中标记的部分可知,Subject确实是调用manager的login方法来进行登录操作;在我的项目中我是用的securitymanager是DefaultWebSecurityManager这个类;
3.DefaultWebSecurityManager.login
重点是上述标记方法,该方法里会验证登录信息,如果登录通过会返回登录信息,如不通过则抛出异常;authenticate方法定义在父类AuthenticatingSecurityManager中;
4.AuthenticatingSecurityManager.authenticate
AuthenticatingSecurityManager将authenticate方法交给了ModularRealmAuthenticator类来完成,而该方法是继承自ModularRealmAuthenticator而来
5.AbstractAuthenticator.
代码不短,但后面都是catch中的处理 代码,关键还是红色标记的部分;doAuthenticate为抽象方法,由子类ModularRealmAuthenticator来实现
6.ModularRealmAuthenticator.doAuthenticate
在这里,我们终于见到了Realm。这个方法就是在判断程序中定义了几个realm,分别都单个realm和多个realm的处理方法。这里我们简单点,直接看单个realm的处理方法doSingleRealmAuthentication;
红色标记部分,就是真正的调用Reaml来实现登录;接下来,我们来看看Reaml的内容,这里选用JdbcRealm来查看;JdbcRealm继承自AuthenticatingRealm,而getAuthenticationInfo就来自这个类;
6.AuthenticatingRealm.getAuthenticationInfo方法
第一个标记是从缓存中查看,该用户是否已经登录。如果已经登录怎么直接完成了登录流程;第二个标记是根据用户信息,去获取数据库保存的该用户的密码等信息;第三个标记是利用第二个标记得到的数据库该用户的信息和本次登录该用户的信息经行比较,如果正确则验证通过,返回用户信息。如果不通过则验证失败,登录不成功,抛出错误;
这是一个抽象方法,从JdbcReaml里查看该方法
7.JdbcReaml.doGetAuthenticationInfo
从这里可以看出来,shiro是根据我们提供的sql代码( protected String authenticationQuery = DEFAULT_AUTHENTICATION_QUERY,这里有默认值。我们肯定要修改的)来进行jdbc的数据库查询;这里如果根据用户名和所给sql语句查询到了用户信息,怎么讲数据库保存的用户信息返回,否则抛出错误;
8.AuthenticatingRealm.assertCredentialsMatch---用户登录信息和数据保存用户信息匹配
重点是在标记部分,利用CredentialsMatcher类来进行验证;CredentialsMatcher是个借口,我们查看他的子类PasswordMatcher
9.PasswordMatcher.doCredentialsMatch---在这里利用PasswordService这个类进行密码对比验证,即完成登录;
- 海报