Shiro(4)默认鉴权与自定义鉴权
=========默认鉴权========
过滤链中定义:
<!-- 过滤链定义 -->
<property name="filterChainDefinitions">
<value>
...
/pages/User/create.do* = perms[User:create]
...
</value>
</property>
这段配置的含义是:/pages/User/create.do*这样的请求路径,需要鉴权,且需要用户有“User:create”的权限字符串。
perms是拦截器的名字,默认实现类是:org.apache.shiro.web.filter.authz.PermissionsAuthorizationFilter
这个过滤器会得到配置中请求路径对应的权限字符串,如“User:create”,然后到realm中查找当前用户包含的权限,具体来说是调用reaml的回调函数:
/**
* 鉴权回调函数,提取当事人的角色和权限
* principals 当事人
*/
protected AuthorizationInfo doGetAuthorizationInfo(
PrincipalCollection principals) {
//用户名
String username = (String) principals.fromRealm(
getName()).iterator().next(); /*这些代码应该是动态从数据库中取出的,此处写死*/
if(username!=null&&username.equals("admin")){
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
// info.addRole("admin");//添加一个角色,不是配置意义上的添加,而是证明该用户拥有admin角色
info.addStringPermission("User:create");
info.addStringPermission("/pages/index.jsp");//添加权限
info.addStringPermission("/pages/info.jsp");//添加权限
return info;
}
return null;
}
此代码属于自定义Realm——public class CustomRealm extends AuthorizingRealm
代码中我们使用的是测试数据,直接往info里面添加角色字符串和权限字符串,我们也可以从数据库中获取,这不是本节重点。
现在关键要明白SecurityManager是从请求端得到应该有的权限字串,从Realm得到当事人具备的角色和权限字串,然后比对,比对成功说明鉴权成功,否则鉴权失败。
事实上,这种配置鉴权的方式,连自定义Realm都不需要,用户信息、角色信息、权限信息都可以配置:
[users]
# user1 = sha256-hashed-hex-encoded password, role1, role2, ...
user1 = 2bb80d537b1da3e38bd30361aa855686bde0eacd7162fef6a25fe97bf527a25b, role1, role2, ...
[roles]
# 'admin' role has all permissions, indicated by the wildcard '*'
admin = *
# The 'schwartz' role can do anything (*) with any lightsaber:
schwartz = lightsaber:*
# The 'goodguy' role is allowed to 'drive' (action) the winnebago (type) with
# license plate 'eagle5' (instance specific id)
goodguy = winnebago:drive:eagle5
这点可以参考官方文档。
===================自定义鉴权=================
往往我们的项目,特别是遗留项目都会设计几张表来存储用户信息和角色信息以及权限映射信息,所以Realm这块,一般要自定义。
而且通常的作法是直接用请求的URL作为权限字符串的,也就是不需要URL再去映射一些权限字符串,所以过滤器这块,我们可能也需要自定义。
自定义鉴权过滤器:
package javacommon.shiro; import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern; import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest; import org.apache.shiro.web.filter.authz.PermissionsAuthorizationFilter; /**
* 基于URL的权限判断过滤器<p>
* 我们自动根据URL产生所谓的权限字符串,这一项在Shiro示例中是写在配置文件里面的,默认认为权限不可动态配置<p>
* URL举例:/User/create.do?***=*** -->权限字符串:/User/create.do
* @author zhengwei lastmodified 2013年8月15日
*
*/
public class URLPermissionsFilter extends PermissionsAuthorizationFilter{
/**
*@param mappedValue 指的是在声明url时指定的权限字符串,如/User/create.do=perms[User:create].我们要动态产生这个权限字符串,所以这个配置对我们没用
*/
public boolean isAccessAllowed(ServletRequest request,
ServletResponse response, Object mappedValue) throws IOException {
return super.isAccessAllowed(request, response, buildPermissions(request));
}
/**
* 根据请求URL产生权限字符串,这里只产生,而比对的事交给Realm
* @param request
* @return
*/
protected String[] buildPermissions(ServletRequest request) {
String[] perms = new String[1];
HttpServletRequest req = (HttpServletRequest) request;
String path = req.getServletPath();
perms[0] = path;//path直接作为权限字符串
/*String regex = "/(.*?)/(.*?)\\.(.*)";
if(url.matches(regex)){
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(url);
String controller = matcher.group(1);
String action = matcher.group(2); }*/
return perms;
}
}
可以看出我们直接将请求路径作为权限字符串,过滤器会去调用Realm,所以自定义Realm中也要为用户添加同样格式的权限字符串
info.addStringPermission("/pages/index.jsp");//添加权限,admin可访问这个路径
最后再来看看全局Filter的配置:
<!-- Shiro Filter 拦截器相关配置 -->
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
...
<property name="filters">
<util:map>
<entry key="authc" value-ref="myAuthenFilter" />
<entry key="perms" value-ref="URLPermissionsFilter" />
</util:map>
</property>
<!-- 过滤链定义 -->
<property name="filterChainDefinitions">
<value>
/login.jsp = authc
/pages/* = authc,perms
/logout.do = logout
...
</value>
</property>
</bean> ...
<!-- 自定义鉴权拦截器 -->
<bean id="URLPermissionsFilter" class="javacommon.shiro.URLPermissionsFilter" />
这段配置意味着访问/pages/*都需要鉴权,而鉴权使用的是自定义的拦截器。
测试:
以admin身份登录并访问pages/info.jsp,没问题,因为它拥有这个权限。
访问pages/NB.jsp,因为这个路径没有添加到admin的权限中,所以鉴权失败,将跳转到unauthorizedUrl指定的路径。
小节:
对于客户要求程序开发者自己管理权限,而且不需要动态配置的情况,使用默认配置法,非常简单。
当需要动态管理权限,那就要自定义Realm和Filter,关键在于请求URL--》权限字符串,Realm可返回一个用户拥有的权限字符串。
这些字符串应该能比对上。
Shiro(4)默认鉴权与自定义鉴权的更多相关文章
- springboot+security整合(3)自定义鉴权
说明 springboot 版本 2.0.3源码地址:点击跳转 系列 springboot+security 整合(1) springboot+security 整合(2) springboot+se ...
- css修改input表单默认样式重置与自定义大全
链接地址: 伪元素表单控件默认样式重置与自定义大全 http://www.zhangxinxu.com/wordpress/?p=3381 Chrome 现在不支持通过伪元素修改 meter 元素样式 ...
- 1、 Shiro框架:认证,授权(验权 2. Shiro框架实现权限控制方式:
1. Shiro框架:认证,授权(验权) a) 认证逻辑:applicationCode—>通过工具类获取subject对象,调用login方法参数令牌信息->安全管理器------> ...
- cesium默认全屏按钮自定义
cesium默认全屏按钮自定义 1 隐藏默认的svg 2 修改它默认的按钮边框,背景 3 修改它点击时的样式 代码如下: .cesium-viewer-fullscreenContainer ...
- Taurus.MVC 微服务框架 入门开发教程:项目集成:4、默认安全认证与自定义安全认证。
系列目录: 本系列分为项目集成.项目部署.架构演进三个方向,后续会根据情况调整文章目录. 本系列第一篇:Taurus.MVC V3.0.3 微服务开源框架发布:让.NET 架构在大并发的演进过程更简单 ...
- Spring Cloud注册中心Eureka设置访问权限并自定义鉴权页面
原文:https://blog.csdn.net/a823007573/article/details/88971496 使用Spring Security实现鉴权 1. 导入Spring Secur ...
- 使用SpringSecurity Oauth2.0实现自定义鉴权中心
Oauth2.0是什么不在赘述,本文主要介绍如何使用SpringSecurity Oauth2.0实现自定义的用户校验 1.鉴权中心服务 首先,列举一下我们需要用到的依赖,本文采用的是数据库保存用户信 ...
- Spring Boot 鉴权之—— JWT 鉴权
第一:什么是JWT鉴权 1. JWT即JSON Web Tokens,是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准((RFC 7519),他可以用来安全的传递信息,因为传递的信息是 ...
- spring cloud jwt用户鉴权及服务鉴权
用户鉴权 客户端请求服务时,根据提交的token获取用户信息,看是否有用户信息及用户信息是否正确 服务鉴权 微服务中,一般有多个服务,服务与服务之间相互调用时,有的服务接口比较敏感,比如资金服务,不允 ...
随机推荐
- nodejs里的express自动刷新gulp-express使用【转载】
搬运自[http://blog.csdn.net/zhu_free/article/details/51476525] gulp-express实现实时刷新 本来使用gulp-connect可以创建本 ...
- pc、移动端H5网站 QQ在线客服、群链接代码【我和qq客服的那些事儿】
转载:http://blog.csdn.net/fungleo/article/details/51835368#comments 移动端H5 QQ在线客服链接代码 <a href=" ...
- 最全python面试题
Python语言特性 1 Python的函数参数传递 看两个例子: a = 1 def fun(a): a = 2 fun(a) print a # 1 a = [] def fun(a): a.ap ...
- CentOS7系统防火墙开关、状态与自启
首先需要说明的是CentOS7使用的是firewalld.service,而不是iptables.service [xf@xuexi ~]$ systemctl status firewalld.se ...
- Linux基础系列-Day1
Linux发展简史 Unix:1969年由美国电话电报公司(AT&T)贝尔实验室的两个工程师所创造的操作系统,它允许计算机同时处理多用户和程序. BSD:重要的Unix分支,1977年由加州大 ...
- URL获取并修改参数【转】
function changeURLPar(url, ref, value) { var str = ""; if (url.indexOf('?') != -1) str = u ...
- [BZOJ4698][SDOI2008]Sandy的卡片(后缀自动机)
差分之后就是求多串LCS. 对其中一个串建SAM,然后把其它串放在上面跑. 对SAM上的每个状态都用f[x]记录这个状态与当前串的最长匹配长度,res[x]是对每次的f[x]取最小值.答案就是res[ ...
- [BZOJ3456]城市规划(生成函数+多项式求逆+多项式求ln)
城市规划 时间限制:40s 空间限制:256MB 题目描述 刚刚解决完电力网络的问题, 阿狸又被领导的任务给难住了. 刚才说过, 阿狸的国家有n个城市, 现在国家需要在某些城市对之间建立一 ...
- 【DFS】【枚举】Gym - 101246G - Revolutionary Roads
给你一张有向图,问你将任意一条边变成双向后,所能得到的最大强连通分量的大小. 缩点之后,预处理can(i,j)表示i能到j. 之后枚举每一条边(u,v),再枚举其他所有点t,如果can(u,t) &a ...
- 【并查集】POJ2236-Wireless Network
[题目大意] 已知每一台电脑只能与它距离为d的电脑相连通,但是两台电脑间可以以第三台作为媒介连接.现在电脑全被损坏.每次可以进行两个操作中的一个,或是修好一台电脑,或是查询两台电脑是否连通. [思路] ...