自定义MyRealm继承AuthorizingRealm
重写doGetAuthorizationInfo和doGetAuthenticationInfo两个方法,
doGetAuthorizationInfo用于授权,doGetAuthenticationInfo用于认证
package com.test;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
public class MyRealm extends AuthorizingRealm{
/**
* 授权
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection arg0) {
// TODO Auto-generated method stub
return null;
}
/**
* 认证
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken arg0) throws AuthenticationException {
// TODO Auto-generated method stub
//获取账号信息
Object principal = arg0.getPrincipal();
//从数据库等数据源获取数据
String name = "root";
String pwd = "123456";
if (!name.equals(principal)) {//低质量的匹配认证
return null;
}
return new SimpleAuthenticationInfo(principal, pwd, "MyRealm");
}
}
Shiro.ini配置文件:
[main]
#自定义 realm
customRealm=com.test.MyRealm
#将realm设置到securityManager
securityManager.realms=$customRealm
测试:
package com.test;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.config.IniSecurityManagerFactory;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.Factory;
import org.apache.shiro.mgt.SecurityManager;
public class Test {
public static void main(String[] args) {
// 获取SecurityManagerFactory对象
Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");
// 根据工厂对象获取SecurityManager对象
SecurityManager manager = factory.getInstance();
// 将SecurityManager添加到运行环境中
SecurityUtils.setSecurityManager(manager);
// 获取Subject对象
Subject subject = SecurityUtils.getSubject();
// 获取对应的认证令牌
AuthenticationToken token = new UsernamePasswordToken("root", "123456") ;
// 做登录认证
try {
subject.login(token);
System.out.println("登录成功....");
} catch (UnknownAccountException e) {
System.out.println("账号错误...");
} catch (IncorrectCredentialsException e) {
System.out.println("密码错误...");
}
System.out.println(subject.isAuthenticated());
}
}
所需依赖:
<dependencies>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>1.1.0</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.6.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
</dependencies>
二、
从源码看AuthorizingRealm
doGetAuthenticationInfo相关源码:
AuthenticatingRealm抽象类中:
AuthorizingRealm继承了AuthenticatingRealm,
最后doGetAuthorizationInfo和doGetAuthenticationInfo两个方法在SimpleAccountRealm中被实现了
那么这里实现了doGetAuthorizationInfo和doGetAuthenticationInfo两个方法是从ini配置文件里进行匹配认证账号和密码等信息的。
我们如何让它对我们相关业务去进行匹配验证了?
只需要我们去继承AuthorizingRealm抽象类,实现doGetAuthorizationInfo和doGetAuthenticationInfo两个抽象方法,根据我们自己的业务需求去获取数据和认证授权,
例如:从数据库查询出账号密码,进行认证,不默认的去从ini配置文件里读取账号和密码进行认证。
AuthenticatingRealm和AuthorizingRealm都有doGetAuthorizationInfo和doGetAuthenticationInfo两个方法。AuthorizingRealm继承了AuthenticatingRealm,而AuthenticatingRealm中需要重写的方法很多,而继承AuthorizingRealm只需要重写我们需要的重写doGetAuthorizationInfo和doGetAuthenticationInfo两个方法。
注意:自定义的Realm只完成了账号的认证。密码认证还是在AuthenticatingRealm中完成的,只是我们在自定义Realm中完成了密码的设置。
AuthenticatingRealm类中提供了
protected abstract AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException;
用于向外暴露,自定义实现该方法,而实际上AuthenticatingRealm类也实现了AuthenticationInfo,
这里的AuthenticationInfo方法就是实际验证了密码。
借鉴大佬:
https://dpb-bobokaoya-sm.blog.csdn.net/article/details/86629568