shiro身份验证
来源:互联网 发布:电路原理图软件 编辑:程序博客网 时间:2024/06/14 04:37
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()); }}
③测试自定义数据源
@Testpublic 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]#声明一个realmmyRealm1=realm.MyRealm1#指定securityManager的realms实现securityManager.realms=$myRealm1
多个realm配置
[main]#声明一个realmmyRealm1=realm.MyRealm1myRealm2=realm.MyRealm2#指定securityManager的realms实现securityManager.realms=$myRealm1,$myRealm2测试结果:
表明验证顺利通过!
主体数据源还可以直接写用户信息shiro.ini
[users]zhang=123wang=123表明zhang/123,wang/123两个用户,相同地,验证也可通过;
④连接数据得到主体数据源
1>shiro-jdbc-realm.ini
[main]jdbcRealm=org.apache.shiro.realm.jdbc.JdbcRealmdataSource=com.alibaba.druid.pool.DruidDataSourcedataSource.driverClassName=com.mysql.jdbc.DriverdataSource.url=jdbc:mysql://localhost:3306/shirodataSource.username=rootdataSource.password=rootjdbcRealm.dataSource=$dataSourcesecurityManager.realms=$jdbcRealm2>测试类
@Testpublic 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>本地数据库数据
测试结果:
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.ModularRealmAuthenticatorsecurityManager.authenticator=$authenticator#指定securityManager.authenticator的authenticationStrategyallSuccessfulStrategy=org.apache.shiro.authc.pam.AtLeastOneSuccessfulStrategysecurityManager.authenticator.authenticationStrategy=$allSuccessfulStrategymyRealm1=realm.MyRealm1myRealm2=realm.MyRealm2myRealm3=realm.MyRealm3securityManager.realms=$myRealm1,$myRealm2,$myRealm3②shrio-fisrt-success.ini
[main]#指定securityManager的authenticator实现authenticator=org.apache.shiro.authc.pam.ModularRealmAuthenticatorsecurityManager.authenticator=$authenticator#指定securityManager.authenticator的authenticationStrategyallSuccessfulStrategy=org.apache.shiro.authc.pam.FirstSuccessfulStrategysecurityManager.authenticator.authenticationStrategy=$allSuccessfulStrategymyRealm1=realm.MyRealm1myRealm2=realm.MyRealm2myRealm3=realm.MyRealm3securityManager.realms=$myRealm1,$myRealm2,$myRealm3③shiro-all-success.ini
[main]#指定securityManager的authenticator实现authenticator=org.apache.shiro.authc.pam.ModularRealmAuthenticatorsecurityManager.authenticator=$authenticator#指定securityManager.authenticator的authenticationStrategyallSuccessfulStrategy=org.apache.shiro.authc.pam.AllSuccessfulStrategysecurityManager.authenticator.authenticationStrategy=$allSuccessfulStrategymyRealm1=realm.MyRealm1myRealm2=realm.MyRealm2myRealm3=realm.MyRealm3securityManager.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
- shiro 身份验证
- shiro 身份验证
- Shiro身份验证
- Shiro身份验证
- shiro身份验证
- Shiro身份验证
- 第二章 Shiro身份验证
- Shiro身份验证(三)
- Apache Shiro 身份验证
- 初学Shiro 2:身份验证
- shiro 第二节 身份验证
- Shiro学习之身份验证
- shiro身份验证授权入门
- shiro身份验证和授权
- Apache Shiro 身份验证
- Shiro身份验证Realm
- Shiro身份验证Test
- Shiro之身份验证
- LINUX常用命令
- [sicily] 1001. 会议安排
- 【面试总结】【远光软件】【java开发工程师】
- Windows安装TensorFlow详细教程
- shiro修改没有登录或者session失效,根据ajax返回json
- shiro身份验证
- 剑指Offer(第2版) 面试题3、面试题4,Java实现
- Git与SVN区别-6.19
- linux基础入门之rm命令
- Hession使用
- 高斯分布微分熵的推导
- Spring的AOP实现方式—ProxyFactoryBean配置方式实现源码剖析
- java集合源码解读系列
- mybatis与spring整合