Apache Shiro是一个强大易用的Java安全框架,提供了认证、授权、加密和会话管理功能,可为任何应用提供安全保障。本文主要介绍一下Shiro中的身份认证功能,如下:
本文参考自Apache Shiro的官方文档:http://shiro.apache.org/authentication.html
1. 认证主体(Authenticating Subjects)
Subject 认证主体包含两个信息:
Principals:身份。可以是用户名,邮件,手机号码等等,用来标识一个登录主体身份;
Credentials:凭证。常见有密码,数字证书等等。
在Shiro中可以在.ini文件中指定一个认证主体,也可以从数据库中取,这里使用.ini文件来写一个简单的认证主体:
[users] csdn1=12345 csdn2=12345
可以表示两个用户,账号为csdn1和csdn2,密码都是12345。至于这个文件怎么用,后面我会在实例中介绍。
验证一个主体的方法可以有效地细分为三个不同的步骤:
Step 1:收集主体提交的身份和凭证;
Step 2:提交该身份和凭证;
Step 3:如果提交成功,允许访问,否则重新尝试身份验证或阻止访问。
Step 4:退出
下面说明Shiro中的API是如何反映以上步骤的:
//Step1: Collect the Subject's principals and credentials //根据用户名和密码获得一个令牌(token) UsernamePasswordToken token = new UsernamePasswordToken(username, password); //token.setRememberMe(true); //可选用
在Step1中,我们使用UsernamePasswordToken,支持最常用的用户名/密码认证方式。这是Shiro的org.apache.shiro.authc.AuthenticationToken接口,这是由Shiro的认证系统代表提交的主体和凭证使用的基本接口的实现。username和password就是和Subject认证主体中对应的身份和凭证做验证的。当然也可以记住该用户,这个可有可无,关于RememberMe将在后续文章中介绍。
//Step2: Submit the principals and credentials //得到当前执行的用户 Subject currentUser = SecurityUtils.getSubject(); //进行认证 currentUser.login(token);
在Step2中,先通过SecurityUtils工具类获取当前执行的用户,然后进行身份认证,这个认证会参考ini文件中的Subject主体(当然了,实际中是参考数据库中的信息),在下面的示例程序中可以看的出。
//Step3: Handling Success or Failure try { currentUser.login(token); } catch ( AuthenticationException ae ) { //unexpected error? //Handel error } //No problems, continue on as expected...
在Step3中,我们要根据认证的结果来处理正确或者错误的结果,所以我们需要将currentUser.login(token)使用try/catch包起来。
//Step4: Logging out currentUser.logout();
与认证相反的是释放所有已知的确定的状态。当主体完成与应用程序交互,可以调用subject.logout()放弃所有的身份信息,subject.logout()会删除所有身份信息以及他们的会话(这里的会话指的是Shiro中的会话)。
2. 认证过程(Authentication Sequence)
上文介绍了认证主体,以及从代码的角度来分析了一下身份认证过程。下面来看一下在身份认证中,Shiro里面都干了些啥。图出自官方文档:
Step1:应用程序代码在调用Subject.login(token)方法后,传入代表最终用户的身份和凭证构造的AuthenticationToken实例token。
Step2:将Subject实例委托给应用程序的SecurityManager(Shiro的安全管理)通过调用securityManager.login(token)来开始实际的认证工作。这里开始真正的认证工作了。
Step3,4,5:然后SecurityManager就会根据具体的reaml去进行安全认证了。
这个realm到底是啥呢?realm就是一个域,Shiro就是从realm中获取验证数据的,也就是我们写在.ini文件中的东西,当然了,这个realm有很多种,如text realm、jdbc realm、jndi realm等,text realm比较简单,这一节主要总结一下jdbc realm的使用,text realm也会提到。
3. 身份认证示例
pom.xml中的包如下:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>demo.shiro</groupId> <artifactId>Shiro02</artifactId> <version>0.0.1-SNAPSHOT</version> <name>Shiro02</name> <description>Shiro02</description> <build/> <dependencies> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-core</artifactId> <version>1.2.5</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>1.7.21</version> </dependency> <dependency> <groupId>c3p0</groupId> <artifactId>c3p0</artifactId> <version>0.9.1.2</version> </dependency> <dependency> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> <version>1.2</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.38</version> </dependency> </dependencies> </project>
log4j.properties文件如下:
log4j.rootLogger=INFO, stdout log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m %n # General Apache libraries log4j.logger.org.apache=WARN # Spring log4j.logger.org.springframework=WARN # Default Shiro logging log4j.logger.org.apache.shiro=TRACE # Disable verbose logging log4j.logger.org.apache.shiro.util.ThreadContext=WARN log4j.logger.org.apache.shiro.cache.ehcache.EhCache=WARN
首先写一个shiro.ini文件,文件内容很简单,只放一个用户信息:
[users]
csdn=1234
然后开始写身份认证的java代码了,如下:
public class TextRealm { public static void main(String[] args) { // 读取配置文件,初始化SecurityManager工厂 Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini"); // 获取securityManager实例 SecurityManager securityManager = factory.getInstance(); // 把securityManager实例绑定到SecurityUtils SecurityUtils.setSecurityManager(securityManager); // 创建token令牌,用户名/密码 UsernamePasswordToken token = new UsernamePasswordToken("csdn", "123"); // 得到当前执行的用户 Subject currentUser = SecurityUtils.getSubject(); try{ // 身份认证 currentUser.login(token); System.out.println("身份认证成功!"); }catch(AuthenticationException e){ e.printStackTrace(); System.out.println("身份认证失败!"); } // 退出 currentUser.logout(); } }
运行该程序就可以根据传入的参数和realm中的数据进行匹对,完成身份认证,从而打印认证成功,如果用户名和密码填写一个错误的,则会验证失败。
接下来再分析一下jdbc realm的写法,首先新建一个JdbcRealm.ini文件,如下:
[main] #数据源选择的是c3p0 dataSource=com.mchange.v2.c3p0.ComboPooledDataSource dataSource.driverClass=com.mysql.jdbc.Driver dataSource.jdbcUrl=jdbc:mysql://localhost:3306/db_shiro dataSource.user=root dataSource.password=root #定义一个jdbc的realm,取名为jdbcRealm jdbcRealm=org.apache.shiro.realm.jdbc.JdbcRealm #jdbcRealm中有个属性是dataSource,选择我们上边定义的dataSource jdbcRealm.dataSource=$dataSource #SecurityManager中的realm选择上面定义的jdbcRealm securityManager.realms=$jdbcRealm
然后需要准备数据库的数据,我新建了一个数据库db_shiro,里面有个users表,两个字段username和password,我就放了三个数据用来测试的,如下:
然后写JdbcRealm.java代码,和上面的一样的,只不过读取的配置文件不同
public class JdbcRealm { public static void main(String[] args) { // 读取配置文件,初始化SecurityManager工厂 Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:jdbc_realm.ini"); // 获取securityManager实例 SecurityManager securityManager = factory.getInstance(); // 把securityManager实例绑定到SecurityUtils SecurityUtils.setSecurityManager(securityManager); // 得到当前执行的用户 Subject currentUser = SecurityUtils.getSubject(); // 创建token令牌,用户名/密码 UsernamePasswordToken token = new UsernamePasswordToken("倪升武2", "123"); try{ // 身份认证 currentUser.login(token); System.out.println("身份认证成功!"); }catch(AuthenticationException e){ e.printStackTrace(); System.out.println("身份认证失败!"); } // 退出 currentUser.logout(); } }
这样Shiro就会根据这个jdbc realm从数据库中获取验证数据对传入的参数进行身份验证,验证通过则打印出通过的语句,否则不予通过。这就是Shiro中简单的身份认证,下一节将总结一下Shiro中的权限认证,即授权。
相关推荐
其中shiro.loginUrl 跟 shiro.logoutUrl的前面是cas验证的地址,后面的是我们应用系统的地址,这样配置的方式是为了在访问我们的应用系统的时候,先到cas进行验证,如果验证成功了,cas将重定向到shiro.successUrl ...
将marathon-shiro-authentication-plugin.jar放在您的插件目录中,并使用--plugin_dir标志提供此目录的路径为Marathon创建配置JSON(例如,在/etc/marathon/plugin_conf.json ){ " plugins " : [ { " plugin " : ...
* Authentication:认证,表示用户的身份验证。 * Authorization:授权,表示用户的权限控制。 五、Shiro的授权机制 Shiro的授权机制基于角色的访问控制,主要包括以下几个步骤: * 用户认证:用户输入用户名和...
Authentication:身份认证/登录,验证用户是不是拥有相应的身份; Authorization:授权,即权限验证,验证某个已认证的用户是否拥有某个权限;即判断用户是否能做事情,常见的如:验证某个用户是否拥有某个角色。...
buji-pac4j项目是Shiro Web应用程序和Web服务的简单而强大的安全性库,它支持身份验证和授权,还支持CSRF保护等高级功能。 它基于Java 8,Shiro 1.7和v5 。 它在Apache 2许可下可用。 代表认证机制。 它执行登录过程...
Java Shiro 是一个强大且灵活的开源安全框架,用于身份认证、授权和会话管理等安全领域的应用开发。学习 Java Shiro 可以通过思维导图来梳理核心概念和学习路径,以下是一个简要的 Java Shiro 学习思维导图。 Java ...
Authentication 认证 - 用户身份识别,常被称为用户“登录”; Authorization 授权 - 访问控制; Cryptography 密码加密 - 保护或隐藏数据防止被偷窥; Session Management 会话管理 - 每个用户会话时效性的状态。
Apache Shiro是一个强大而灵活的开源安全框架,它能够干净利落地处理身份认证,授权,企业会话管理和加密。现在,使用Apache Shiro的人越来越多,因为它相当简单,相比比Spring Security,Shiro可能没有Spring ...
MaxKey(马克思的钥匙)用户单点登录认证系统(Sigle Sign On System),寓意是最大钥匙,是业界领先的企业级IAM身份管理和身份认证产品,支持OAuth 2.0/OpenID Connect、SAML 2.0、JWT、CAS等标准化的开放协议,提供...
CAS 是 Central Authentication Service 的缩写 —— 中央认证服务,一种独立开放指令协议,是 Yale 大学发起的一个企业级开源项目,旨在为 Web 应用系统提供一种可靠的 SSO 解决方案。 CAS 支持以下特性: CAS v1, ...
当你的页面认证采用基于Cookie的方式,例如form,windows集成认证时,如下操作后有时认证失效,Authentication (用户验证信息)丢失,需要再次登录 系统正常登录后: 第一个页面(PageA.htm):window....
Authentication(验证) Authorization(授权) Session Management(会话管理) Cryptography(加密) 身份认证(验证) 从配置文件获取用户密码 依赖 <groupId>org.apache.shiro <art
pac4j是Java的一个简单而强大的安全引擎,用于对用户进行身份验证,获取其个人资料并管理授权,以保护Web应用程序和Web服务的安全。 它提供了一套完整的。 它基于Java 8,并在Apache 2许可下可用。 它可用于大多数...
Python应用程序的安全框架项目网站:http: 什么是彩斋Yosai...主要特点通过权限级别和角色级别的访问控制启用基于角色的访问控制策略两要素身份验证,具有基于时间的一次性密码缓存和序列化的本机支持完整的事件审计线
CAS是用于Web的企业多语言单点登录解决方案,它试图成为满足身份验证和授权需求的综合平台。 CAS是一个开放且有据可查的身份验证协议。 该协议的主要实现是此处托管的具有相同名称的开源Java服务器组件,并支持大量...
支持JWT,基本身份验证,摘要身份验证...可以扩展自定义支持的身份验证方法。 [高性能到期字典匹配树](#Why Is High Performance)。 良好的扩展界面,演示和文档。 较低的确定性配置,易于扩展且不与其他框架...