权限认证与授权(Shrio 框架)
权限概述
- 认证: 系统提供的用于识别用户身份的功能, 通常登录功能就是认证功能; -- 让系统知道你是谁
- 授权: 系统授予用户可以访问哪些功能的证书. -- 让系统知道你能做什么!
常见的权限控制方式
URL 拦截权限控制
- 底层基于拦截器或过滤器实现
方法注解权限控制
- 我们框架会将加入注解的Action创建代理对象,由代理对象进行权限校验,如果校验通过,通过反射调用目标对象的方
法,如果校验不通过,框架会抛出权限不足异常; - 底层基于代理技术实现,为 Action 创建代理对象,由代理对象进行权限校验;
- 我们框架会将加入注解的Action创建代理对象,由代理对象进行权限校验,如果校验通过,通过反射调用目标对象的方
创建权限数据模型
- 权限表
- 角色表(权限的集合), 引入角色表,是为了方便授权
- 用户表
- 角色权限关系表
- 用户角色关系表
apache shiro 框架
- 核心功能
- 身份认证(Authentication): 简称"登录";
- 授权(Authorization):给用户分配角色或者权限资源;
- 会话管理(Session Management)
- 加密
shiro 框架认证流程
1. 使用shiro框架的URL拦截进行权限控制(基于过滤器技术实现)
1.1 导入jar包: shiro-all;
1.2 在web.xml中配置一个由spring提供的过滤器,用于整合shiro框架(这个过滤器必须放在struts2 过滤器前)
<!-- 配置spring 框架提供的用于整合shiro框架的过滤器 -->
<filter>
<filter-name>shiroFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>shiroFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
1.3 在spring配置文件中配置bean,id和上面的过滤器名称一致
<!-- 配置shiro框架的过滤器工厂对象 -->
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<!-- 注入安全管理器对象 -->
<property name="securityManager" ref="securityManager"></property>
<!-- 注入相关页面,访问URL -->
<property name="loginUrl" value="/login.jsp"/>
<property name="successUrl" value="/index.jsp"/>
<property name="unauthorizedUrl" value="/unauthorized.jsp"/>
<!-- 注入URL拦截规则 -->
<property name="filterChainDefinitions">
<value>
/css/** = anon
/js/** = anon
/images/** = anon
/validatecode.jsp* = anon
/login.jsp = anon
/userAction_login.action = anon
/page_base_staff.action = perms["staff-list"]
/* = authc
</value>
</property>
</bean>
<!-- 注册安全管理器对象 -->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<property name="realm" ref="bosRealm"></property>
</bean>
<!-- 注册 realm -->
<bean id="bosRealm" class="cn.itcast.bos.realm.BOSRealm"></bean>
1.4 修改 UserAction 中的login方法,使用shiro框架提供的方式进行认证操作
// UserAction.java
public class UserAction extends BaseAction<User>{
// 属性驱动,接收页面输入的验证码
private String checkcode;
public void setCheckcode(String checkcode){
this.checkcode = checkcode;
}
// 使用shiro框架提供的方式,进行认证操作
public String login(){
// 从Session中获取生成的验证码
String validatecode =
(String)ServletActionContext.getRequest().getSession().getAttribute("key");
//校验验证码是否正确
if(StringUtils.isNotBlank(checkcode) && checkcode.equals(validatecode)){
// 使用shiro框架提供的方式进行认证操作
Subject subject = SecurityUtils.getSubject(); // 获取当前用户对象
// 创建用户名,密码令牌对象
AuthenticationToken token = new UsernamePasswordToken(model.getUsername(),
MD5Utils.md5(model.getPassword()));
try{
subject.login(token);
}catch(Exception e){
e.printStackTrace();
return LOGIN;
}
// 登录成功,将user从当前线程中取出,放入session中
User user = (User)subject.getPrincipal();
ServletActionContext.getRequest().getSession().setAttribute("loginUser",user);
return HOME;
}else{
// 输入的验证码错误,设置提示信息,跳转到登录页面
this.addActionError("输入的验证码错误!");
return LOGIN;
}
}
}
// 自定义realm类, BOSRealm.java
public class BOSRealm extends AuthorizingRealm{
@Autowired
private IUserDao userDao;
// 认证方法
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token)
throws AuthenticationException {
UsernamePasswordToken passwordToken = (UsernamePasswordToken)token;
// 获取页面输入的用户名
String username = passwordToken.getUsername();
// 根据用户名查询数据库中的密码
User user = userDao.findUserByUsername(username);
if(user == null){
// 如果页面输入的用户名不存在
return null;
}
// 创建简单认证对象
AuthenticationInfo info = new SimpleAuthenticationInfo(user,user.getPassword(),
this.getName());
// shiro框架负责比对数据库中的密码和页面输入的密码是否一致
return info;
}
// 授权方法
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection arg0) {
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
// 为用户授权
info.addStringPermission("staff-list");
// 获取当前用户(两种方式)
User user1 = (User)SecurityUtils.getSubject().getPrincipal();
User user2 = (User)principals.getPrimaryPrincipal();
// TODO 获取需要修改为根据当前登录用户查询数据库,获取实际对应的权限
return info;
}
}
2. 使用 shiro 的方法注解方式进行权限控制(基于代理技术实现)
2.1 在spring配置文件中开启shiro注解支持
<!-- 开启shiro框架注解支持 -->
<bean id="defaultAdvisorAutoProxyCreator"
class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator">
<!-- 强制使用cglib,创建Action的代理对象 -->
<property name="proxyTargetClass" value="true"/>
</bean>
<!-- 配置shiro框架提供的切面类,用于创建代理对象 -->
<bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor"/>
2.2 在Action类中的方法上,使用shiro框架提供的注解,@RequiresPermissions("权限名称")
- 在权限不足时,会抛出如下异常:
2.3 在 struts.xml 中配置全局异常捕获,当shiro框架抛出权限不足异常时,跳转到权限不足提示页面
<!-- 配置全局结果集 -->
<global-results>
<result name="unauthorized">/unauthorized.jsp</result>
</global-results>
<!-- 配置全局异常处理 -->
<global-exception-mappings>
<exception-mapping result="unauthorized"
exception="org.apache.shiro.authz.UnauthorizedException"/>
</global-exception-mappings>
3. 使用shiro提供的页面标签方式进行权限控制
3.1 在jsp页面中,引入shiro的标签库:
<%@ taglib prefix="shiro" uri="http://shiro.apache.org/tags"%>
3.2 使用shiro的标签控制页面元素的展示
<shiro:hasPermission name="权限名称">
<!-- 页面中需要权限控制的元素 -->
<input type="button" value="test"/>
</shiro:hasPermission>
使用 ehcache 缓存权限数据
1. 导入jar包: com.springsource.net.sf.ehcache
2. 在项目中提供 ehcache 的配置文件
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="../config/ehcache.xsd">
<diskStore path="java.io.tmpdir"/>
<defaultCache
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
overflowToDisk="true"
maxElementsOnDisk="10000000"
diskPersistent="false"
diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU"
/>
</ehcache>
3. 在spring配置文件中配置缓存管理器对象,并注入给安全管理器对象
// applicationContext.xml
<!-- 注册安全管理器对象 -->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<property name="realm" ref="bosRealm"></property>
<!-- 注入缓存管理器 -->
<property name="cacheManager" ref="cacheManager"></property>
</bean>
<!-- 注入缓存管理器 -->
<bean id="cacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
<!-- 注入 ehcache 的配置文件 -->
<property name="cacheManagerConfigFile" value="classpath:ehcache.xml"></property>
</bean>
权限认证与授权(Shrio 框架)的更多相关文章
- springboot中实现权限认证的两个框架
web开发安全框架 提供认证和授权功能! 一.SpringSecurity 1.导入依赖 <dependency> <groupId>org.springframework.b ...
- shiro权限认证与授权
什么是shiro? Shiro是apache旗下一个开源框架,它将软件系统的安全认证相关的功能抽取出来,实现用户身份认证,权限授权.加密.会话管理等功能,组成了一个通用的安全认证框架. 为什么要用sh ...
- Shiro入门之一 -------- Shiro权限认证与授权
一 将Shirojar包导入web项目 二 在web.xml中配置shiro代理过滤器 注意: 该过滤器需要配置在struts2过滤器之前 <!-- 配置Shiro的代理过滤器 --> ...
- Asp.net Core 系列之--5.认证、授权与自定义权限的实现
ChuanGoing 2019-11-24 asp.net core系列已经来到了第五篇,通过之前的基础介绍,我们了解了事件订阅/发布的eventbus整个流程,初探dapper ORM实现,并且简单 ...
- 1、 Shiro框架:认证,授权(验权 2. Shiro框架实现权限控制方式:
1. Shiro框架:认证,授权(验权) a) 认证逻辑:applicationCode—>通过工具类获取subject对象,调用login方法参数令牌信息->安全管理器------> ...
- Java权限管理(授权与认证)
CRM权限管理 有兴趣的同学也可以阅读我最近分享的:Shiro框架原理分析 (PS : 这篇博客里面介绍了使用Shiro框架的方式实现权限管理) https://www.cnblogs.com/y ...
- SpringMVC整合Shiro,Shiro是一个强大易用的Java安全框架,提供了认证、授权、加密和会话管理等功能
SpringMVC整合Shiro,Shiro是一个强大易用的Java安全框架,提供了认证.授权.加密和会话管理等功能. 第一步:配置web.xml <!-- 配置Shiro过滤器,先让Shiro ...
- .Net Core权限认证基于Cookie的认证&授权.Scheme、Policy扩展
在身份认证中,如果某个Action需要权限才能访问,最开始的想法就是,哪个Action需要权限才能访问,我们写个特性标注到上面即可,[TypeFilter(typeof(CustomAuthorize ...
- shiro太复杂?快来试试这个轻量级权限认证框架!
前言 在java的世界里,有很多优秀的权限认证框架,如Apache Shiro.Spring Security 等等.这些框架背景强大,历史悠久,其生态也比较齐全. 但同时这些框架也并非十分完美,在前 ...
随机推荐
- buildroot 修改root密码后无法登录ssh解决方法
客户说想修改root密码后再登录ssh, 研究了一下,是因为ssh登录是匹配了之前的 密码生成文件,只要把之前的密码生成文件删除就可以. 过程如下: 删除 /etc/ssh/ssh_host*. rm ...
- 无需看到你的脸就能认出你——实现Beyond Frontal Faces: Improving Person Recognition Using Multiple Cues
今年年初Facebook AI Research发布了一篇名为Beyond Frontal Faces: Improving Person Recognition Using Multiple Cue ...
- DRBD(Distributed Replicated Block Device) 分布式块设备复制 进行集群高可用方案
DRBD是一个用软件实现的.无共享的.服务器之间镜像块设备内容的存储复制解决方案. 外文名 DRBD drbdadm 高级管理工具 drbdsetup 置装载进kernel的DRBD模块 drbdme ...
- Tomcat7调试运行环境搭建与源代码分析入门
1. 需要准备好下面这些工具 JDK 1.6+ Maven 2或3 TortoiseSVN 1.7+ (从1.7开始”.svn”目录集中放在一处了,不再每个目录下都放一份) Eclipse 3.5+ ...
- 扩展KMP - HDU 4333 Revolving Digits
Revolving Digits Problem's Link Mean: 给你一个字符串,你可以将该字符串的任意长度后缀截取下来然后接到最前面,让你统计所有新串中有多少种字典序小于.等于.大于原串. ...
- thinkphp 集成 twig模版引擎
下载地址:https://github.com/fucongcong/ThinkPHPLevel/archive/master.zip 控制器格式为: <?php namespace Home\ ...
- AWT是Java最早出现的图形界面,但很快就被Swing所取代
AWT是Java最早出现的图形界面,但很快就被Swing所取代. Swing才是一种真正的图形开发. AWT在不同平台所出现的界面可能有所不同:因为每个OS都有自己的UI组件库,java调用不同系统的 ...
- 在堆栈中,push为入栈操作,pop为出栈操作
LinkedList提供以下方法:(ArrayList无此类方法) addFirst(); removeFirst(); addLast(); removeLast(); 在堆栈中,push为入栈操作 ...
- ThinkPHP整合短信通知功能
1.使用的“云之讯”云通讯的接口,注册,登录. 地址:http://www.ucpaas.com/ 2. 3. 4. 5.按规范与实际需求,填写相应的信息,注意要审核通过! ------------- ...
- php 快速读取文件夹下文件列表
在读取某个文件夹下的内容的时候 以前是使用 opendir readdir结合while循环过滤 . ..当前文件夹和父文件夹来操作的. 代码如下: 然后偶然发现了有scandir函数 可以扫描文件夹 ...