(1)认证规则
权限管理分为用户身份认证和授权两部分。
用户身份认证:
判断用户输入的 用户名和口令是否与系统中存储的用户名口令一致。
授权:
主体经过身份认证后,需要分配权限方可访问资源。
(2)Shiro的运行流程:
1.Apache的强大灵活的开源安全框架
2.身份认证,授权,企业会话管理,安全加密,缓存管理
(3)Apache Shiro和Spring Security区别:
Apache Shiro:
简单,灵活
可脱离Spring
权限控制粒度较粗
Spring官网也是用Shiro进行 权限管理
Spring Security:
复杂,笨重
不可脱离Spring
权限控制粒度更细
(3)Shiro架构
Subject: (主体)
主体可以是任何可以与应用交互的“用户”
SecurityManager: Shiro的心脏(安全管理器)
所有的具体的交互都都是通过SecurityManager进行控制
它管理着所有Subject,且负责认证和授权,以及会话,缓存管理
Authenticator: (认证器)
如果用户觉得Shiro默认的不好,可以自定义实现;
其需要认证策略(Authentication Strategy),即什么情况下算用户认证通过了
Authrizer: (授权器)
用来决定主体是否有权限进行相应的操作;
即控制着用户能访问应用中的那些功能
Realm:(安全数据源)
可以有1个或者多个Realm,可以是JDBC实现/LDAP实现/内存实现等。由用户提供
注意:
Shiro不知道你的用户/权限存储在哪及以何种格存储,
所以我们一般在应用中都需要实现自己的Realm
Session Manager:
Shiro抽象了一个自己的Session来管理主体与应用之间交互的数据;
例如:
我们在Web环境用,刚开始是一台Web服务器,接着又上了台EJB服务器;
这时想把两台服务器的会话数据放到一个地方,这个时候就可以实现自己的分布式会话
(如把数据放到Memcached服务器)
SessionDAO:
Dao数据访问对象,负责增删改查
CacheManager:
缓存控制器,来管理如用户、角色、权限等的缓存的;
因为这些数据基本 上很少去改变,放到缓存中后可以提高访问的性能
Cryptography:
密码模块,Shiro 提高了一些常见的加密组件用于如密码加密/解密的。
(4)Shiro认证和权限管理流程:
Shiro认证:
1.指定Realms: SimpleAccountRealm
SimpleAccountRealm realm = new SimpleAccountRealm();
@Before
public void addUser() {
realm.addAccount("zhou", "123456","admin","user");
}
2.构建SecurityManager环境:
DefaultSecurityManager
defaultSecurityManager.setRealm(realm) 将realm设置到SecurityManager环境中来
3.主体(Subject)提交请求通过SecurityManager
SecurityUtils
4.SecurityManager调用Authenticator来做认证
5.Authenticator通过Realm获取认证数据
6.从数据库中获取的认证信息和主体提交过来的认真信息做对比
UsernamePasswordToken:提交认证
subject.login(token);
subject.isAuthenticated():打印认证结果
@Test
public void test() {
//1.构建SecurityManager环境
DefaultSecurityManager defaultSecurityManager = new DefaultSecurityManager();
defaultSecurityManager.setRealm(realm);//将realm设置到SecurityManager环境中来
//2.主体(Subject)提交认证请求
SecurityUtils.setSecurityManager(defaultSecurityManager);//设置SecurityManager环境
Subject subject = SecurityUtils.getSubject();
//3.提交认证
UsernamePasswordToken token = new UsernamePasswordToken("zhou","123456");
subject.login(token);
//打印认证结果
System.out.println("isAuthenticated:" + subject.isAuthenticated());
//退出登录
// subject.logout();
// System.out.println("isAuthenticated:" + subject.isAuthenticated());
//检查当前的主体是否具有参数里面的角色数据
subject.checkRoles("admin","user");
}
Shiro授权
1.构建SecurityManager环境
2.调用Subject用户主体接口,委托给Security Manager(安全管理器)
3.Security Manager委托给Authorizer(授权器)
4.Authorizer在授权之前会调用Realm(安全数据源,shiro和数据库/数据源之间的桥梁)
5.Authorizer会判断Realm的权限/角色是否和传入的匹配
如果匹配返回true,否则返回false表示授权失败
(5)Shiro加密
Shiro散列配置
1)HashedCredentialsMatcher
2) 自定义Realm中使用散列
3)盐的使用
Shiro加密过程:
1)在Realm中设置CredentialsMatcher对象
2)设置算法名称和加密次数
3) 在自定义的Realm中设置加密的CredentialsMatcher对象
4)在自定义的Realm中算出加密之后的密文
4.1)密码加上盐
4.2)返回authenticationInfo对象之前将盐设置进去
//在Realm中设置CredentialsMatcher对象
HashedCredentialsMatcher matcher = new HashedCredentialsMatcher()
//设置加密的名称
matcher.setHashAlgorithmName("md5");
//设置加密的次数
matcher.setHashIterations(1);
//在自定义的Realm中设置加密的CredentialsMatcher对象
customRealm.setCredentialsMatcher(matcher);
//算出加密之后的密文
public static void main(String[] args) {
//密码加上盐
Md5Hash md5Hash = new Md5Hash("123456","Mark");
System.out.println(md5Hash.toString());
}
//返回authenticationInfo对象之前将盐设置进去
authenticationInfo.setCredentialsSalt(ByteSource.Util.bytes("Mark"));