=========默认鉴权========

过滤链中定义:

<!-- 过滤链定义 -->
<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)默认鉴权与自定义鉴权的更多相关文章

  1. springboot+security整合(3)自定义鉴权

    说明 springboot 版本 2.0.3源码地址:点击跳转 系列 springboot+security 整合(1) springboot+security 整合(2) springboot+se ...

  2. css修改input表单默认样式重置与自定义大全

    链接地址: 伪元素表单控件默认样式重置与自定义大全 http://www.zhangxinxu.com/wordpress/?p=3381 Chrome 现在不支持通过伪元素修改 meter 元素样式 ...

  3. 1、 Shiro框架:认证,授权(验权 2. Shiro框架实现权限控制方式:

    1. Shiro框架:认证,授权(验权) a) 认证逻辑:applicationCode—>通过工具类获取subject对象,调用login方法参数令牌信息->安全管理器------> ...

  4. cesium默认全屏按钮自定义

    cesium默认全屏按钮自定义 1  隐藏默认的svg 2  修改它默认的按钮边框,背景 3   修改它点击时的样式 代码如下: .cesium-viewer-fullscreenContainer ...

  5. Taurus.MVC 微服务框架 入门开发教程:项目集成:4、默认安全认证与自定义安全认证。

    系列目录: 本系列分为项目集成.项目部署.架构演进三个方向,后续会根据情况调整文章目录. 本系列第一篇:Taurus.MVC V3.0.3 微服务开源框架发布:让.NET 架构在大并发的演进过程更简单 ...

  6. Spring Cloud注册中心Eureka设置访问权限并自定义鉴权页面

    原文:https://blog.csdn.net/a823007573/article/details/88971496 使用Spring Security实现鉴权 1. 导入Spring Secur ...

  7. 使用SpringSecurity Oauth2.0实现自定义鉴权中心

    Oauth2.0是什么不在赘述,本文主要介绍如何使用SpringSecurity Oauth2.0实现自定义的用户校验 1.鉴权中心服务 首先,列举一下我们需要用到的依赖,本文采用的是数据库保存用户信 ...

  8. Spring Boot 鉴权之—— JWT 鉴权

    第一:什么是JWT鉴权 1. JWT即JSON Web Tokens,是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准((RFC 7519),他可以用来安全的传递信息,因为传递的信息是 ...

  9. spring cloud jwt用户鉴权及服务鉴权

    用户鉴权 客户端请求服务时,根据提交的token获取用户信息,看是否有用户信息及用户信息是否正确 服务鉴权 微服务中,一般有多个服务,服务与服务之间相互调用时,有的服务接口比较敏感,比如资金服务,不允 ...

随机推荐

  1. Linux安全之密钥登录

    我们一般使用 PuTTY 等 SSH 客户端来远程管理 Linux 服务器.但是,一般的密码方式登录,容易有密码被暴力破解的问题.所以,一般我们会将 SSH 的端口设置为默认的 22 以外的端口,或者 ...

  2. Monty Hall悖论

    Monty Hall悖论又称为蒙提·霍尔悖论.三门问题.Monty Hall是上个世纪60年代,电视游戏节目“Let's Make a Deal”的主持人,这个悖论便是以他的名字来命名的.节目的规则是 ...

  3. 修改Struts2的struts.xml配置文件位置

    默认情况下,Struts2的配置文件名称为struts.xml,且该文件放在src根目录下.如下图所示: 如果需要修改struts.xml的位置,例如把struts.xml放到struts2文件夹下, ...

  4. 转:x64与x86的改变

    http://tieba.baidu.com/p/1250470248 x64与x86的改变 硬件要求就是64位的CPU.操作系统也必须是64位的,如果在64位的CPU上安装了32位的操作系统,就算编 ...

  5. Codeforces Round #424 (Div. 2, rated, based on VK Cup Finals) Office Keys(思维)

    Office Keys time limit per test 2 seconds memory limit per test 256 megabytes input standard input o ...

  6. Linux命令之ping

    ping [选项] destination ping命令向网络主机发送ICMP回传请求 详细描述:ping使用ICMP协议强制ECHO_REQUEST(回传请求)数据报从主机或网关获取ICMP协议的E ...

  7. Flask实战第59天:首页帖子布局完成

    编辑front_index.html <div id="carousel-example-generic" class="carousel slide index- ...

  8. oracle Lower Upper length substr

    字符函数: Lower(char):将字符串装换为小写的格式 Upper(char):将字符串装换为大写的格式 length(char):返回字符串的长度 substr(char,m,n):从m开始截 ...

  9. python 定义二维数组

    1. myList = [([0] * n) for i in range(m)],n是列,m是行 >>> array=[([0]*3) for i in range(4)] > ...

  10. Compass用法

    一.什么是Compass? Compass是Sass的工具库,Compass在SASS的基础上,封装了一系列有用的模块去补充Sass的功能,类似Javascript和jQuery 二.安装 之前已经写 ...