Shiro授权管理
一、授权
授权,也叫访问控制,即在应用中控制谁能访问哪些资源(如访问页面/编辑数据/页面操作等)。在授权中需了解的几个关键对象:主体(Subject)、资源(Resource)、权限(Permission)、角色(Role)。
二、Shiro授权概念(RBAC)
1,Subject
主体,即访问应用的用户,在Shiro中使用Subject代表该用户。用户只有授权后才允许访问相应的资源。
2,Resource
在应用中用户可以访问的任何东西,比如访问JSP 页面、查看/编辑某些数据、访问某个业务方法、打印文本等等都是资源。用户只要授权后才能访问。
3,Permission
安全策略中的原子授权单位,通过权限我们可以表示在应用中用户有没有操作某个资源的权力。即权限表示在应用中用户能不能访问某个资源,如:访问用户列表页面查看/新增/修改/删除用户数据(即很多时候都是CRUD(增查改删)式权限控制)打印文档等等。
权限代表了用户有没有操作某个资源的权利,即反映在某个资源上的操作允不允许,不反映谁去执行这个操作。所以后续还需要把权限赋予给用户,即定义哪个用户允许在某个资源上做什么操作(权限),Shiro 不会去做这件事情,而是由实现人员提供。Shiro 支持粗粒度权限(如用户模块的所有权限)和细粒度权限(操作某个用户的权限,即实例级别的)。
4,Role
角色代表了操作集合,可以理解为权限的集合,一般情况下我们会赋予用户角色而不是权限,即这样用户可以拥有一组权限,赋予权限时比较方便。典型的如:开发工程师、项目经理、技术总监、CTO等都是角色,不同的角色拥有一组不同的权限。
隐式角色:即直接通过角色来验证用户有没有操作权限,如在应用中CTO、技术总监、开发工程师可以使用打印机,假设某天不允许开发工程师使用打印机,此时需要从应用中删除相应代码;再如在应用中CTO、技术总监可以查看用户、查看权限;突然有一天不允许技术总监查看用户、查看权限了,需要在相关代码中把技术总监角色从判断逻辑中删除掉;即粒度是以角色为单位进行访问控制的,粒度较粗;如果进行修改可能造成多处代码修改。
显示角色:在程序中通过权限控制谁能访问某个资源,角色聚合一组权限集合;这样假设哪个角色不能访问某个资源,只需要从角色代表的权限集合中移除即可;无须修改多处代码;即粒度是以资源/实例为单位的;粒度较细。
三、授权流程
1、首先调用Subject.isPermitted*/hasRole*接口,其会委托给SecurityManager,而SecurityManager接着会委托给Authorizer。
2、Authorizer是真正的授权者,如果我们调用如isPermitted(“user:view”),其首先会通过PermissionResolver把字符串转换成相应的Permission实例。
3、在进行授权之前,其会调用相应的Realm获取Subject相应的角色/权限用于匹配传入的角色/权限。
4、Authorizer会判断Realm的角色/权限是否和传入的匹配,如果有多个Realm,会委托给ModularRealmAuthorizer 进行循环判断,如果匹配如isPermitted*/hasRole*会返回true,否则返回false表示授权失败。
四、SpringBoot中Shiro授权Demo
Config.java
package io.guangsoft.erp.config; import io.guangsoft.erp.realm.Realm;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.codec.Base64;
import org.apache.shiro.mgt.RememberMeManager;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.CookieRememberMeManager;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.servlet.SimpleCookie;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import java.util.LinkedHashMap;
import java.util.Map; @Configuration
public class Config { @Bean
public Realm realmManager() {
// 加密相关
HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
// 散列算法
hashedCredentialsMatcher.setHashAlgorithmName("md5");
// 散列次数
hashedCredentialsMatcher.setHashIterations(2);
Realm realm = new Realm();
realm.setCredentialsMatcher(hashedCredentialsMatcher);
return realm;
} @Bean
public RememberMeManager rememberMeManager() {
CookieRememberMeManager rememberMeManager = new CookieRememberMeManager();
//注入自定义cookie(主要是设置寿命, 默认的一年太长)
SimpleCookie simpleCookie = new SimpleCookie("rememberMe");
simpleCookie.setHttpOnly(true);
//设置RememberMe的cookie有效期为7天
simpleCookie.setMaxAge(604800);
rememberMeManager.setCookie(simpleCookie);
//手动设置对称加密秘钥,防止重启系统后系统生成新的随机秘钥,防止导致客户端cookie无效
rememberMeManager.setCipherKey(Base64.decode("6ZmI6I2j3Y+R1aSn5BOlAA=="));
return rememberMeManager;
} @Bean
public SecurityManager securityManager() {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(realmManager());
securityManager.setRememberMeManager(rememberMeManager());
return securityManager;
} //两个Bean开启Shiro的注解(如@RequiresRoles,@RequiresPermissions)
@Bean
public DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator(){
DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
advisorAutoProxyCreator.setProxyTargetClass(true);
return advisorAutoProxyCreator;
} @Bean
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
return authorizationAttributeSourceAdvisor;
} @Bean
public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(securityManager);
//当用户未登录则跳转到登录路径
shiroFilterFactoryBean.setLoginUrl("/login");
//登录成功后要跳转的链接,表单登录方式有效
shiroFilterFactoryBean.setSuccessUrl("/index");
//未授权界面,指定没有权限操作时跳转页面
shiroFilterFactoryBean.setUnauthorizedUrl("/warning");
//配置不会被过滤的链接顺序判断,过虑器链定义,从上向下顺序执行,一般将/**放在最下边
Map<String, String> filterChainDefinitionMap = new LinkedHashMap<String, String>();
//对静态资源设置匿名访问,anon:所有url都可以匿名访问
filterChainDefinitionMap.put("/assets/**", "anon");
//放开登录接口,允许进行登录操作
filterChainDefinitionMap.put("/shiro/login", "anon");
//配置退出过滤器,其中的具体的退出代码Shiro已经替我们实现了
filterChainDefinitionMap.put("/shiro/logout", "logout");
//authc:所有url都必须认证通过才可以访问
filterChainDefinitionMap.put("/**", "authc");
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
return shiroFilterFactoryBean;
} }
Realm.java
package io.guangsoft.erp.realm; import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.ByteSource; import java.util.ArrayList;
import java.util.List; public class Realm extends AuthorizingRealm { //认证
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
String userName = (String) token.getPrincipal();
System.out.println("通过username在数据库中获取用户密码并设置加密盐.");
String password = "4d521acb9b8b3b4fa082ab16b3bd363a";
String salt = "guanghe";
return new SimpleAuthenticationInfo(userName, password, ByteSource.Util.bytes(salt), this.getName());
} //授权
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
Subject subject = SecurityUtils.getSubject();
String username = (String) subject.getPrincipal();
System.out.println("通过username在数据库中获取用户角色与权限.");
// 角色
List<String> roles = new ArrayList<>();
roles.add("admin");
roles.add("user");
// 权限
List<String> permissions = new ArrayList<>();
permissions.add("admin:select");
permissions.add("admin:update");
permissions.add("user:select");
SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
simpleAuthorizationInfo.addStringPermissions(permissions);
simpleAuthorizationInfo.addRoles(roles);
return simpleAuthorizationInfo;
} }
mainController.java
package io.guangsoft.erp.controller; import org.apache.shiro.authz.annotation.Logical;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping; @Controller
public class mainController { @RequestMapping("index")
public String index() {
return "index.html";
} @RequestMapping("login")
public String login() {
return "login.html";
} @RequiresRoles(value = {"admin","user"},logical = Logical.AND)
@RequiresPermissions(value={"user:select","admin:select"},logical = Logical.OR)
@RequestMapping("select")
public String select() {
return "manage/select.html";
} @RequiresRoles("operator")
@RequestMapping("update")
public String update() {
return "manage/update.html";
} @RequiresPermissions("admin:delete")
@RequestMapping("delete")
public String delete() {
return "manage/delete.html";
} }
Shiro授权管理的更多相关文章
- 转:JAVAWEB开发之权限管理(二)——shiro入门详解以及使用方法、shiro认证与shiro授权
原文地址:JAVAWEB开发之权限管理(二)——shiro入门详解以及使用方法.shiro认证与shiro授权 以下是部分内容,具体见原文. shiro介绍 什么是shiro shiro是Apache ...
- Apache shiro集群实现 (四)shiro授权(Authentication)--访问控制
Apache shiro集群实现 (一) shiro入门介绍 Apache shiro集群实现 (二) shiro 的INI配置 Apache shiro集群实现 (三)shiro身份认证(Shiro ...
- Spring Boot Shiro 权限管理 【转】
http://blog.csdn.net/catoop/article/details/50520958 主要用于备忘 本来是打算接着写关于数据库方面,集成MyBatis的,刚好赶上朋友问到Shiro ...
- shiro权限管理的框架-入门
shiro权限管理的框架 1.权限管理的概念 基本上涉及到用户参与的系统都要进行权限管理,权限管理属于系统安全的范畴,权限管理实现对用户访问系统的控制,按照安全规则或者安全策略控制用户可以访问而且只能 ...
- frame shiro 授权及原理简述
shiro 授权模式 shiro采用的是rbac授权模式rbac,基于角色的权限管理,谁扮演什么角色,被允许做什么事情. shiro 授权流程 shiro 授权方式 1.编程式 通过写if/else授 ...
- Spring boot整合shiro权限管理
Apache Shiro功能框架: Shiro聚焦与应用程序安全领域的四大基石:认证.授权.会话管理和保密. #,认证,也叫作登录,用于验证用户是不是他自己所说的那个人: #,授权,也就是访问控制,比 ...
- (补漏)Springboot2.0 集成shiro权限管理
原文Springboot2.0 集成shiro权限管理 一.关于停止使用外键. 原本集成shiro建立用户.角色.权限表的时候使用了外键,系统自动创建其中两个关联表,用@JoinTable.看起来省事 ...
- (39.4) Spring Boot Shiro权限管理【从零开始学Spring Boot】
在读此文章之前您还可能需要先了解: (39.1) Spring Boot Shiro权限管理[从零开始学Spring Boot] http://412887952-qq-com.iteye.com/b ...
- (39.2). Spring Boot Shiro权限管理【从零开始学Spring Boot】
(本节提供源代码,在最下面可以下载) (4). 集成Shiro 进行用户授权 在看此小节前,您可能需要先看: http://412887952-qq-com.iteye.com/blog/229973 ...
随机推荐
- phpadmin dvwa sqli-labs xsser.me
下载phpadmin,安装后网站根目录 phpStudy\PHPTutorial\WWW 将下载的dvwa文件夹放到该目录下,修改config/config.inc.php文件中的mysql连接信息. ...
- div左右居中css
l_btn{ font-size: 1.2rem; width: 190px; height: 50px; border: 1px solid #fff; border-radius: 25px; c ...
- vscode添加vue格式化插件
1.安装Vetur插件 2.ctrl+,打开用户设置,找到"vetur.format.defaultFormatter.html": "none",
- thinkphp 多图片上传 单图片上传
不管是单图片上传还是多图片上传都必须要引用这两个js 下载地址 链接:http://pan.baidu.com/s/1eStkUt0 密码:asvo <script src="Publ ...
- Intellij IDEA 生成返回值对象快捷键
在编写一行JAVA语句时,有返回值的方法已经决定了返回对象的类型和泛型类型,我们只需要给这个对象起个名字就行. 如果使用快捷键生成这个返回值,我们就可以减少不必要的打字和思考,专注于过程的实现. 步骤 ...
- day17 十七、时间模块
一.时间模块 import time print(time) # <module 'time' (built-in)> import time print('暂停开始') secs = t ...
- H5 C3
为什么学习HTML5 a.因为语义化标签的出现网页结构更加清晰 b.因为多媒体的出现,让网页播放音频和视频没有了依赖 c.因为CSS3的出现,让页面变得更加炫酷和多彩 d.因为新的API的出现,使的开 ...
- js多选下拉框
1.js原生实现 1.1:引用JS文件 /*! jQuery v1.12.4 | (c) jQuery Foundation | jquery.org/license */ !function(a,b ...
- java学习笔记-集合set
equals指内容(值)相等,== 指地址相等 ===============set类 set继承自collection,但set没有新增方法,只是set里的元素不重复,下面是set常用方法 ==== ...
- 1.认识Wireshark的主窗口界面(转)
原文地址:https://www.ichunqiu.com/vm/51411/1 (1)首先了解一下这款软件主窗口界面中每个部分的功能.Wireshark主窗口界面如下图所示: 上图中每部分的含义如下 ...