Apache Shiro框架
什么是 Apache Shiro?
Apache Shiro是一个强大而灵活的开源安全框架,它干净利落地处理身份认证,授权,企业会话管理和加密。
为甚么要用Apache Shiro?
以下是你可以用 Apache Shiro所做的事情:
验证用户来核实他们的身份
对用户执行访问控制,如:
判断用户是否被分配了一个确定的安全角色
判断用户是否被允许做某事
在任何环境下使用 Session API,即使没有Web 或 EJB容器。
在身份验证,访问控制期间或在会话的生命周期,对事件作出反应。
聚集一个或多个用户安全数据的数据源,并作为一个单一的复合用户“视图”。
启用单点登录(SSO)功能。
为没有关联到登录的用户启用"Remember Me"服务
Shiro架构图
1.从外部来看Shiro,即从应用程序角度来观察如何使用Shiro完成工作。如下图:
应用程序(application code)à主体(subject)à安全管理器(securityManager)à数据域(realm)
2.从Shiro内部看Shiro的架构,如下图所示:
Shiro把Shiro开发团队称为“应用程序的四大基石”——身份验证,授权,会话管理和加密作为其目标。
Authentication:有时也简称为“登录”,这是一个证明用户是他们所说的他们是谁的行为。
Authorization:访问控制的过程,也就是绝对“谁”去访问“什么”。
Session Management:管理用户特定的会话,即使在非 Web 或 EJB 应用程序。
Cryptography:通过使用加密算法保持数据安全同时易于使用。
也提供了额外的功能来支持和加强在不同环境下所关注的方面,尤其是以下这些:
Web Support:Shiro的 web支持的 API能够轻松地帮助保护 Web 应用程序。
Caching:缓存是 Apache Shiro中的第一层公民,来确保安全操作快速而又高效。
Concurrency:Apache Shiro利用它的并发特性来支持多线程应用程序。
Testing:测试支持的存在来帮助你编写单元测试和集成测试,并确保你的能够如预期的一样安全。
"Run As":一个允许用户假设为另一个用户身份(如果允许)的功能,有时候在管理脚本很有用。
"Remember Me":在会话中记住用户的身份,所以他们只需要在强制时候登录。
Shiro配置文件
shiro.ini文件放在classpath下,shiro会自动查找。其中格式是key/value键值对配置。INI配置文件一般适用于用户少且不需要在运行时动态创建的情景下使用。
ini文件中主要配置有四大类:main,users,roles,urls
1、[main]
main主要配置shiro的一些对象,例如securityManager ,Realm,
authenticator,authcStrategy 等等,
2、[users]
[users]允许你配置一组静态的用户,包含用户名,密码,角色,一个用户
可以有多个角色,可以配置多个角色,例如:
3、[roles]
[roles]将角色和权限关联起来,格式为:角色名=权限字符串1,权限字符
串2…..,例如:
权限字符串格式进一步解释:
|---资源:操作【user:create:表示对用户资源进行create操作】【等价于:
user:create:*(对所有的用户实例进行操作)】|---资源:操作:实例
【user:create:01:表示对用户资源的01实例进行create操作】|---例子:
【user:*:01 表示对用户资源的01实例进行所有操作】
4、[urls]
这部分配置主要在web应用中,格式为:url=拦截器[参数],拦截器[参
数]……,例如:
认证实现
什么叫认证?
认证:验证用户是否合法,在 shiro 中,用户需要提供principals (身份)和credentials(凭证给shiro,从而实现对用户身份的验证。
principals
身份,即主体的标识属性,可以是任何东西,如用户名、邮箱等,唯一即可。例如:用户名/邮箱/手机号等。
credentials
凭证,即只有主体知道的安全值,如密码/数字证书等。最常见的principals和credentials组合就是用户名/密码了。
认证实现
步骤:
1.导入jar包
commons-logging-1.1.1.jar
junit-4.9.jar
log4j-1.2.17.jar
shiro-all-1.3.2.jar 核心jar包
slf4j-api-1.7.5.jar
slf4j-log4j12-1.7.5.jar
2. 从源码的示例项目quickstart中拷贝shiro.ini放到src下,并配置,或者在src类路径下创建shiro.ini,并配置文件
3.编写代码
出现错误的提示:
账户错误:
org.apache.shiro.authc.UnknownAccountException:
Realm [org.apache.shiro.realm.text.IniRealm@4c75cab9] was unable to find
account data for the submitted AuthenticationToken
[org.apache.shiro.authc.UsernamePasswordToken - vict, rememberMe=false].
密码错误:
org.apache.shiro.authc.IncorrectCredentialsException:
Submitted credentials for token [org.apache.shiro.authc.UsernamePasswordToken -
victory, rememberMe=false] did not match the expected credentials.
JDBCRealm的实现
Shiro默认使用自带的IniRealm,IniRealm从ini配置文件中读取用户的信息。大部分情况下需要从系统的数据库中读取用户信息,所以需要使用DBCRealm或自定义Realm。
需求:使用JDBCRealm提供数据源,从而实现认证
实现步骤:
1建users表(表名、字段对应上)
2添加jar包(数据库驱动、数据库连接池、beanutils等)
com.springsource.com.mchange.v2.c3p0-0.9.1.2.jar 数据源包
commons-beanutils-1.9.2.jar
commons-logging-1.1.1.jar
junit-4.9.jar
log4j-1.2.17.jar
mysql-connector-java-5.1.30.jar 数据库包
shiro-all-1.3.2.jar shiro核心包
slf4j-api-1.7.5.jar
slf4j-log4j12-1.7.5.jar
3编写shiro.ini
4编写测试代码
测试结果:
自定义Realm
实现步骤:
1建users表(表名、字段对应上)
2添加jar包(数据库驱动、数据库连接池、beanutils等)
com.springsource.com.mchange.v2.c3p0-0.9.1.2.jar 数据源包
commons-beanutils-1.9.2.jar
commons-logging-1.1.1.jar
junit-4.9.jar
log4j-1.2.17.jar
mysql-connector-java-5.1.30.jar 数据库包
shiro-all-1.3.2.jar shiro核心包
slf4j-api-1.7.5.jar
slf4j-log4j12-1.7.5.jar
3.自定义realm
4.配置shiro.ini
5.编写测试代码:
密码加密实现方案
常见的加密算法分为哪几类?
对称加密算法(加密与解密密钥相同):
非对称算法(加密密钥和解密密钥不同):
对称与非对称算法比较
散列算法:SHA-1,MD5
MD5加密、加盐与迭代‘
加盐:
使用MD5存在一个问题,相同的password生产的Hash值是相同的,如
果两个用户设置了相同的密码,那么数据库当就会存储相同的值,这样是极
不安全的。
加Salt可以一定程度上解决这一问题。所谓加Salt方法,就是加点
“佐料”。其基本想法是这样的:当用户首次提供密码时(通常是注册时),
由系统自动往这个密码里撒一些“佐料”,然后再散列。而当用户登录时,
系统为用户提供的代码撒上同样的“佐料”,然后散列,再比较散列值,来
确定密码是否正确。
加盐原理:
给原文加入随机数生成新的MD5值。
迭代:加密的次数
代码演示:
结果:
’因为是迭代一次,故红框内的结果一致。
凭证匹配器
在Realm接口的实现类AuthenticatingRealm中有credentialsMatcher属性。
意为凭证匹配器。常用来设置加密算法及迭代次数等。
自定义realm中创建SimpleAuthenticationInfo对象的参数分别是:身份,凭证,盐值,域名。
shiro.ini配置
Shiro实现授权的方式
自定义realm
测试类:基于角色
当执行subject.hasRole()方法 的时候就会触发自定义类 doGetAuthorizationInfo(PrincipalCollection principals)方法的执行。
测试类:基于权限:
同样,当执行subject.isPermitted()方法的时候会触发doGetAuthorizationInfo(PrincipalCollection principals)方法的执行。
SSM与Shiro框架整合
实现步骤
1.导入rbac项目
2.导入shiro相关jar包(shiro-all 以及shiro-spring)
shiro-all-1.3.2.jar
shiro-spring-1.3.2.jar
3.在web.xml中添加DelegatingFilterProxy配置
4.编写spring-shiro.xml
5.编写mapper接口及mapper.xml
6.编写service接口及实现类
7.编写controller
8.编写Realm
测试: