学习shiro第三天
今天比较晚,所以只看了shiro的认证策略Authentication Strategy,下面讲讲shiro的三种认证策略。
1.AtLeastOneSuccessfulStrategy:这个是shiro默认的认证策略,它表示如果存在多个realm来执行认证,只要其中有一个成功,那么认证就成功(这里注意所有的realm都会进行验证,不管是失败还是成功);
2.AllSuccessfulStrategy:这个策略表示必须所有的realm认证成功才算最终认证成功,哪怕只有一个不成功,那么结果都为认证不成功。(这里也是会将所有的realm都进行验证);
3.FirstSuccessfulStrategy:它表示只要有一个realm中认证成功了,那么剩下的其它realm都不必进行验证了,直接返回认证成功。注意这里只要遇到第一个成功认证的realm,其他剩下的realm都不会被调用。
说了三种认证策略的概念,那么我们怎么进行配置认证策略呢?这个问题就要追溯到shiro中进行认证操作的认证器子类modularRealmAuthenticator,它里面有一个属性authenticationStrategy,并且
modularRealmAuthenticator在它的构造函数中将这个属性默认设置成new AtLeastOneSuccessfulStrategy():
private AuthenticationStrategy authenticationStrategy;
/*--------------------------------------------
| C O N S T R U C T O R S |
============================================*/
/**
* Default no-argument constructor which
* {@link #setAuthenticationStrategy(AuthenticationStrategy) enables} an
* {@link org.apache.shiro.authc.pam.AtLeastOneSuccessfulStrategy} by default.
*/
public ModularRealmAuthenticator() {
this.authenticationStrategy = new AtLeastOneSuccessfulStrategy();
}
所有我们要配置认证策略,只需要配置modularRealmAuthenticator类中的authenticationStrategy属性。下面是配置认证策略的过程:
[main]
dataSource=com.mchange.v2.c3p0.ComboPooledDataSource
dataSource.driverClass=com.mysql.jdbc.Driver
dataSource.jdbcUrl=jdbc:mysql://localhost:3306/test
dataSource.user=root
dataSource.password=root
myRealm=org.apache.shiro.realm.jdbc.JdbcRealm
myRealm.dataSource=$dataSource dataSource1=com.mchange.v2.c3p0.ComboPooledDataSource
dataSource1.driverClass=com.mysql.jdbc.Driver
dataSource1.jdbcUrl=jdbc:mysql://localhost:3306/test1
dataSource1.user=root
dataSource1.password=root
myRealm1=org.apache.shiro.realm.jdbc.JdbcRealm
myRealm1.dataSource=$dataSource1
#配置认证策略
authenticator=org.apache.shiro.authc.pam.ModularRealmAuthenticator
authenticationStrategy=org.apache.shiro.authc.pam.FirstSuccessfulStrategy
authenticator.authenticationStrategy=$authenticationStrategy
securityManager.authenticator=$authenticator
securityManager.realms=$myRealm,$myRealm1
在配置认证策略中,我将认证策略配成了FirstSuccessFulStrategy,然后将这个配置了新的认证策略的认证器赋予了SecurityManager中的authenticator属性从而完成了认证策略的配置。为了测试这几个策略的区别,我在shiro.ini文件中又创建了一个realm,并注入了一个新的数据源:





