前言
本章讲解Shiro登录验证的源码剖析以及登录验证策略
方法
一、Shiro登陆验证源码解析
1.使用Subject的login方法验证token
2.实际上Subject类仅仅是一个接口,他通过实现类DelegatingSubject将token委托给SecurityManager 来完成验证
3.而SecurityManager作为“心脏”接口,有很多的实现类帮助干活,上面的login方法实际是通过DefaultSecurityManager调用authenticate方法完成验证
4. authenticate方法是由其父类AuthenticatingSecurityManager完成的
在这里其有一个authenticator属性,这便是验证器啦:
5. Authenticator是由其默认的实现类ModularRealmAuthenticator的doAuthenticate方法来完成验证的
6. doAuthenticate方法用来获取realms,来将token和realm中的数据进行比较(验证),如果是单一的realm则直接进行比较。如果是多个realms则需要通过AuthenticationStrategy(验证策略)进行验证。
二、Shiro登陆验证策略
1.概述
在Shiro中一共有以下三种验证策略,用来在多realms条件下的验证。
AllSuccessfulStrategy | 所有都满足的情况 |
AtLeastOneSuccessfulStrategy | 至少一条满足的情况 |
FirstSuccessfulStrategy | 至少一条满足的情况,后续Realm停止验证 |
默认的认证策略为 AtLeastOneSuccessfulStrategy
2.编码验证
1)我们来设置两个realm(IniRealm、JdbcRealm)
配置文件做如下更改:
[main]
dataSource = com.mchange.v2.c3p0.ComboPooledDataSource
dataSource.driverClass = oracle.jdbc.driver.OracleDriver
dataSource.jdbcUrl = jdbc:oracle:thin:@localhost:1521:orcl
dataSource.user = scott
dataSource.password = tiger
jdbcRealm = org.apache.shiro.realm.jdbc.JdbcRealm
iniRealm = cn.edu.ccut.test.MyRealm
# $相当于spring的依赖注入
jdbcRealm.dataSource = $dataSource
authenticationStrategy = org.apache.shiro.authc.pam.AllSuccessfulStrategy
securityManager.authenticator.authenticationStrategy = $authenticationStrategy
securityManager.realms = $jdbcRealm,$iniRealm
MyRealm为我自定义的IniRealm,代码如下:
package cn.edu.ccut.test;
import org.apache.shiro.realm.text.IniRealm;
/**
* @Auther:jwang
* @Date:2019/5/10
* @Description:cn.edu.ccut.test
* @Version 1.0
**/
public class MyRealm extends IniRealm {
public MyRealm(){
this.setResourcePath("classpath:user.ini");
}
}
他使用了一个user.ini,user.ini用来配置用户名和密码:
JdbcRealm还是之前我们学习的那个,没有变化:
这时候我们的策略是 AllSuccessfulStrategy,也就是所有realm必须满足条件,我们输入zhangsan和1234验证通过,
sa和sa则验证失败:
2)下面我们换一个策略 FirstSuccessfulStrategy
这时候,输入lisi和5678也可以验证成功,并不是说FirstSuccessfulStrategy是第一个Realm成功才算成功!这点尤为重要!
3)最后我们尝试默认的策略AtLeastOneSuccessfulStrategy
我们依然使用lisi和5678登录:
使用sa和sa登录: