自定义MyRealm继承AuthorizingRealm 重写doGetAuthorizationInfo和doGetAuthenticationInfo两个方法, doGetAuthorizationInfo用于授权,doGetAuthenticationInfo用于认证 package com.test;import org.apache.shiro.authc.Authenticat
自定义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