首页 技术 正文
技术 2022年11月16日
0 收藏 397 点赞 4,275 浏览 7380 个字
  • Realm配置

    #声明一个realm
myRealm1=com.github.zhangkaitao.shiro.chapter2.realm.MyRealm1
myRealm2=com.github.zhangkaitao.shiro.chapter2.realm.MyRealm2
#指定securityManager的realms实现
securityManager.realms=$myRealm1,$myRealm2
  1. securityManager会按照realms指定的顺序进行身份认证。此处我们使用显示指定顺序的方式指定了Realm的顺序,如果删除“securityManager.realms=$myRealm1,$myRealm2”,那么securityManager会按照realm声明的顺序进行使用(即无需设置realms属性,其会自动发现),当我们显示指定realm后,其他没有指定realm将被忽略,如“securityManager.realms=$myRealm1”,那么myRealm2不会被自动设置进去
  2. 1、变量名=全限定类名会自动创建一个类实例

    2、变量名.属性=值 自动调用相应的setter方法进行赋值

    3、$变量名 引用之前的一个对象实例

  • Authenticator及AuthenticationStrategy

  1. Authenticator的职责是验证用户帐号,是Shiro API中身份验证核心的入口点:
    public AuthenticationInfo authenticate(AuthenticationToken authenticationToken)
throws AuthenticationException;
  • SecurityManager接口继承了Authenticator,另外还有一个ModularRealmAuthenticator实现(ModularRealmAuthenticator默认使用AtLeastOneSuccessfulStrategy策略。),其委托给多个Realm进行验证,验证规则通过AuthenticationStrategy接口指定,默认提供的实现:
  • FirstSuccessfulStrategy:只要有一个Realm验证成功即可,只返回第一个Realm身份验证成功的认证信息,其他的忽略;
  • AtLeastOneSuccessfulStrategy:只要有一个Realm验证成功即可,和FirstSuccessfulStrategy不同,返回所有Realm身份验证成功的认证信息;
  • AllSuccessfulStrategy:所有Realm验证成功才算成功,且返回所有Realm身份验证成功的认证信息,如果有一个失败就失败了。

一、案例

  • 需求:

    假设我们有三个realm:

    myRealm1: 用户名/密码为zhang/123时成功,且返回身份/凭据为zhang/123;

    myRealm2: 用户名/密码为wang/123时成功,且返回身份/凭据为wang/123;

    myRealm3: 用户名/密码为zhang/123时成功,且返回身份/凭据为zhang@163.com/123,和myRealm1不同的是返回时的身份变了;

  • pom.xml依赖省略,可查看前几章
  • 配置shiro.ini文件
[main]
#指定securityManager的authenticator实现 
authenticator=org.apache.shiro.authc.pam.ModularRealmAuthenticator
securityManager.authenticator=$authenticator #指定securityManager.authenticator的authenticationStrategy
allSuccessfulStrategy=org.apache.shiro.authc.pam.FirstSuccessfulStrategy
securityManager.authenticator.authenticationStrategy=$allSuccessfulStrategy
myRealm1=realms.MyRealm1
myRealm2=realms.MyRealm2
myRealm3=realms.MyRealm3
securityManager.realms=$myRealm1,$myRealm2,$myRealm3 [users]
zhang=123
wang=123
    •   认证策略为FirstSuccessfulStrategy ,只要有一个Realm验证成功即可,只返回第一个Realm身份验证成功的认证信息,其他的忽略
  • MyRealm1.java
