前言:
首先我们先分析怎么实现自定义某些realm,按照以往的方法肯定是实现接口或者继承某类
查看继承树结构
通过debug模式下分析源码可以得知
AuthenticatingRealm类中的 doGetAuthenticationInfo()方法是实现用户认证的
AuthorizingRealml类中的doGetAuthorizationInfo()方法是完成用户授权的
然后在这两个类中只是声明了该方法,没有去实现,接着我们看继承树中最根部的SimpleAccountRealm类
我们可以发现,在该类中完成了用户认证和授权的代码核心实现
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,就必须继承AuthorizingRealm类,为什么呢?因为如果继承AuthenticatingRealm,只能完成用户认证,无法授权;而继承了AuthorizingRealm就很方便了,里面既实现了AuthenticatingRealm类中的doGetAuthenticationInfo()方法完成用户认证,又加入了新的方法doGetAuthorizationInfo()用于完成授权操作
代码实现(仅仅只进行认证操作)
public class CustomerRealm extends AuthorizingRealm {
//授权
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
return null;
}
//认证
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
String principal = (String) authenticationToken.getPrincipal();
if("tom".equals(principal)){
//参数1,返回数据库中的正确的账户 //参数2 :密码 //参数3.提供当前realm的名字
SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo("tom","123",this.getName());
return simpleAuthenticationInfo;
}
System.out.println(principal);
return null;
}
}
测试
public class TestCustomerRealm {
public static void main(String[] args) {
//创建security manager
DefaultSecurityManager securityManager = new DefaultSecurityManager();
//设置realm
securityManager.setRealm(new CustomerRealm());
//将安全工具类设置安全管理器
SecurityUtils.setSecurityManager(securityManager);
//通过安全工具类获取Subject
Subject subject = SecurityUtils.getSubject();
//创建令牌
UsernamePasswordToken tom = new UsernamePasswordToken("tom", "123");
try {
subject.login(tom);
}catch (UnknownAccountException e){
e.printStackTrace();
System.out.println();
}catch (IncorrectCredentialsException e){
e.printStackTrace();
}
}
}
shiro.ini文件
[users]
tom=123
jone=456
jane=789
测试成功
😘😘😘