两个数据库中都有users的表,但是数据并不相同。下面开始认证编码,还是那一套流程:
package test_JdbcRealm; import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.config.IniSecurityManagerFactory;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.Factory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory; public class TestAuthencationStrategy { private static final Logger logger = LoggerFactory.getLogger(TestAuthencationStrategy.class); public static void main(String[] args) {
//1.创建securityManager工厂
Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");
//2.获取securityManager实例
SecurityManager securityManager = factory.getInstance();
//3.将SecurityManager实例设置到SecurityUtils工具类中
SecurityUtils.setSecurityManager(securityManager);
//4。创建Subject实例
Subject subject = SecurityUtils.getSubject();
//5.获取token,模拟用户登陆
UsernamePasswordToken token = new UsernamePasswordToken("wangwu", "456789");
try {
//6.认证token
subject.login(token);
if(subject.isAuthenticated()) {
logger.info("登陆成功");
}
} catch (AuthenticationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
logger.error("用户名或密码错误,登陆失败");
}
}
}
运行控制台输出如下:
2019-07-26 23:54:32,756 INFO [com.mchange.v2.log.MLog] - MLog clients using slf4j logging.
2019-07-26 23:54:33,216 INFO [com.mchange.v2.c3p0.C3P0Registry] - Initializing c3p0-0.9.5.2 [built 08-December-2015 22:06:04 -0800; debug? true; trace: 10]
2019-07-26 23:54:33,344 INFO [org.apache.shiro.config.IniSecurityManagerFactory] - Realms have been explicitly set on the SecurityManager instance - auto-setting of realms will not occur.
2019-07-26 23:54:33,373 INFO [com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource] - Initializing c3p0 pool... com.mchange.v2.c3p0.ComboPooledDataSource [ acquireIncrement -> 3, acquireRetryAttempts -> 30, acquireRetryDelay -> 1000, autoCommitOnClose -> false, automaticTestTable -> null, breakAfterAcquireFailure -> false, checkoutTimeout -> 0, connectionCustomizerClassName -> null, connectionTesterClassName -> com.mchange.v2.c3p0.impl.DefaultConnectionTester, contextClassLoaderSource -> caller, dataSourceName -> 2zm2h7a4d1dnn281ezvn|7e0ea639, debugUnreturnedConnectionStackTraces -> false, description -> null, driverClass -> com.mysql.jdbc.Driver, extensions -> {}, factoryClassLocation -> null, forceIgnoreUnresolvedTransactions -> false, forceSynchronousCheckins -> false, forceUseNamedDriverClass -> false, identityToken -> 2zm2h7a4d1dnn281ezvn|7e0ea639, idleConnectionTestPeriod -> 0, initialPoolSize -> 3, jdbcUrl -> jdbc:mysql://localhost:3306/test, maxAdministrativeTaskTime -> 0, maxConnectionAge -> 0, maxIdleTime -> 0, maxIdleTimeExcessConnections -> 0, maxPoolSize -> 15, maxStatements -> 0, maxStatementsPerConnection -> 0, minPoolSize -> 3, numHelperThreads -> 3, preferredTestQuery -> null, privilegeSpawnedThreads -> false, properties -> {user=******, password=******}, propertyCycle -> 0, statementCacheNumDeferredCloseThreads -> 0, testConnectionOnCheckin -> false, testConnectionOnCheckout -> false, unreturnedConnectionTimeout -> 0, userOverrides -> {}, usesTraditionalReflectiveProxies -> false ]
2019-07-26 23:54:33,677 INFO [com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource] - Initializing c3p0 pool... com.mchange.v2.c3p0.ComboPooledDataSource [ acquireIncrement -> 3, acquireRetryAttempts -> 30, acquireRetryDelay -> 1000, autoCommitOnClose -> false, automaticTestTable -> null, breakAfterAcquireFailure -> false, checkoutTimeout -> 0, connectionCustomizerClassName -> null, connectionTesterClassName -> com.mchange.v2.c3p0.impl.DefaultConnectionTester, contextClassLoaderSource -> caller, dataSourceName -> 2zm2h7a4d1dnn281ezvn|6e1567f1, debugUnreturnedConnectionStackTraces -> false, description -> null, driverClass -> com.mysql.jdbc.Driver, extensions -> {}, factoryClassLocation -> null, forceIgnoreUnresolvedTransactions -> false, forceSynchronousCheckins -> false, forceUseNamedDriverClass -> false, identityToken -> 2zm2h7a4d1dnn281ezvn|6e1567f1, idleConnectionTestPeriod -> 0, initialPoolSize -> 3, jdbcUrl -> jdbc:mysql://localhost:3306/test1, maxAdministrativeTaskTime -> 0, maxConnectionAge -> 0, maxIdleTime -> 0, maxIdleTimeExcessConnections -> 0, maxPoolSize -> 15, maxStatements -> 0, maxStatementsPerConnection -> 0, minPoolSize -> 3, numHelperThreads -> 3, preferredTestQuery -> null, privilegeSpawnedThreads -> false, properties -> {user=******, password=******}, propertyCycle -> 0, statementCacheNumDeferredCloseThreads -> 0, testConnectionOnCheckin -> false, testConnectionOnCheckout -> false, unreturnedConnectionTimeout -> 0, userOverrides -> {}, usesTraditionalReflectiveProxies -> false ]
2019-07-26 23:54:33,696 INFO [org.apache.shiro.session.mgt.AbstractValidatingSessionManager] - Enabling session validation scheduler...
2019-07-26 23:54:33,704 INFO [test_JdbcRealm.TestAuthencationStrategy] - 登陆成功
可以看到虽然test数据库中没有wangwu这个用户,但是test1数据库中有,所以myRealm1的认证过程是成功了的,而myRealm的认证过程毋庸置疑是失败了的,但是我们这里配的认证策略是FirstSuccessfulStrategy,所以只要有一个成功,就认证成功。
我们把认证策略改成AllSuccessfulStrategy再来测试一下上面的认证流程,发现控制台输出了如下内容:
2019-07-26 23:59:26,933 INFO [com.mchange.v2.log.MLog] - MLog clients using slf4j logging.
2019-07-26 23:59:27,323 INFO [com.mchange.v2.c3p0.C3P0Registry] - Initializing c3p0-0.9.5.2 [built 08-December-2015 22:06:04 -0800; debug? true; trace: 10]
2019-07-26 23:59:27,447 INFO [org.apache.shiro.config.IniSecurityManagerFactory] - Realms have been explicitly set on the SecurityManager instance - auto-setting of realms will not occur.
2019-07-26 23:59:27,476 INFO [com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource] - Initializing c3p0 pool... com.mchange.v2.c3p0.ComboPooledDataSource [ acquireIncrement -> 3, acquireRetryAttempts -> 30, acquireRetryDelay -> 1000, autoCommitOnClose -> false, automaticTestTable -> null, breakAfterAcquireFailure -> false, checkoutTimeout -> 0, connectionCustomizerClassName -> null, connectionTesterClassName -> com.mchange.v2.c3p0.impl.DefaultConnectionTester, contextClassLoaderSource -> caller, dataSourceName -> 2zm2h7a4d1jymk14v9ac3|7e0ea639, debugUnreturnedConnectionStackTraces -> false, description -> null, driverClass -> com.mysql.jdbc.Driver, extensions -> {}, factoryClassLocation -> null, forceIgnoreUnresolvedTransactions -> false, forceSynchronousCheckins -> false, forceUseNamedDriverClass -> false, identityToken -> 2zm2h7a4d1jymk14v9ac3|7e0ea639, idleConnectionTestPeriod -> 0, initialPoolSize -> 3, jdbcUrl -> jdbc:mysql://localhost:3306/test, maxAdministrativeTaskTime -> 0, maxConnectionAge -> 0, maxIdleTime -> 0, maxIdleTimeExcessConnections -> 0, maxPoolSize -> 15, maxStatements -> 0, maxStatementsPerConnection -> 0, minPoolSize -> 3, numHelperThreads -> 3, preferredTestQuery -> null, privilegeSpawnedThreads -> false, properties -> {user=******, password=******}, propertyCycle -> 0, statementCacheNumDeferredCloseThreads -> 0, testConnectionOnCheckin -> false, testConnectionOnCheckout -> false, unreturnedConnectionTimeout -> 0, userOverrides -> {}, usesTraditionalReflectiveProxies -> false ]
org.apache.shiro.authc.UnknownAccountException: No account found for user [wangwu]
at org.apache.shiro.realm.jdbc.JdbcRealm.doGetAuthenticationInfo(JdbcRealm.java:244)
2019-07-26 23:59:27,761 ERROR [test_JdbcRealm.TestAuthencationStrategy] - 用户名或密码错误,登陆失败
at org.apache.shiro.realm.AuthenticatingRealm.getAuthenticationInfo(AuthenticatingRealm.java:571)
at org.apache.shiro.authc.pam.ModularRealmAuthenticator.doMultiRealmAuthentication(ModularRealmAuthenticator.java:219)
at org.apache.shiro.authc.pam.ModularRealmAuthenticator.doAuthenticate(ModularRealmAuthenticator.java:269)
at org.apache.shiro.authc.AbstractAuthenticator.authenticate(AbstractAuthenticator.java:198)
at org.apache.shiro.mgt.AuthenticatingSecurityManager.authenticate(AuthenticatingSecurityManager.java:106)
at org.apache.shiro.mgt.DefaultSecurityManager.login(DefaultSecurityManager.java:275)
at org.apache.shiro.subject.support.DelegatingSubject.login(DelegatingSubject.java:260)
at test_JdbcRealm.TestAuthencationStrategy.main(TestAuthencationStrategy.java:30)
报了用户找不到的异常,因为在test数据库中我们并没有wangwu这个用户,所以myRealm认证是失败的,而我们配置了AllSuccessfulStrategy这个策略,只要有一个认证失败,那么最终就认证失败,因此这里输出了认证失败的提示语。
以上是我今天所看的shiro认证策略的内容和应用,如果有什么纠正和补充的请在评论区留言,谢谢!
学习shiro第三天的更多相关文章
- Shiro learning - 入门学习 Shiro中的基础知识(1)
Shiro入门学习 一 .什么是Shiro? 看一下官网对于 what is Shiro ? 的解释 Apache Shiro (pronounced “shee-roh”, the Japanese ...
- 学习shiro第二天
昨天讲了shiro的认证流程以及代码实现,今天将对这个进行扩展. 因为我们的测试数据是shiro.ini文件中配置的静态数据,但实际上数据应该从数据库中查询出来才合理,因此我们今天讲讲JdbcReal ...
- 我的MYSQL学习心得(三) 查看字段长度
我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(四) 数据类型 我的MYSQL学习心得(五) 运 ...
- PyQt4入门学习笔记(三)
# PyQt4入门学习笔记(三) PyQt4内的布局 布局方式是我们控制我们的GUI页面内各个控件的排放位置的.我们可以通过两种基本方式来控制: 1.绝对位置 2.layout类 绝对位置 这种方式要 ...
- 学习javascript数据结构(三)——集合
前言 总括: 本文讲解了数据结构中的[集合]概念,并使用javascript实现了集合. 原文博客地址:学习javascript数据结构(三)--集合 知乎专栏&&简书专题:前端进击者 ...
- 小菜学习设计模式(三)—工厂方法(Factory Method)模式
前言 设计模式目录: 小菜学习设计模式(一)—模板方法(Template)模式 小菜学习设计模式(二)—单例(Singleton)模式 小菜学习设计模式(三)—工厂方法(Factory Method) ...
- MATLAB地图工具箱学习总结(三)地图工具箱的基本知识
MATLAB地图工具箱学习总结(三)地图工具箱的基本知识 今天想要介绍的是一些比较基础的函数.了解了这些函数,地图投影的基本概念才能真正明白.而要想继续研究MATLAB中有关地图投影的函数,尤其是未来 ...
- python学习心得第三章
python学习心得第三章 1.三元运算 变量=值1 if 条件 else 值2 由图如果条件成立则赋值1给变量,如果条件不成立则赋值2给变量. 2.数据类型 集合:set() class set(o ...
- C#可扩展编程之MEF学习笔记(三):导出类的方法和属性
前面说完了导入和导出的几种方法,如果大家细心的话会注意到前面我们导出的都是类,那么方法和属性能不能导出呢???答案是肯定的,下面就来说下MEF是如何导出方法和属性的. 还是前面的代码,第二篇中已经提供 ...
随机推荐
- HTTP 压测工具wrk简介
前段时间项目压测,看到开发命令行下使用这个命令进行压测非常简洁.方便,萌发了学习的兴趣,这里仅做简单介绍. 安装 wrk支持大多数UNIX系统,不支持Windows.需要操作系统支持LuaJIT和Op ...
- .NET能开发出什么样的APP?盘点通过Smobiler开发的APP
.NET程序员一定最熟悉所见即所得式开发,亲切的Visual Studio开发界面,敲了无数个日夜的C#代码. Smobiler也是因为具备这样的特性,使开发人员,可以在VisualStudio上,像 ...
- 【JavaWeb】实现二级联动菜单
实现效果 频道信息 package demo; public class Channel { private String code; //频道编码 private String name; //频道 ...
- 3.JavaCC 语法描述文件的格式解析
JavaCC的语法描述文件格式如下所示: options { JavaCC的选项 } PARSER_BEGIN(解析器类名) package 包名; import 库名; public class ...
- [Go] 利用有缓存channel控制同时并发的数量
如果有一个大循环,里面每一个都开启groutine,那么瞬间就会开启非常多的groutine,要解决这个问题就要用channel的阻塞特性来解决 package main import "t ...
- nginx默认配置文件解释
nginx默认配置文件 nginx.conf 介绍: 全局配置 user nginx; 设置nginx服务的系统使用用户 worker_processes 1; 工作进程数(建议和CPU核心数保持 ...
- day3_7.1
1.python的注释 python中为了使代码更容易被人看懂,提高团队开发效率,可使用注释.代码中的注释不加入编译中. 注释有单行注释,如 #这是一段注释 和多行注释: ''' 这是一行注释 ''' ...
- 项目那几步走:先配置setting路径文件、创建数据库、执行数据库迁移命令、配置mysql数据库信息、注册app、注释中间件、pymysql替换mysqldb-配置urls路由-继续视图函数-然后HTML页面展示-HTML里面导入css文件、models配置数据库表、
django使用mysql数据库: 首先cmd创建库 1.settings: """Django settings for day42 project. Generate ...
- 剑指Offer-11.二进制中1的个数(C++/Java)
题目: 输入一个整数,输出该数二进制表示中1的个数.其中负数用补码表示. 分析: 将数字和1先做与运算,然后将1右移一位,现在是判断数字的第二位是不是1,这样循环的做下去即可.也可以转换成字符串再统计 ...
- WinSxS目录下文件的清除
1)McAfee Scanner service 持续高cpu 2)上网查到了,需要看 %deflogdir%目录下的OnDemandScan_Activity.log 3) 打开这个文件,发觉一直在 ...