package realms;import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.SimpleAccount;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;public class MyRealm1 extends AuthorizingRealm{ /**
* 判断授权的
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
// TODO Auto-generated method stub
return null;
} /**
* 判断认证的
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
String userName=token.getPrincipal().toString();
String passWord=new String((char[])token.getCredentials()); if(!userName.equals("zhang")) throw new UnknownAccountException("Realm1 用户名错误");
if(!passWord.equals("123")) throw new IncorrectCredentialsException("Realm1 密码错误"); return new SimpleAccount(userName, passWord, getName());
}}
  • MyRealm2.java
package realms;import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.SimpleAccount;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;public class MyRealm2 extends AuthorizingRealm{
/**
* 判断授权的
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
// TODO Auto-generated method stub
return null;
} /**
* 判断认证的
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
String userName=token.getPrincipal().toString();
String passWord=new String((char[])token.getCredentials()); if(!userName.equals("wang")) throw new UnknownAccountException("Realm2 用户名错误");
if(!passWord.equals("123")) throw new IncorrectCredentialsException("Realm2 密码错误"); return new SimpleAccount(userName, passWord, getName());
}}
  • MyRealm3.java
package realms;import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.SimpleAccount;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;public class MyRealm3 extends AuthorizingRealm{
/**
* 判断授权的
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
// TODO Auto-generated method stub
return null;
} /**
* 判断认证的
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
String userName=token.getPrincipal().toString();
String passWord=new String((char[])token.getCredentials()); if(!userName.equals("zhang")) throw new UnknownAccountException("Realm3 用户名错误");
if(!passWord.equals("123")) throw new IncorrectCredentialsException("Realm4 密码错误"); return new SimpleAccount("zhang@163.com", passWord, getName());
}}
  • 测试
package 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.mgt.SecurityManager;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;public class TestMain {
public static void main(String[] args) {
SecurityManager securityManager=new IniSecurityManagerFactory("classpath:shiro.ini").getInstance();
SecurityUtils.setSecurityManager(securityManager); Subject subject=SecurityUtils.getSubject(); AuthenticationToken token=new UsernamePasswordToken("zhang","123");
try {
subject.login(token);
PrincipalCollection ps=subject.getPrincipals();
System.out.println(ps.asList()); System.out.println(ps.getRealmNames());
System.out.println(subject.getPrincipal().toString()); } catch (UnknownAccountException e) {
System.out.println(e.getMessage());
}catch(IncorrectCredentialsException e){
System.out.println(e.getMessage());
} }
}
  • 结果:

(四)自定义多个Realm以及Authenticator与AuthenticationStrategy因为是FirstSuccessfulStrategy策略,myRealm1认证成功,所以只返回这个Realm的认证信息,其他的省略。

  • 修改shiro.ini,认证策略修改为AtLeastOneSuccessfulStrategy ,其他文件均不变
[main]
authenticator=org.apache.shiro.authc.pam.ModularRealmAuthenticator
securityManager.authenticator=$authenticator
atLeastOneSuccessfulStrategy=org.apache.shiro.authc.pam.AtLeastOneSuccessfulStrategy
securityManager.authenticator.authenticationStrategy=$atLeastOneSuccessfulStrategy
myRealm1=realms.MyRealm1
myRealm2=realms.MyRealm2
myRealm3=realms.MyRealm3
securityManager.realms=$myRealm1,$myRealm2,$myRealm3 [users]
zhang=123
wang=123

(四)自定义多个Realm以及Authenticator与AuthenticationStrategy

  • 修改shiro.ini,认证策略修改为AllSuccessfulStrategy,其他文件均不变
[main]
authenticator=org.apache.shiro.authc.pam.ModularRealmAuthenticator
securityManager.authenticator=$authenticator
atLeastOneSuccessfulStrategy=org.apache.shiro.authc.pam.AtLeastOneSuccessfulStrategy
securityManager.authenticator.authenticationStrategy=$atLeastOneSuccessfulStrategy
myRealm1=realms.MyRealm1
myRealm2=realms.MyRealm2
myRealm3=realms.MyRealm3
securityManager.realms=$myRealm1,$myRealm2,$myRealm3 [users]
zhang=123
wang=123

(四)自定义多个Realm以及Authenticator与AuthenticationStrategy

相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,492
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,907
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,740
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,495
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:8,132
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:5,297