shiro身份验证 2022-06-14 11:47 1088阅读 0赞 ## 1.场景还原 ## Shiro 是 Java 的一个安全框架。目前,使用 Apache Shiro 的人越来越多,因为它非常实用又简单易懂,今天笔者就shiro的身份验证讲解一下,希望小伙伴能够受益。 ## 2.概念梳理 ## ** Subject** :主体(用户) ** Realm**:验证主体的数据源 ## 3.验证步骤 ## ①加入shiro依赖 <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-core</artifactId> <version>1.2.2</version> </dependency> ②自定义主体数据源realm,集成Realm public class MyRealm1 implements Realm { @Override public String getName() { return "myrealm1"; } @Override public boolean supports(AuthenticationToken token) { return token instanceof UsernamePasswordToken; //仅支持UsernamePasswordToken类型的Token } @Override public AuthenticationInfo getAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { String username = (String)token.getPrincipal(); //得到用户名 String password = new String((char[])token.getCredentials()); //得到密码 if(!"zhang".equals(username)) { throw new UnknownAccountException(); //如果用户名错误 } if(!"123".equals(password)) { throw new IncorrectCredentialsException(); //如果密码错误 } //如果身份认证验证成功,返回一个AuthenticationInfo实现; return new SimpleAuthenticationInfo(username, password, getName()); } } ③测试自定义数据源 @Test public void testCustomRealm() { //1、获取SecurityManager工厂,此处使用Ini配置文件初始化SecurityManager Factory<org.apache.shiro.mgt.SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro-realm.ini"); //2、得到SecurityManager实例 并绑定给SecurityUtils org.apache.shiro.mgt.SecurityManager securityManager = factory.getInstance(); SecurityUtils.setSecurityManager(securityManager); //3、得到Subject及创建用户名/密码身份验证Token(即用户身份/凭证) Subject subject = SecurityUtils.getSubject(); UsernamePasswordToken token = new UsernamePasswordToken("zhang", "123"); try { //4、登录,即身份验证 subject.login(token); } catch (AuthenticationException e) { //5、身份验证失败 e.printStackTrace(); } Assert.assertEquals(true, subject.isAuthenticated()); //断言用户已经登录 //6、退出 subject.logout(); } resources下新建shiro-realm.ini [main] #声明一个realm myRealm1=realm.MyRealm1 #指定securityManager的realms实现 securityManager.realms=$myRealm1 多个realm配置 [main] #声明一个realm myRealm1=realm.MyRealm1 myRealm2=realm.MyRealm2 #指定securityManager的realms实现 securityManager.realms=$myRealm1,$myRealm2 测试结果: ![Center][] 表明验证顺利通过! 主体数据源还可以直接写用户信息shiro.ini [users] zhang=123 wang=123 表明zhang/123,wang/123两个用户,相同地,验证也可通过; ④连接数据得到主体数据源 1>shiro-jdbc-realm.ini [main] jdbcRealm=org.apache.shiro.realm.jdbc.JdbcRealm dataSource=com.alibaba.druid.pool.DruidDataSource dataSource.driverClassName=com.mysql.jdbc.Driver dataSource.url=jdbc:mysql://localhost:3306/shiro dataSource.username=root dataSource.password=root jdbcRealm.dataSource=$dataSource securityManager.realms=$jdbcRealm 2>测试类 @Test public void testJDBCRealm() { //1、获取SecurityManager工厂,此处使用Ini配置文件初始化SecurityManager Factory<org.apache.shiro.mgt.SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro-jdbc-realm.ini"); //2、得到SecurityManager实例 并绑定给SecurityUtils org.apache.shiro.mgt.SecurityManager securityManager = factory.getInstance(); SecurityUtils.setSecurityManager(securityManager); //3、得到Subject及创建用户名/密码身份验证Token(即用户身份/凭证) Subject subject = SecurityUtils.getSubject(); UsernamePasswordToken token = new UsernamePasswordToken("liyang", "123"); try { //4、登录,即身份验证 subject.login(token); } catch (AuthenticationException e) { //5、身份验证失败 e.printStackTrace(); } if(subject.isAuthenticated()){ System.out.print("登陆成功"); }else{ System.out.print("登陆失败"); } Assert.assertEquals(true, subject.isAuthenticated()); //断言用户已经登录 //6、退出 subject.logout(); } 3>本地数据库数据 ![Center 1][] 测试结果: ![Center 2][] ## 4.认证策略详解 ## SecurityManager 接口继承了 Authenticator,另外还有一个 ModularRealmAuthenticator 实现,其委托给多个 Realm 进行验证,验证规则通过 AuthenticationStrategy 接口指定,默认提供的实现: **FirstSuccessfulStrategy**:只要有一个 Realm 验证成功即可,只返回第一个 Realm 身份验证成功的认证信息,其他的忽略; **AtLeastOneSuccessfulStrategy**:只要有一个 Realm 验证成功即可,和 FirstSuccessfulStrategy不同,返回所有 Realm 身份验证成功的认证信息; **AllSuccessfulStrategy**:所有 Realm 验证成功才算成功,且返回所有 Realm 身份验证成功的认证信息,如果有一个失败就失败了。 ModularRealmAuthenticator 默认使用 AtLeastOneSuccessfulStrategy 策略。 ①shiro-atLeatOne-success.ini [main] #指定securityManager的authenticator实现 authenticator=org.apache.shiro.authc.pam.ModularRealmAuthenticator securityManager.authenticator=$authenticator #指定securityManager.authenticator的authenticationStrategy allSuccessfulStrategy=org.apache.shiro.authc.pam.AtLeastOneSuccessfulStrategy securityManager.authenticator.authenticationStrategy=$allSuccessfulStrategy myRealm1=realm.MyRealm1 myRealm2=realm.MyRealm2 myRealm3=realm.MyRealm3 securityManager.realms=$myRealm1,$myRealm2,$myRealm3 ②shrio-fisrt-success.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=realm.MyRealm1 myRealm2=realm.MyRealm2 myRealm3=realm.MyRealm3 securityManager.realms=$myRealm1,$myRealm2,$myRealm3 ③shiro-all-success.ini [main] #指定securityManager的authenticator实现 authenticator=org.apache.shiro.authc.pam.ModularRealmAuthenticator securityManager.authenticator=$authenticator #指定securityManager.authenticator的authenticationStrategy allSuccessfulStrategy=org.apache.shiro.authc.pam.AllSuccessfulStrategy securityManager.authenticator.authenticationStrategy=$allSuccessfulStrategy myRealm1=realm.MyRealm1 myRealm2=realm.MyRealm2 myRealm3=realm.MyRealm3 securityManager.realms=$myRealm1,$myRealm3 然后测试 public class AuthenticatorTest { @Test public void testAllSuccessfulStrategyWithSuccess() { login("classpath:shiro-authenticator-all-success.ini"); Subject subject = SecurityUtils.getSubject(); //得到一个身份集合,其包含了Realm验证成功的身份信息 PrincipalCollection principalCollection = subject.getPrincipals(); System.out.print(principalCollection.asList().get(1)); Assert.assertEquals(2, principalCollection.asList().size()); } @Test public void testAtLeastOneSuccessfulStrategyWithSuccess() { login("classpath:shiro-authenticator-atLeastOne-success.ini"); Subject subject = SecurityUtils.getSubject(); //得到一个身份集合,其包含了Realm验证成功的身份信息 PrincipalCollection principalCollection = subject.getPrincipals(); System.out.print(principalCollection.asList().get(0)); Assert.assertEquals(2, principalCollection.asList().size()); } @Test public void testFirstOneSuccessfulStrategyWithSuccess() { login("classpath:shiro-authenticator-first-success.ini"); Subject subject = SecurityUtils.getSubject(); //得到一个身份集合,其包含了第一个Realm验证成功的身份信息 PrincipalCollection principalCollection = subject.getPrincipals(); Assert.assertEquals(1, principalCollection.asList().size()); } private void login(String configFile) { //1、获取SecurityManager工厂,此处使用Ini配置文件初始化SecurityManager Factory<org.apache.shiro.mgt.SecurityManager> factory = new IniSecurityManagerFactory(configFile); //2、得到SecurityManager实例 并绑定给SecurityUtils org.apache.shiro.mgt.SecurityManager securityManager = factory.getInstance(); SecurityUtils.setSecurityManager(securityManager); //3、得到Subject及创建用户名/密码身份验证Token(即用户身份/凭证) Subject subject = SecurityUtils.getSubject(); UsernamePasswordToken token = new UsernamePasswordToken("zhang", "123"); subject.login(token); System.out.println(subject.isAuthenticated()); } @After public void tearDown() throws Exception { ThreadContext.unbindSubject();//退出时请解除绑定Subject到线程 否则对下次测试造成影响 } } 好了,大伙按需get!我是张星,欢迎加去博主技术交流群,群号:313145288 [Center]: /images/20220614/bba70d32731c4953ab26ff7889f21296.png [Center 1]: /images/20220614/6a0663aa57e0480991a423acb50865d0.png [Center 2]: /images/20220614/68337aba473045c7a1fb2e9490ee58de.png
相关 Shiro学习笔记(2)——身份验证之Realm 环境准备 什么是Realm 为什么要用Realm 自定义Realm 散列算法支持 多个Realm 配置Authenticator和Au 怼烎@/ 2022年08月05日 00:56/ 0 赞/ 216 阅读
相关 Shiro学习(2)身份验证 身份验证:即在应用中谁能证明他就是他本人。一般提供如他们的身份ID一些标识信息来表明他就是他本人,如提供身份证,用户名/密码来证明。 在shiro中,用户需要提供princ 悠悠/ 2022年07月26日 01:53/ 0 赞/ 1040 阅读
相关 shiro身份验证 1.场景还原 Shiro 是 Java 的一个安全框架。目前,使用 Apache Shiro 的人越来越多,因为它非常实用又简单易懂,今天笔者就shiro的身份验 缺乏、安全感/ 2022年06月14日 11:47/ 0 赞/ 1089 阅读
相关 Shiro笔记(四)----身份验证之Realm 一、Realm简介 1.什么是Realm Realm 是可以访问程序特定的安全数据如用户、角色、权限等的一个组件。Realm会将这些程序特定的安全数据转 ゝ一纸荒年。/ 2022年06月11日 22:53/ 0 赞/ 870 阅读
相关 Shiro(二)之身份验证 一、身份验证 即在应用中谁能证明他就是他本人。一般提供如他们的身份 ID 一些标识信息来表明他就是他本人,如提供身份证,用户名/密码来证明。 在 shiro 中,用户需 曾经终败给现在/ 2022年06月01日 09:41/ 0 赞/ 1124 阅读
相关 Shiro步步为营--Springboot开启身份验证 项目的完整目录层次如下图所示。 ![20190703090529803.png][] 项目地址:[https://github.com/pengjunlee/shiro-a 深碍√TFBOYSˉ_/ 2021年12月15日 15:57/ 0 赞/ 253 阅读
相关 Apache Shiro学习笔记(二)身份验证获取SecurityManager Shiro配置文件(first-shiro.ini) <table style="padding:0px; margin:0px auto 10px; font-size:1 灰太狼/ 2021年09月23日 02:52/ 0 赞/ 360 阅读
相关 Shiro--身份验证 身份验证 身份验证: 即在应用中谁能证明他就是他本人。一般提供如他们的身份ID一些标识信息来表明他就是他本人,如提供身份证,用户名/密码来证明。 ゞ 浴缸里的玫瑰/ 2021年08月24日 22:51/ 0 赞/ 1244 阅读
相关 思维导图视频代码揭秘shiro身份验证 > 思维导图、视频、代码携手揭秘shiro,干货多多,趣味多多! 目录 思维导图 视频 代码 -------------------- 思维导图 ![ Dear 丶/ 2021年07月25日 02:30/ 0 赞/ 306 阅读
相关 Apache Shiro身份验证 主要概念 身份验证:一般需要提供身份ID等一些标识信息来表明登录者的身份,如提供email,用户名/密码来证明。 在shiro中,用户需要提供principals(身 比眉伴天荒/ 2021年06月24日 16:12/ 0 赞/ 1437 阅读
还没有评论,来说两句吧...