一、Shiro简介及架构图介绍
Apache Shiro是一个强大易用的Java安全框架,提供了认证、授权、加密和会话管理等功能。
对于任何一个应用程序,Shiro都可以提供全面的安全管理服务。其不仅可以用在JavaSE环境,也可以用在JavaEE环境。
从外部来看Shiro,即从应用程序角度来观察如何使用Shiro完成工作。
如图:
![c815fc4ef0e858b4e514f3a749a2bea8.png](https://i-blog.csdnimg.cn/blog_migrate/6fdc22852e9563716225b7d4581b6508.png)
从Shiro内部看Shiro的架构
![6d87420082500b9ed1d49394d63bc5ca.png](https://i-blog.csdnimg.cn/blog_migrate/3c52be80f1d5abe30e82cd457e40907d.jpeg)
二、Shiro涉及常见名词
![52151190c3de2ce2866c4a51e4fdf37e.png](https://i-blog.csdnimg.cn/blog_migrate/638649f55fee66126b6b5a507aafd1c6.jpeg)
三、Shiro配置文件详解
shiro.ini文件放在classpath下,shiro会自动查找。其中格式是key/value
键值对配置。INI配置文件一般适用于用户少且不需要在运行时动态创建的
情景下使用。
ini文件中主要配置有四大类:main,users,roles,urls
示例:
![8b1353db91e03ae69369e096c25c4602.png](https://i-blog.csdnimg.cn/blog_migrate/d47b45069c072c7b8546a50c18f5861d.jpeg)
Shiro配置文件详解
1、[main]
main主要配置shiro的一些对象,例如securityManager ,Realm,
authenticator,authcStrategy 等等。例如:
![d1ad1bc1724c4d18b999860fe5847449.png](https://i-blog.csdnimg.cn/blog_migrate/f858a86ab2c3e2026c6b5fac58b615ba.jpeg)
2、[users]
[users]允许你配置一组静态的用户,包含用户名,密码,角色,一个用户
可以有多个角色,可以配置多个角色,例如:
![3c3a80be6128c403e9686220e54a4561.png](https://i-blog.csdnimg.cn/blog_migrate/eba40ccb98052ff522ae852772487995.png)
3、[roles]
[roles]将角色和权限关联起来,格式为:角色名=权限字符串1,权限字符
串2…..,例如:
![fc150e1b50cefa84683d0174899a89c0.png](https://i-blog.csdnimg.cn/blog_migrate/cb71e99fea9f403e0d76d089f36ebb38.png)
权限字符串格式进一步解释:
|---资源:操作【user:create:表示对用户资源进行create操作】【等价于:
user:create:*(对所有的用户实例进行操作)】
|---资源:操作:实例【user:create:01:表示对用户资源的01实例进行create操作】
|---例子:【user:*:01 表示对用户资源的01实例进行所有操作】
4、[urls]
这部分配置主要在web应用中,格式为:url=拦截器[参数],拦截器[参
数]……,例如:
![6242c225c010149389890377f1ff35b9.png](https://i-blog.csdnimg.cn/blog_migrate/aeba19eb49f16e241669c7d59479ec31.png)
四、认证实现
认证:验证用户是否合法
在 shiro 中,用户需要提供principals (身份)和credentials(凭证)给shiro,从而实现对用户身份的验证。
1.principals
身份,即主体的标识属性,可以是任何东西,如用户名、邮箱等,唯一即可。
例如:用户名/邮箱/手机号等。
2.credentials
凭证,即只有主体知道的安全值,如密码/数字证书等。
最常见的principals和credentials组合就是用户名/密码了。
3.实现步骤
导入jar包
![8eae7981c75676509ddbdce4390c09cb.png](https://i-blog.csdnimg.cn/blog_migrate/9b56656d64219a8db42506b90812d67f.png)
shiro.ini配置文件
![baec9589cd15978bf33c707a3bf168e9.png](https://i-blog.csdnimg.cn/blog_migrate/2d89b264e9a6f21c586142ee548eb59c.png)
测试:
package
![5b65aca98c8718ce64c56e2c31f12a0c.png](https://i-blog.csdnimg.cn/blog_migrate/2d7ba4b13ffbcfead7d9ac6f374ada62.jpeg)
五、JDBCRealm
Shiro默认使用自带的IniRealm,IniRealm从ini配置文件中读取用户的信息。大部分情况下需要从系统的数据库中读取用户信息,所以需要使用JDBCRealm或自定义Realm。
Shiro 内置了可以连接大量安全数据源(又名目录)的 Realm,如 LDAP、关系数据库(JDBC)、类似 INI 的文本配置资源以及属性文件等。如果缺省的 Realm 不能满足需求,还可以插入代表自定义数据源的自己的 Realm 实现。
Realm的作用:
Realm充当了Shiro与应用安全数据间的“桥梁”或者“连接器”。也就是说,当对用户执行认证(登录)和授权(访问控制)验证时,Shiro会从应用配置的Realm中查找用户及其权限信息。从这个意义上讲,Realm 实质上是一个安全相关的 DAO:它封装了数据源的连接细节,并在需要时将相关数据提供给 Shiro 。当配置 Shiro时,你必须至少指定一个 Realm ,用于认证和(或)授权。配置多个 Realm 是可以的,但是至少需要一个。
使用JDBCRealm数据库表需要注意的问题
Shiro默认使用自带的IniRealm,IniRealm从ini配置文件中读取用户信息,大部分情况下需要从数据库中读取用户信息,这时候需要使用jdbcRealm或自定义Realm,使用jdbcRealm时,需要在shiro.ini文件中配置数据源。
需求:
使用JDBCRealm提供数据源,从而实现认证
实现步骤:
建users表(表名、字段对应上)
![3042338694217343678ccce9f46a5730.png](https://i-blog.csdnimg.cn/blog_migrate/9ead3bcc8b841596f53ff6fe5554ad70.png)
添加jar包(数据库驱动、数据库连接池、beanutils等)
![3484b3d2282984ad8e32f9552bfa9063.png](https://i-blog.csdnimg.cn/blog_migrate/c3cae0dc5ff39af5237c2fcfb2d7001f.png)
编写shiro.ini
![83358e250b90a54887613bd5c6e84a53.png](https://i-blog.csdnimg.cn/blog_migrate/0893897dd96d38a275662675c85d4d30.jpeg)
编写测试代码
package
![8d8609553d739ea5743ce29234b1b3b6.png](https://i-blog.csdnimg.cn/blog_migrate/ff552fd49054138521c8190d68267bc6.jpeg)
六、自定义Realm
自定义Realm,可以注入给securityManager更加灵活的安全数据源(例如,JDBCRealm中表和字段都限定了)
通过实现Realm接口,或根据需求继承他的相应子类即可。
AuthenticatingRealm:认证使用的Realm,只包含认证的方法,认证时调用doGetAuthenticationInfo方法
AuthorizingRealm:授权使用的Realm,继承了AuthenticatingRealm, 包含认证和授权的方法,认证时调用doGetAuthenticationInfo方法,授权时调用doGetAuthorizationInfo方法
自定义Realm的实现步骤:
我们通过自定义Realm从指定的数据源中获取数据
自定义Realm,继承AuthorizingRealm类
编写shiro.ini
![ebf684adbac6a6f1393e41d3aa9f54d4.png](https://i-blog.csdnimg.cn/blog_migrate/32effdf8490b895517b1038d5f245d90.png)
自定义Realm
package
七、密码加密实现方案
几种常见加密算法比较
对称加密算法(加密与解密密钥相同)
![f6a15ad062b9d643668a5bca19763071.png](https://i-blog.csdnimg.cn/blog_migrate/f767d8abf1d8a763b5dfc0a8a6ce69ed.png)
非对称算法(加密密钥和解密密钥不同)
![99fffff4af66b8d2c69326b806aa2204.png](https://i-blog.csdnimg.cn/blog_migrate/f667eab679a57d8e73ded27ee2c8fdc6.jpeg)
对称与非对称算法比较
![e606e34282c19498e58b24ee9341f83b.png](https://i-blog.csdnimg.cn/blog_migrate/e7b8efa3d3e7f44ae3bb02ccd2954499.png)
散列算法比较
![6b539f158642099c661e843f18484245.png](https://i-blog.csdnimg.cn/blog_migrate/89d83f4be441320223b34913b77c8590.png)
MD5加密、加盐与迭代
加盐:
使用MD5存在一个问题,相同的password生产的Hash值是相同的,如果两个用户设置了相同的密码,那么数据库当就会存储相同的值,这样是极不安全的。
加Salt可以一定程度上解决这一问题。所谓加Salt方法,就是加点“佐料”。其基本想法是这样的:当用户首次提供密码时(通常是注册时),由系统自动往这个密码里撒一些“佐料”,然后再散列。而当用户登录时,系统为用户提供的代码撒上同样的“佐料”,然后散列,再比较散列值,来确定密码是否正确。
加盐原理:
给原文加入随机数生成新的MD5值。
迭代:加密的次数
代码示例:
package
![2e638d52a39dd3e972ecdcd00cd12bac.png](https://i-blog.csdnimg.cn/blog_migrate/1e7d9dec54bd2e23413fb42913f2a0bf.png)
八、凭证匹配器
凭证匹配器:
在Realm接口的实现类AuthenticatingRealm中有credentialsMatcher属性。意为凭证匹配器。常用来设置加密算法及迭代次数等。
重写认证和授权的方法
doGetAuthenticationInfo(AuthenticationToken token):认证的方法
doGetAuthorizationInfo(PrincipalCollection arg0):授权方法
在配置文件(shiro.ini)中配置自定义的realm
customRealm = com.sxt.realm.CustomRealm
securityManager.realm = $customRealm
public
配置shiro.ini文件
![71fd3a83f53399e495e0e5d93dc89898.png](https://i-blog.csdnimg.cn/blog_migrate/d774e68cfb14303e042e8c350c48300c.jpeg)
测试:
public
![8a5122bd507968280e185726ea3f36bf.png](https://i-blog.csdnimg.cn/blog_migrate/9f90f0b3d825aaa0c6246ed771594314.jpeg)
九、Shiro实现授权的方式
授权,又称作为访问控制,是对资源的访问管理的过程。即对于认证通过的用户,授予他可以访问某些资源的权限。
Shiro 支持三种方式的授权:代码触发、注解触发、标签触发
授权流程图
![4e90778ea59181b2f914c35526d6d092.png](https://i-blog.csdnimg.cn/blog_migrate/db7a0e13dfd9438570a9e97b72249731.jpeg)
代码示例:
实现授权方式
@Override
shiro.ini配置文件
![bf79fd38fd7510961e7c0e74a9d397fd.png](https://i-blog.csdnimg.cn/blog_migrate/71fa996038c5023518cf9fbc57ee0634.jpeg)
测试:
public
![d45df056e05df9f9f0f2c3912a8095a7.png](https://i-blog.csdnimg.cn/blog_migrate/9137fdd1cf9661b15bab8ecaf3f82553.jpeg)