千家信息网

什么是Shiro验证

发表于:2026-11-03 作者:千家信息网编辑
千家信息网最后更新 2026年11月03日,这期内容当中小编将会给大家带来有关什么是Shiro验证,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。shiro验证:用户需要提供系统理解和信任的某种身份证明(密码、
千家信息网最后更新 2026年11月03日什么是Shiro验证

这期内容当中小编将会给大家带来有关什么是Shiro验证,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。

shiro验证:用户需要提供系统理解和信任的某种身份证明(密码、证书等),来证明自己可以登录该系统。
在验证阶段需要先理解几个术语:

  • Subject(主体)- 可以通俗的理解为访问应用程序的用户。只不过这个用户可以是人、第三方进程等等。

  • Principals(身份)- 主体的唯一标识属性。例如:身份证号码、手机号、邮箱等等。

  • Credentials(凭证)- 只有主体知道的安全值。例如:密码、数字证书等等。

  • Realms(领域)- 数据访问对象。用来获取Principals和Credentials。例如:用户名和密码存放在.ini文件中,可以通过IniRealm获取用户名和密码、用户名和密码存放在数据库中,可以通过JdbcRealm获取用户名和密码等等。

  • AuthenticationToken(验证令牌)- 结合Principals(身份)和Credentials(凭证)可获得的用户身份令牌。

  • Authenticator (验证者) - 验证用户验证令牌是否满足要求的科目。

  • AuthenticationStrategy(身份验证策略)- 表示以何种策略验证用户身份。

如下是从官网获取的验证架构图:

  • 步骤1:收集主题提交的 Principals 和 Credentials 得到 Token,应用程序代码调用Subject.login方法,传入 Token 以进行身份验证动作。

  • 步骤2:Subject实例,通常是 DelegatingSubject(或子类)通过调用 securityManager.login(token)将实际的身份验证工作委托给 SecurityManager 处理

  • 步骤3:SecurityManager 作为基本的组件,接收 Token 然后通过调用 authenticate(token)将其委托给 Authenticator。Authenticator 几乎总是实例 ModularRealmAuthenticator,它支持在身份验证期间协调一个或多个 Realm 实例。

  • 步骤4:如果为应用配置了多个 Realm ,则 ModularRealmAuthenticator 实例将使用其配置的 AuthenticationStrategy 启动多领域身份验证尝试。在调用 Realms 进行身份验证之前,期间或者之后,将调用 AuthenticationStrategy 以允许它对每个 Realm 的结果做出反应。

  • 步骤5:将咨询每个 realm 以查看是否支持已提交的 AuthenticationToken。如果是这样,将使用提交的 Token 调用 realm 的getauthenticationfo方法。getauthenticationfo方法有效地表示该特定领域的单一身份验证尝试。

接下来就开始使用ShiroAPI完成验证操作了。
环境准备:

本文使用 Maven 构建,因此需要一点 Maven 知识。首先准备环境依赖:

            junit        junit        4.9        test                commons-logging        commons-logging        1.2                org.apache.shiro        shiro-core        1.3.2    

添加 junit 和 shiro-core 依赖即可。

初识:登录 / 退出

1、首先准备一些用户身份 / 凭据(shiro.ini)

[users]zhangsan=123lisi=123

2、测试用例(com.luther.shiro.authenticator.AuthenticateTest)

/** * 底层默认使用ModularRealmAuthenticator验证模块(多realm验证) 
* AtLeastOneSuccessfulStrategy验证策略(只要有一个域成功进行身份验证, * 则认为成功。否则失败。会返回所有成功的用户标识) * @author luther * @time 2019年7月5日 上午9:58:39 */@Testpublic void testHelloWorld() { // 使用Ini配置文件初始化SecurityManager Factory factory = new IniSecurityManagerFactory("classpath:shiro.ini"); // 得到SecurityManager实例 并绑定给SecurityUtils SecurityManager securityManager = factory.getInstance(); SecurityUtils.setSecurityManager(securityManager); // 得到Subject及创建用户名/密码身份验证Token(即用户身份/凭证) Subject subject = SecurityUtils.getSubject(); UsernamePasswordToken token = new UsernamePasswordToken("zhangsan", "123"); // 记住用户 token.setRememberMe(Boolean.TRUE); try { // 登录 subject.login(token); System.out.println("登录成功"); } catch (AuthenticationException e) { System.err.println("登录失败,失败原因:"); e.printStackTrace(); } assertTrue("用户已验证成功", subject.isAuthenticated()); // 退出 subject.logout();}

Realm
realm 接口结构如下,其下方法有:

String getName(); //返回一个唯一的Realm名字boolean supports(AuthenticationToken token); //判断此Realm是否支持此TokenAuthenticationInfo getAuthenticationInfo(AuthenticationToken token) throws AuthenticationException;  //根据Token获取认证信息

其中主要默认实现如下:
org.apache.shiro.realm.text.IniRealm:从ini文件获取用户权限等信息。
org.apache.shiro.realm.text.PropertiesRealm:从properties文件获取用户权限等信息。
org.apache.shiro.realm.jdbc.JdbcRealm:从数据库获取用户权限等信息。
以后开发一般继承 AuthorizingRealm(授权)抽象类即可;其继承了 AuthenticatingRealm(即身份验证),而且也间接继承了 CachingRealm(带有缓存实现)。

一、单 Realm 配置

1、自定义 Realm 实现(com.luther.shiro.realm.MyRealm1):

public class MyRealm1 implements Realm {        @Override        public String getName() {                return this.getClass().getName();        }        @Override        public boolean supports(AuthenticationToken token) {                // 只支持UsernamePasswordToken                return token instanceof UsernamePasswordToken;        }        @Override        public AuthenticationInfo getAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {                UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) token;                                // 得到用户名                String username = usernamePasswordToken.getUsername();                // 得到密码                String password = new String(usernamePasswordToken.getPassword());                                // 户名错误                if (!"zhangsan".equals(username)) {                        throw new UnknownAccountException();                 }                // 密码错误                if (!"123".equals(password)) {                        throw new IncorrectCredentialsException();                 }                System.out.println("用户" + username + "验证成功");                // 返回                return new SimpleAccount(username, password, getName());        }}

2、ini 配置文件指定自定义 Realm 实现 (shiro-realm.ini)

[main]#声明一个realmmyRealm1=com.luther.shiro.realm.MyRealm1#指定securityManager的realms实现,通过 $name 来引入之前的 realm 定义securityManager.realms=$myRealm1

3、测试用例请参考 com.luther.shiro.authenticator.AuthenticateTest 的testSingleRealm 测试方法,此方法和 testHelloWorld 除了配置文件其它没有差异。

二、多 Realm 配置

1、ini 配置文件(shiro-multi-realm.ini)

[main]#声明一个realmmyRealm1=com.luther.shiro.realm.MyRealm1#声明一个realmmyRealm2=com.luther.shiro.realm.MyRealm2#指定securityManager的realms实现,通过 $name 来引入之前的 realm 定义securityManager.realms=$myRealm2,$myRealm1#此例子中显视的指定了顺序为myRealm2,myRealm1。(可以少指定,比如只指定myRealm2,则myRealm1会被忽略)#如果不指定securityManager.realms,则会按realm的声明(无需设置 realms 属性,其会自动发现)顺序来,此处即为myRealm1,myRealm2。

2、测试用例请参考 com.luther.shiro.authenticator.AuthenticateTest 的 testMutiRealm 测试方法。

Authenticator 及 AuthenticationStrategy

一、Authenticator 及 AuthenticationStrategy简介
Authenticator 的职责是验证用户帐号,是 Shiro API 中身份验证核心的入口点(默认实现为 ModularRealmAuthenticator ),其方法定义为:

public AuthenticationInfo authenticate(AuthenticationToken authenticationToken) throws AuthenticationException;

如果验证成功,将返回 AuthenticationInfo 验证信息;此信息中包含了身份及凭证;如果验证失败将抛出相应的 AuthenticationException 实现。

AuthenticationStrategy 则是 Authenticator 进行验证时的验证策略 (默认实现为:AtLeastOneSuccessfulStrategy),Shiro API 自带的策略有以下三种:
FirstSuccessfulStrategy:只要有一个 Realm 验证成功即可,只返回第一个 Realm 身份验证成功的认证信息,其他的忽略。
AtLeastOneSuccessfulStrategy:只要有一个 Realm 验证成功即可,和 FirstSuccessfulStrategy 不同,返回所有 Realm 身份验证成功的认证信息。
AllSuccessfulStrategy:所有 Realm 验证成功才算成功,且返回所有 Realm 身份验证成功的认证信息,如果有一个失败就失败了。

二、Authenticator 及 AuthenticationStrategy演示
假设我们有三个 realm:
myRealm1: 用户名/密码为 zhangsan/123 时成功,且返回身份/凭据为 zhangsan/123;
myRealm2: 用户名/密码为 lisi/123 时成功,且返回身份/凭据为 lisi/123;
myRealm3: 用户名/密码为 zhangsan/123 时成功,且返回身份/凭据为 zhangsan.qq/123

1、通用化登录逻辑

private void authentition(String iniConfigPath, String username, String password) {        // 使用Ini配置文件初始化SecurityManager        Factory factory = new IniSecurityManagerFactory(iniConfigPath);        // 得到SecurityManager实例 并绑定给SecurityUtils        SecurityManager securityManager = factory.getInstance();        SecurityUtils.setSecurityManager(securityManager);                // 得到Subject及创建用户名/密码身份验证Token(即用户身份/凭证)        Subject subject = SecurityUtils.getSubject();        UsernamePasswordToken token = new UsernamePasswordToken(username, password);        // 记住用户        token.setRememberMe(Boolean.TRUE);                try {                // 登录                subject.login(token);                System.out.println("用户zhangsan登录成功,其身份标识为" + subject.getPrincipals());        } catch (AuthenticationException e) {                System.err.println("登录失败,失败原因:");                e.printStackTrace();        }                assertTrue("用户已验证成功", subject.isAuthenticated());                // 退出        subject.logout();}

2、测试 AtLeastOneSuccessfulStrategy
2.1 ini 配置文件 (shiro-firstSuccessfulStrategy.ini)

[main]#指定securityManager的authenticator实现,可以不指定,因为其默认实现就是ModularRealmAuthenticator#authenticator=org.apache.shiro.authc.pam.ModularRealmAuthenticator#securityManager.authenticator=$authenticator#指定securityManager.authenticator的authenticationStrategy,可以不指定,因为其默认实现就是AtLeastOneSuccessfulStrategy#authenticationStrategy=org.apache.shiro.authc.pam.AtLeastOneSuccessfulStrategy#securityManager.authenticator.authenticationStrategy=$authenticationStrategy#声明一个realmmyRealm1=com.luther.shiro.realm.MyRealm1#声明一个realmmyRealm2=com.luther.shiro.realm.MyRealm2#声明一个realmmyRealm3=com.luther.shiro.realm.MyRealm3#指定securityManager的realms实现,通过 $name 来引入之前的 realm 定义securityManager.realms=$myRealm3,$myRealm2,$myRealm1

2.2 测试代码

/** * 演示AtLeastOneSuccessfulStrategy的效果 * 每个realm都会进行验证,并返回全部的成功用户标识 * @author luther * @time 2019年7月5日  上午11:30:24 */@Testpublic void testAtLeastOneSuccessfulStrategy() {        authentition("classpath:shiro-atLeastOneSuccessfulStrategy.ini", "zhangsan", "123");}

2.3 测试结果

开始验证com.luther.shiro.realm.MyRealm3com.luther.shiro.realm.MyRealm3 - 用户zhangsan验证成功开始验证com.luther.shiro.realm.MyRealm2开始验证com.luther.shiro.realm.MyRealm1com.luther.shiro.realm.MyRealm1 - 用户zhangsan验证成功用户zhangsan登录成功,其身份标识为zhangsan.qq,zhangsan

即 PrincipalCollection 包含了 zhangsan 和 zhangsan.qq 身份信息。

3、测试 AllSuccessfulStrategy
3.1 ini 配置文件 (shiro-allSuccessfulStrategy.ini)

[main]#指定securityManager的authenticator实现,可以不指定,因为其默认实现就是ModularRealmAuthenticator#authenticator=org.apache.shiro.authc.pam.ModularRealmAuthenticator#securityManager.authenticator=$authenticator#指定securityManager.authenticator的authenticationStrategy为AllSuccessfulStrategyauthenticationStrategy=org.apache.shiro.authc.pam.AllSuccessfulStrategysecurityManager.authenticator.authenticationStrategy=$authenticationStrategy#声明一个realmmyRealm1=com.luther.shiro.realm.MyRealm1#声明一个realmmyRealm2=com.luther.shiro.realm.MyRealm2#声明一个realmmyRealm3=com.luther.shiro.realm.MyRealm3#指定securityManager的realms实现,通过 $name 来引入之前的 realm 定义securityManager.realms=$myRealm3,$myRealm2,$myRealm1

3.2 测试代码

/** * 演示AllSuccessfulStrategy的效果 * 依次对每个realm进行验证,验证通过下一个,验证失败,直接返回失败验证原因,只有全部成功时才返回全部的用户标识 * 每个realm都会进行验证,并返回全部的成功用户标识 * @author luther * @time 2019年7月5日  上午11:30:24 */@Testpublic void testAllSuccessfulStrategy() {        authentition("classpath:shiro-allSuccessfulStrategy.ini", "zhangsan", "123");}

3.3 测试结果

开始验证com.luther.shiro.realm.MyRealm3com.luther.shiro.realm.MyRealm3 - 用户zhangsan验证成功开始验证com.luther.shiro.realm.MyRealm2登录失败,失败原因:org.apache.shiro.authc.UnknownAccountException        at com.luther.shiro.realm.MyRealm2.getAuthenticationInfo(MyRealm2.java:42)        ······

4、测试 firstSuccessfulStrategy
4.1 ini 配置文件 (shiro-firstSuccessfulStrategy.ini)

[main]#指定securityManager的authenticator实现,可以不指定,因为其默认实现就是ModularRealmAuthenticator#authenticator=org.apache.shiro.authc.pam.ModularRealmAuthenticator#securityManager.authenticator=$authenticator#指定securityManager.authenticator的authenticationStrategy为FirstSuccessfulStrategyauthenticationStrategy=org.apache.shiro.authc.pam.FirstSuccessfulStrategysecurityManager.authenticator.authenticationStrategy=$authenticationStrategy#声明一个realmmyRealm1=com.luther.shiro.realm.MyRealm1#声明一个realmmyRealm2=com.luther.shiro.realm.MyRealm2#声明一个realmmyRealm3=com.luther.shiro.realm.MyRealm3#指定securityManager的realms实现,通过 $name 来引入之前的 realm 定义securityManager.realms=$myRealm3,$myRealm2,$myRealm1

4.2 测试代码

/** * 演示FirstSuccessfulStrategy的效果 * 会对每个realm进行验证,全部验证完后会返回验证成功的第一个用户标识(此处需注意,不是依次验证立马返回,而是全部验证再返回) * @author luther * @time 2019年7月5日  上午11:30:24 */@Testpublic void testFirstSuccessfulStrategy() {        authentition("classpath:shiro-firstSuccessfulStrategy.ini", "zhangsan", "123");}

4.3 测试结果

开始验证com.luther.shiro.realm.MyRealm3com.luther.shiro.realm.MyRealm3 - 用户zhangsan验证成功开始验证com.luther.shiro.realm.MyRealm2开始验证com.luther.shiro.realm.MyRealm1com.luther.shiro.realm.MyRealm1 - 用户zhangsan验证成功用户zhangsan登录成功,其身份标识为zhangsan.qq

以上已经演示了API自带的验证策略,以下稍微演示下自定义的验证策略。
自定义 AuthenticationStrategy 实现之前,首先简单看其 API:

//在所有Realm验证之前调用AuthenticationInfo beforeAllAttempts(Collection realms, AuthenticationToken token) throws AuthenticationException;//在每个Realm之前调用AuthenticationInfo beforeAttempt(Realm realm, AuthenticationToken token, AuthenticationInfo aggregate) throws AuthenticationException;//在每个Realm之后调用AuthenticationInfo afterAttempt(Realm realm, AuthenticationToken token, AuthenticationInfo singleRealmInfo, AuthenticationInfo aggregateInfo, Throwable t)throws AuthenticationException;//在所有Realm之后调用AuthenticationInfo afterAllAttempts(AuthenticationToken token, AuthenticationInfo aggregate) throws AuthenticationException;

5、自定义验证策略(com.luther.shiro.authenticationStrategy.LastSuccessfulStrategy)

/** * 验证所有realm,并返回最后一个验证通过的身份标识 * @author luther * @time 2019年7月5日  下午4:12:31 */public class LastSuccessfulStrategy extends AbstractAuthenticationStrategy {                // 第一种方案修改afterAttempt方法        @Override        public AuthenticationInfo afterAttempt(Realm realm, AuthenticationToken token, AuthenticationInfo singleRealmInfo,                        AuthenticationInfo aggregateInfo, Throwable t) throws AuthenticationException {                return singleRealmInfo;        }//      // 第二种方案修改merge方法//      @Override//      protected AuthenticationInfo merge(AuthenticationInfo info, AuthenticationInfo aggregate) {//              if (info != null) {//                      aggregate = info;//              }//              //              return aggregate;//      }        }

5.1 ini 配置文件 (shiro-lastSuccessfulStrategy.ini)

[main]#指定securityManager的authenticator实现,可以不指定,因为其默认实现就是ModularRealmAuthenticator#authenticator=org.apache.shiro.authc.pam.ModularRealmAuthenticator#securityManager.authenticator=$authenticator#指定securityManager.authenticator的authenticationStrategy为自定义的LastSuccessfulStrategyauthenticationStrategy=com.luther.shiro.authenticationStrategy.LastSuccessfulStrategysecurityManager.authenticator.authenticationStrategy=$authenticationStrategy#声明一个realmmyRealm1=com.luther.shiro.realm.MyRealm1#声明一个realmmyRealm2=com.luther.shiro.realm.MyRealm2#声明一个realmmyRealm3=com.luther.shiro.realm.MyRealm3#指定securityManager的realms实现,通过 $name 来引入之前的 realm 定义securityManager.realms=$myRealm3,$myRealm2,$myRealm1

5.2 测试代码

/** * 演示自定义的LastSuccessfulStrategy的效果 * 会对每个realm进行验证,全部验证完后会返回验证成功的最后一个用户标识        * @author luther * @time 2019年7月5日  上午11:30:24 */@Testpublic void testLastSuccessfulStrategy() {        authentition("classpath:shiro-lastSuccessfulStrategy.ini", "zhangsan", "123");}

5.3 测试结果

开始验证com.luther.shiro.realm.MyRealm3com.luther.shiro.realm.MyRealm3 - 用户zhangsan验证成功开始验证com.luther.shiro.realm.MyRealm2开始验证com.luther.shiro.realm.MyRealm1com.luther.shiro.realm.MyRealm1 - 用户zhangsan验证成功用户zhangsan登录成功,其身份标识为zhangsan

上述就是小编为大家分享的什么是Shiro验证了,如果刚好有类似的疑惑,不妨参照上述分析进行理解。如果想知道更多相关知识,欢迎关注行业资讯频道。

验证 用户 成功 身份 测试 密码 登录 配置 文件 标识 用户名 信息 方法 策略 演示 实例 就是 代码 凭证 步骤 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 广东万易互联网科技有限公司惠州分公司 山东特亿宝互联网科技有限公司 互联网电商科技 青岛互联网科技公司 成都互联网科技公司 百单互联网科技有限公司 天津摩尔互联网科技 互联网科技博客 成都狮子座互联网科技 银川新华互联网科技学校地址 港股科技和互联网 黑科技闪耀互联网之光 阿大互联网科技有限公司 杭州壁岐互联网科技有限公司 长沙茂晟互联网科技有限公司 合肥互联网科技公司公章图片 东营紫格互联网科技 银川新华互联网科技学校是国营吗 10位科技互联网大佬 如何强化互联网金融科技 易互联网科技有限公司 广州凡科互联网科技 郑州华宇互联网科技 掌上梦互联网科技 居家互联网科技有限公司 太原新华互联网科技学校怎么样 互联网公司黑科技创始人 互联网科技企业商标注意事项 互联网科技职业技能培训学校 互联网科技对化妆品行业
0