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

过滤链中定义:

<!-- 过滤链定义 -->
<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. git reset用法

    git 删除 错误 提交的 commit 方法:         根据–soft –mixed –hard,会对working tree和index和HEAD进行重置:    git reset -- ...

  2. NOI2014 魔法森林 day1t2 SPFA

    这道题做法还是很多的,至少有人用最优性剪枝当场A掉了.我只有50分的暴力分(写丑了),SB我不会LCT,先写一下SPFA的神思路做法(说白了还是我SB),LCT以后定补.ORZ想出来的人(hq大神). ...

  3. 03 java 基础:注释 关键字 标识符 JShell

    Java 10 中已有 Jshell 工具,方便用户在其中直接输入相关 java 代码. 注释:java 中分为单行注释 //   多行注释 /*   */   文档注释 /**  */ 关键字:在 ...

  4. CentOS 7.4 上如何安装 tomcat 9

    本文将详细讲解在 CentOS 7.4 系统上如何安装tomcat 9,tomcat是没有32位和64位之分的. 创建tomcat的安装路径 首先在/usr/local/下建立一个tomcat的文件夹 ...

  5. 【剑指offer】(第 2 版)Java 题解

    [剑指offer](第 2 版)Java 题解 第一章 面试的流程 略... 第二章 面试需要的基础知识 面试题 1. 赋值运算符函数 面试题 2. 实现 Singleton 模式 Solution ...

  6. go chapter 7 - 类型

    任意类型 interface{} 遍历并判断类型 func MyPrintf(args ...interface{}) { for _, arg := range args { switch arg. ...

  7. NOIP2018 提高组题解

    Day1 T1 据说是原题积木大赛,但是考场上蠢了,只会写数据结构,于是写了一个线段树\(+\)堆\(+\)贪心,先选出最小的,然后区间修改,然后把左右两端区间的最小值丢进堆里,不停从堆中去最小值更新 ...

  8. 求高精度幂(poj1001)

    Description Problems involving the computation of exact values of very large magnitude and precision ...

  9. 【贪心】【multiset】Tinkoff Challenge - Final Round (Codeforces Round #414, rated, Div. 1 + Div. 2) C. Naming Company

    考虑两个人,先把各自的集合排个序,丢掉一半,因为比较劣的那一半一定用不到. 然后贪心地放,只有两种决策,要么把一个最优的放在开头,要么把一个最劣的放在结尾. 如果我的最优的比对方所有的都劣(或等于), ...

  10. 【模拟+递归+位运算】POJ1753-Flip Game

    由于数据规模不大,利用爆搜即可.第一次用位运算写的,但是转念一想应该用递归更加快,因为位运算没有剪枝啊(qДq ) [思路] 位运算:时间效率较低(172MS),有些辜负了位运算的初衷.首先将二维数组 ...