在Shiro中,如果没有自定义Realm的话,那么权限管理数据是通过IniRealm
的形式去读取配置文件shiro.ini
来加载数据,但是以后的权限管理数据肯定都是来源于数据库的,所以我们要把数据更改到数据库。
shiro提供的Realm
在SimpleAccountRealm
类中进行认证
在SimpleAccountRealm
类中有两个方法,分别提供认证和授权
public class SimpleAccountRealm extends AuthorizingRealm {
//省略
//用于认证的方法
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
UsernamePasswordToken upToken = (UsernamePasswordToken)token;
SimpleAccount account = this.getUser(upToken.getUsername());
if (account != null) {
if (account.isLocked()) {
throw new LockedAccountException("Account [" + account + "] is locked.");
}
if (account.isCredentialsExpired()) {
String msg = "The credentials for account [" + account + "] are expired";
throw new ExpiredCredentialsException(msg);
}
}
return account;
}
//用于授权的方法
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
String username = this.getUsername(principals);
this.USERS_LOCK.readLock().lock();
AuthorizationInfo var3;
try {
var3 = (AuthorizationInfo)this.users.get(username);
} finally {
this.USERS_LOCK.readLock().unlock();
}
return var3;
}
}
自定义Realm
/**
* @auther heling
* @date 2021/10/4
* 自定义realm实现,将认证/授权数据来源转为数据库的实现
*/
public class CustomerRealm extends AuthorizingRealm {
//授权
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
return null;
}
//认证
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
//在token中获取用户名
String principal = (String)authenticationToken.getPrincipal();
System.out.println(principal);
//根据身份信息使用jdbc mybatis查询相关数据库
if("heling".equals(principal)){
//参数1:返回数据库中正确的用户名
//参数2:返回数据库中正确密码
//参数3:提供当前realm的名字 this.getName();
SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(principal,"123",this.getName());
return simpleAuthenticationInfo;
}
return null;
}
}
使用自定义Realm
认证
/**
* @auther heling
* @date 2021/10/4
* 使用自定义realm
*/
public class TestCustomerRealmAuthenticator {
public static void main(String[] args) {
//创建securityManager
DefaultSecurityManager defaultSecurityManager = new DefaultSecurityManager();
//设置自定义realm
defaultSecurityManager.setRealm(new CustomerRealm());
//将安全工具类设置安全管理器
SecurityUtils.setSecurityManager(defaultSecurityManager);
//通过安全工具类获取subject
Subject subject = SecurityUtils.getSubject();
//创建token
UsernamePasswordToken token = new UsernamePasswordToken("heling", "123");
try{
System.out.println("认证状态:" + subject.isAuthenticated());
subject.login(token); //用户认证
System.out.println("认证状态:" + subject.isAuthenticated());
}catch (UnknownAccountException e){
e.printStackTrace();
System.out.println("认证失败:用户名不存在");
}catch (IncorrectCredentialsException e){
e.printStackTrace();
System.out.println("认证失败:密码错误");
}
}
}