权限分为:操作权限、业务权限、数据权限三种
1、操作权限
现阶段操作权限都是使用shiro进行控制
shiro 也是基于RBAC思想 【不懂的小朋友就去百度RBAC】
shiro 的表设计
最基本的无张表:用户表、用户角色表、角色表、角色操作权限表、操作权限表、
一般也满足使用了
复杂点有用户组表 角色组表 等等 这些RBAC都有介绍
那么 What is Apache Shiro?
Apache Shiro 是一个强大而灵活的开源安全框架,它干净利落地处理身份认证,授权,企业会话管理和加密。
这个比较牛逼、集成了 shiro 什么权限怎么控制的你就不用管了、照着他的文档使用就可以了、页面操作按钮【可以使用Tag控制】
web.xml 添加了拦截器之后、他能保证整个会话中都知道用户的权限、一直放到缓存中、你在整个流程中想要什么时候查询整个用户的角色、id都可以直接通过他的方法拿到、那么他是怎么实现的呢?
其实把他理解成一个封装工具或者一个安全框架也行、契合到项目中使用、简洁我们自己的代码、而且他这个工具还是Apache的 在安全方面还是比较值得信任的
那么他做了什么呢?
官方有以下说明:
验证用户来核实用户身份
对用户访问进行控制
判断用户是否被分配了一个确定的安全角色
判断用户是否被允许做某事
在任何环境下使用SessionAPI 即使没有 web EJB容器
在身份验证、访问控制期间、会话的生命周期、对事件做出反应
聚集一个或多个用户安全数据源、并作为一个单一复合用户“视图”
启动单点登陆【SSO】功能
为没有关联登陆的用户启用 Remember Me服务
。。。
关于实现原理:
shiro 团队 把这四个功能成为 应用程序的四大基石:身份认证、授权、会话管理、加密
shiro核心部分:
Authentication:有时也简称为“登录”,这是一个证明用户是他们所说的他们是谁的行为。
Authorization:访问控制的过程,也就是绝对“谁”去访问“什么”。
Session Management:管理用户特定的会话,即使在非 Web 或 EJB 应用程序。
Cryptography:通过使用加密算法保持数据安全同时易于使用。
看不懂?那么想想我们自己的登陆系统应该是怎样的呢?
那么这样就好理解了 登陆就像是Authentication 管理用户标识 谁是谁
那么Authorization就像是登陆系统中的查看角色权限等功能\管理谁应该访问什么资源
Session Management 就是一个管理会话的工具 将返还的ticket放置在哪里传递给用户
Cryptography 暂时就理解为加密算法
额外功能:
Web Support:Shiro 的 web 支持的 API 能够轻松地帮助保护 Web 应用程序。
Caching:缓存是 Apache Shiro 中的第一层公民,来确保安全操作快速而又高效。
Concurrency:Apache Shiro 利用它的并发特性来支持多线程应用程序。
Testing:测试支持的存在来帮助你编写单元测试和集成测试,并确保你的能够如预期的一样安全。
"Run As":一个允许用户假设为另一个用户身份(如果允许)的功能,有时候在管理脚本很有用。
"Remember Me":在会话中记住用户的身份,所以他们只需要在强制时候登录。
分解下:
先说认证 Authenticating Subjects (验证 Subjects)
系统分为了三个不同的步骤:
1、手机Subjects提交的Principals(身份)和Credentials(凭证)
2、提交Principals(身份)和Credentials(凭证)进行认证
3、如果提交成功、则允许访问、否则则重新认证或者阻止进行访问
代码如下:
Step 1 :收集 Subject 的 的 Principals( 身份)和 和 Credentials( 凭证)
UsernamePasswordToken token = new UsernamePasswordToken(username, password);
Step 2 :提交 Subject 的 的 Principals( 身份)和 和 Credentials(
Subject currentUser = SecurityUtils.getSubject();
currentUser.login(token);
Step3
成功: 应用程序继续执行、并把subject.isAuthenticated(true)
失败:返回登录?访问次数过多进行锁定?等等可以用户自己判断
那么关于注销呢 也是easy
调用方法如下:
currentUser.logout(); //removes all identifying information an invalidates their session too.
贴一下官方文档原图体会下具体流程:
功能模块定义
1、Authenticator(认证器)
shiro中默认使用了一个ModularRealmAuthenticator实例
这个实例中同样支持着一个Realm以及多个Realm的应用
通过配置也可以修改这个配置 在shiro.ini 中配置响应数据
2、AuthenticationStrategy(认证策略)
当一个应用程序配置了两个或者以上的Realm时候、就需要依靠内部组件来配置认证策略
在这个规则中使用到了AuthenticationStrategy 一个无状态组件 在身份验证尝试中会询问4次
1、在任何 Realm 被调用之前被询问;
2. 在一个单独的 Realm 的 getAuthenticationInfo 方法被调用之前立即被询问;
3. 在一个单独的 Realm 的 getAuthenticationInfo 方法被调用之后立即被询问;
4. 在所有的 Realm 被调用后询问。
然后AuthenticationStrategy 会总结合并所有的返回值 并最终确定Subject的最终ID值 (即Principals身份)
3、Realm 的验证顺序
关于Realm的验证顺序 有两种 一种是Implicit ordering(隐式排列) 另一种是 Explicit Ordering(显示排列)
在shiro.ini中配置如下:
隐式排列:
blahRealm = com.company.blah.Realm
…
fooRealm = com.company.foo.Realm
…
barRealm = com.company.another.Realm
或者
securityManager.realms = $blahRealm, $fooRealm, $barRealm
显示排列
如果你想明确地定义 Realm 的交互顺序,忽略它们是如何定义的,你可以设置 securityManager 的属性作为一
个明确的集合属性。例如,如果使用上面的定义,但你想 blahRealm 最后被请求而不是第一个:
blahRealm = com.company.blah.Realm
…
fooRealm = com.company.foo.Realm
…
barRealm = com.company.another.Realm
securityManager.realms = $fooRealm, $barRealm,$blahRealm
当你显式地配置 securityManager.realms 的属性是,只有已引用的 Realm 将会在
SecurityManager 中被配置。这意味着你能够在 INI 文件中定义 5 个 realm,但是实际上只能使用 3 个如果只有
这 3 个被引用到 realm 的属性中的话.这是和隐式 realm 顺序不同的,所有可用的隐式的 realm 都将被使用。
至此 shiro身份认证顺序逻辑结束
那么 shiro 的使用呢
maven 导入 shiro 包
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>1.1.0</version>
</dependency
另外 shiro 使用了 slf4j 作为日志记录工具
所以还要导入 slf4j 相关 jar 包
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.6.1</version>
<scope>test</scope>
</dependency>