shiro权限管理框架

表结构:

用户 *---* 角色 *---* 权限 ==> 建立 5 张数据表

Menu 菜单, 为了方便进行动态菜单管理 , 为不同用户定制不同系统菜单
不同用户系统菜单,可以根据用户角色 进行管理 角色 * --- * 菜单

 

权限框架:

  1. 自己写权限框架
  2. Spring Security (使用复杂, 依赖 Spring
  3. Apache Shiro (更轻量, 使用更简单, 并不完全依赖 spring,可以独立使用 )

 

Apache Shiro 体系结构(了解)

1、 Authentication 认证 ---- 用户登录,身份识别 who are you?

2、 Authorization 授权 --- 用户具有哪些权限、角色 what can you do ?

3、 Cryptography 安全数据加密

4、 Session Management 会话管理

5、 Web Integration web 系统集成

6、 Interations 集成其它应用, spring、缓存框架

重点理解authentication(登录-认证)和authorization(访问控制-授权),分别对应realm类中doGetAuthenticationInfo和doGetAuthorizationInfo方法

shiro权限管理框架

 

三大组件:

Shiro从高层次来看,Shiro的结构中有三个主要的概念:Subject、SecurityManager和Realms。下图展示了这些组件是如何交互的:

shiro权限管理框架

  • Subject:指当前正在执行程序的“用户”。Subject含义更广,因为用户通常是指人,而Subject可以指人、进程、计划任务、守护进程等。准确的说,Subject指的是“当前和软件交互的事物”。在多数场景中,你可以将Subject粗暴地认为是用户。
    Subject对象都会和一个SecurityManager对象绑定。当你和一个Subject交互时,这些交互行为会被相应的SecurityManager翻译为subject-specific的行为。
  • SecurityManager:SecurityManager是Shiro结构中的核心。它用来协调其内部的各种安全组件。然而,一旦SecurityManager和其内部的安全组件配置完成后,程序员就不再会用到它了,这时候程序员通常是与Subject的API打交道。
    我们将在后序教程中详细介绍SecurityManager。但是在此之前,要知道当我们与Subject交互时,实际上是SecurityManager在幕后帮我们完成了那些操作,从上面的图中也可以看出这一点。
  • Realms:Realms就像一个桥或连接器,将Shiro和你的应用安全数据连接起来。当我们用安全相关的数据交互时,比如用户账户的身份验证(登录)和授权管理,Shiro会从一个或多个配置好的Realms中寻找相关数据。
    从这个角度来说,Realms实际上是一个DAO:将连接到数据源的细节封装到内部,并且使Shiro可以轻易地读取相关的数据。当我们配置Shiro时,必须至少有一个Realms。SecurityManager可以由多个Realms配置,但至少有一个Realms配置。
    Shiro提供了多种Realms去连接数据源,如LDAP,数据库(JDBC),文本配置文件(如INI)。
    和其他内部组件一样,SecurityManager管理Realms如何获取安全数据和认证数据去配置Subject。

 

spring整合:

1.导包:实际all里边包括很多子功能jar,可以根据需求导,这里就一并全导了,免的找

shiro权限管理框架

2.配置web.xml

shiro权限管理框架

3.配置applicationContext-shiro.xml和applicationContext.xml

applicationContext-shiro.xml

shiro权限管理框架

其中:

anon 未认证可以访问
authc 认证后可以访问
perms 需要特定权限才能访问
roles 需要特定角色才能访问
user 需要特定用户才能访问
port 需要特定端口才能访问
reset 根据指定 HTTP 请求访问才能访问

shiro权限管理框架

applicationContext.xml

shiro权限管理框架

这里的是粗粒度权限控制。

细粒度权限控制:方法上加注解,注解可以写在service层方法上也可以写在controller层方法上。值得注意的是,当有事务管理时,shiro权限注解要写在controller层,它不能跟事务注释在同一方法上,不然权控会无效,所以要分开写

 

认证---登录是通过realm类的doGetAuthenticationInfo(认证)方法去查询数据库,匹配对应账户,返回的结果(user对象)存入authenticationinfo对象;

授权---登陆后该用户有没有访问某界面或者某界面功能,需要通过realm类中的doGetAuthorizationInfo(授权)方法去关联查询该用户下的permission和role表,并分别返回permission和role对象,将返回结果(role和permission)存入authorizationinfo对象中.--- authorizingRealm(authenticationinfo对象应该交给了SecurityManager来管理了.

登陆认证流程:

-UserAction (user对象存入subject)

  1. 获取subject对象
  2. 将前端传过来的username和password存入UsernamePasswordToken对象中
  3. 调用subject.login(token),并对其try…catch,成功跳转主页面,失败跳回登陆界面

代码部分:(加入了验证码+成功后存值到session):

shiro权限管理框架

-realm类(认证doGetAuthenticationInfo,传统的数据库交互)

  1. token转成UsernamePasswordToken
  2. 从token取出username,从数据库查询user对象
  3. 创建SimpleAuthenticationInfo对象,填入形参并返回对象(如果查到user为null,直接返回null)

代码部分:

shiro权限管理框架

这里需要解释一下simpleAuthenticationInfo这个对象的形式参数。

参数1:认证的实体类信息,可以是username或user实体对象

参数2:从数据库查询出来的密码

参数3:当前realm对象的name,调用父类的getName()方法即可

 

登录后授权流程:

-realm类(授权doGetAuthorizationInfo,传统的数据库交互,根据user查出roles和permissions加到AuthorizationInfo对象)

shiro权限管理框架

这里需要对授权解释一下:每次点击某功能都会有这样的授权过程(重复查询数据库),效率低还占用资源,使用ehcache缓存插件的技术,解决同一用户登陆情况下,点击页面功能按键,反复查询数据库的问题。

 

注意:并不是所有的操作都需要权限控制,只是一些需要权控的操作,界面等给予特定角色访问操作权利.

 

小结:


第一种: URL 级别粗粒度权限控制
配置 web.xml shiroFilter 拦截 /*
spring applicationContext*.xml 配置文件中配置同名 bean,配置
filterChainDefinitions 拦截控制规则(因为shiro自己定义了一些过滤器,就是下面的anno,authc等拦截器名),xxx.html为受保护资源。
xxx.html* = anon (未登录可以访问,即匿名访问方式)
xxx.html* =authc (必须登录才能访问 )
xxx.html* = perms[权限] (需要特定权限才能访问)
xxx.html* = roles[角色] (需要特定角色才能访问 )

/** = authc放最下面,表示不在拦截规则控制范围内的都需要鉴权(登陆)才能访问


第二种: 方法级别细粒度权限控制
spring applicationContext*.xml 配置 spring aop spring 管理 bean 对象开启
注解支持

shiro权限管理框架

  • @RequiresPermissions(权限) 需要特定权限才能访问
  • @RequiresRoles(角色) 需要特定角色才能访问
  • @RequiresAuthentication 需要认证才能访问,当前Subject必须在当前session中已经过认证
  • @RequiresGuest不需要认证
  • @RequiresUser当前Subject必须是应用的用户


第三种:通过 shiro 自定义标签,实现页面元素显示控制
<shiro:authenticated> 登录后才能访问
<shiro:hasPermission name="abc"> 需要特定权限才能访问
<shiro:hasRole name="abc"> 需要特定角色才能访问
第四种:在程序中通过代码 判断用户是否具有指定权限(不太常用 ,有代码侵入 )

shiro权限管理框架

一般权控是会用到前三种,前三种相辅相成使用,第四种不会用。还有一点需要注意,Shiro自定义标签只是把按键隐藏了,并未实现真正的权控,其实是可以在URL上构建隐藏按钮的请求格式模仿请求的,所以为了消除这一漏洞,一般第三种用的时候,第二种要去该方法上注上相应的权限要求。

 

实例:系统管理模块

四个模块:外边应该还有个界面,4个界面差不多,应该上面都会有toolbar的增删改

shiro权限管理框架

菜单管理

shiro权限管理框架

权限管理

shiro权限管理框架

这里不要有权限管理添加的页面,所有权限要提前定义好。因为这里关键字与权控直接相关的,你项目交付的时候代码都写死了,版本也交付给客户了,难道客户随意加了个新的权限,你又去改界面,改application.xml以及注解的权控??

角色管理

shiro权限管理框架

用户管理

shiro权限管理框架

 

涉及的7张表:

User表

shiro权限管理框架

Role表

shiro权限管理框架

Menu表

shiro权限管理框架

Permission表

shiro权限管理框架

因为是多对多关系,其中还有4个中间表,中间表仅含两表的id

user*-*role*-*menu->html

user*-*role*-*permission->action

都是简单的与数据库实现CRUD,通过menu表中不同.html界面地址以及permission表中不同.action动作字段来赋予权限,加上shiro的权控框架,加以权限控制