目录树
了解自定义Realm及Shiro简单入门demo2
一、了解自定义Realm
上一个demo里的realm使用的自带的默认的,通常情况下我们都会使用
自定义的realm
- Shiro默认自带的 IniRealm,IniRealm从ini配置文件中读取用户信息,而大部分情况是从数据库中读取用户信息。所以需要实现自定义的realm
realm接口如下:
可以分析得出:
- CathingRealm:负责缓存处理
- AuthenticationRealm:负责认证
- AuthorizingRealm:负责授权
通常情况,自定义的Realm继承AuthorizingRealm即可实现认证和授权
二、自定义realm的demo2
1.导shiro的jar包
2.自定义realm的类
3.写一个shiro测试类
2.1 导shiro-jar包
<dependencies>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>1.5.3</version>
</dependency>
<!--必須要,不然日志文件報錯-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.25</version>
<scope>test</scope>
</dependency>
</dependencies>
2.2 自定义类-CustomerRealm
//我自定义的realm连接器 (可以不使用ini文件)
public class CustomerRealm extends AuthorizingRealm {
//授权
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
return null;
}
//认证
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken YtyToken) throws AuthenticationException {
System.out.println("进入到自定的realm连接器中------------");
// Object principal = YtyToken.getPrincipal();
//正常会返回上面一个object对象,这里我不用,而是直接用String类型的name,所以需要强转,如下
String name = (String) YtyToken.getPrincipal(); //这个是获取用户信息
System.out.println(name);
//进行用户信息的判断;就是判断token中的值
if ("yty".equals(name)){
//三个参数:1.用户姓名 2.用户密码 3.获取当前的realm对象
SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(name,"password",getName());
//成功就返回当前对象
return simpleAuthenticationInfo;
}
//如果用户姓名和密码对应不上 返回null
return null;
}
}
2.3 测试类CustomerTest
public class CustomerTest {
public static void main(String[] args) {
//1.创建安全管理器
DefaultSecurityManager defaultSecurityManager = new DefaultSecurityManager();
//2.给安全管理器设置realm对象--把自定义的realm对象拿过来
defaultSecurityManager.setRealm(new CustomerRealm());
//3.安全工具设置安全管理器-即把安全管理器加入到安全工具中去
SecurityUtils.setSecurityManager(defaultSecurityManager);
//4.通过安全工具获取主体subject
//认证主体
Subject subject = SecurityUtils.getSubject();
//5.设置令牌
//里面的参数就是前端获取过来的,我这里是写死的,正常不能这样子写
UsernamePasswordToken token = new UsernamePasswordToken("yty","password");
System.out.println("认证前-----------");
System.out.println("是否认证:"+subject.isAuthenticated());//判断是否有验证
//开始认证
subject.login(token);
System.out.println("认证后-----------");
System.out.println("是否认证:"+subject.isAuthenticated());//判断是否有验证
}
}
2.4 测试结果分析
由此分析上述demo整个流程都没有问题。
现在我将前端获取的用户姓名信息故意改错,然后测试
将用户名yty改错yty123
结果:报错。
所以还需要处理一下异常,直接报错是不行的。
2.5 异常处理
直接将认证前后的代码放入try…catch试一试
public class CustomerTest {
public static void main(String[] args) {
//1.创建安全管理器
DefaultSecurityManager defaultSecurityManager = new DefaultSecurityManager();
//2.给安全管理器设置realm对象--把自定义的realm对象拿过来
defaultSecurityManager.setRealm(new CustomerRealm());
//3.安全工具设置安全管理器-即把安全管理器加入到安全工具中去
SecurityUtils.setSecurityManager(defaultSecurityManager);
//4.通过安全工具获取主体subject
//认证主体
Subject subject = SecurityUtils.getSubject();
//5.设置令牌
//里面的参数就是前端获取过来的,我这里是写死的,正常不能这样子写
UsernamePasswordToken token = new UsernamePasswordToken("yty","PASSWORD");
try {
System.out.println("认证前-----------");
System.out.println("是否认证:"+subject.isAuthenticated());//判断是否有验证
//开始认证
subject.login(token);
System.out.println("认证后-----------");
System.out.println("是否认证:"+subject.isAuthenticated());//判断是否有验证
}catch (UnknownAccountException abc){
//UnknownAccountException是未知错误的异常
System.out.println("用户信息验证错误,请重新输入-------");
abc.printStackTrace();
}catch (IncorrectCredentialsException abc){
//IncorrectCredentialsException是账号密码错误的异常
System.out.println("用户账号或者密码,请重新输入-------");
abc.printStackTrace();
}
}
}
具体改动为:
//里面的参数就是前端获取过来的,我这里是写死的,正常不能这样子写
UsernamePasswordToken token = new UsernamePasswordToken("yty","PASSWORD");
try {
System.out.println("认证前-----------");
System.out.println("是否认证:"+subject.isAuthenticated());//判断是否有验证
//开始认证
subject.login(token);
System.out.println("认证后-----------");
System.out.println("是否认证:"+subject.isAuthenticated());//判断是否有验证
}catch (UnknownAccountException abc){
//UnknownAccountException是未知错误的异常
System.out.println("用户信息验证错误,请重新输入-------");
abc.printStackTrace();
}catch (IncorrectCredentialsException abc){
//IncorrectCredentialsException是账号密码错误的异常
System.out.println("用户账号或者密码,请重新输入-------");
abc.printStackTrace();
}
然后测试:
然后保持用户名正确,密码password改为PASSWORD,测试:
根据不同的输入参数,即可得到对应的验证结果。
以上所有就是自定义realm的基本了解。