Shiro配置跳过权限验证

Shiro配置跳过权限验证

需求

因为在开发环境,测试环境,有时候需要跳过shiro的权限验证.所以想写个简单的配置跳过shiro的权限验证.跳过权限验证的原理就是重写**@RequiresPermissions**的实现,然后在配置文件中写一个开关,最后通过Aop注入进去就大功告成.

@RequiresPermissions 处理类

在 org.apache.shiro.authz.aop.PermissionAnnotationHandler 中处理这个注解,这就是我们要覆写的类.我准备将它替换成log日志.

/**

* 检查是否有@{@link org.apache.shiro.authz.annotation。注释是

*声明,如果是,执行权限检查,看是否允许调用Subject继续

*访问。

*

* @since 0.9.0

*/

public class PermissionAnnotationHandler extends AuthorizingAnnotationHandler {

/**

*确保调用Subject具有注释指定的权限,如果没有,则抛出

* AuthorizingException表示拒绝访问。

*

*/

public void assertAuthorized(Annotation a) throws AuthorizationException {

if (!(a instanceof RequiresPermissions)) return;

RequiresPermissions rpAnnotation = (RequiresPermissions) a;

//获取注解的值

String[] perms = getAnnotationValue(a);

//获取主体

Subject subject = getSubject();

//如果只有一个需要权限

if (perms.length == 1) {

subject.checkPermission(perms[0]);

return;

}

//与的处理

if (Logical.AND.equals(rpAnnotation.logical())) {

getSubject().checkPermissions(perms);

return;

}

//或的处理

if (Logical.OR.equals(rpAnnotation.logical())) {

// Avoid processing exceptions unnecessarily - "delay" throwing the exception by calling hasRole first

boolean hasAtLeastOnePermission = false;

for (String permission : perms) if (getSubject().isPermitted(permission)) hasAtLeastOnePermission = true;

// Cause the exception if none of the role match, note that the exception message will be a bit misleading

if (!hasAtLeastOnePermission) getSubject().checkPermission(perms[0]);

}

}

}

通过 AopAllianceAnnotationsAuthorizingMethodInterceptor 加入拦截处理,通过Shiro starter 的 Conguration配置到将AuthorizationAttributeSourceAdvisor注入到 Spring Bean中.AuthorizationAttributeSourceAdvisor 实现了 StaticMethodMatcherPointcutAdvisor

破解

既然找到了实现的方法,那么注入一个自己实现类就可以跳过shiro的权限了.但是为了只在测试和开发环境破解,需要使用配置来实现

1.配置跳过shiro开关

首先在spring的配置中加入 spring.profiles.active ,同时配置 xfs.shiro.skipShiro为true.破解时根据当前运行环境和skipShiro来判断是否要跳过shiro

spring:

# 环境 dev|test|prod

profiles:

active: dev

application:

name: system

xfs:

shiro:

skipShiro: true #危险配置,跳过shiro权限控制,用于开发和测试环境调试,慎用

2.重写自己的@RequiresPermissions处理方法

在日志上打log,防止严重的生产问题

package cn.lanhi.auth.starter.interceptor;

import com.alibaba.fastjson.JSON;

import lombok.extern.slf4j.Slf4j;

import org.apache.shiro.authz.AuthorizationException;

import org.apache.shiro.authz.annotation.RequiresPermissions;

import org.apache.shiro.authz.aop.PermissionAnnotationHandler;

import java.lang.annotation.Annotation;

/**

*

*

* @author : snx cn.shennaixin@gmail.net

* @date : 2020-06-16 11:39

*/

@Slf4j

public class ShiroPermissionHandler extends PermissionAnnotationHandler {

public ShiroPermissionHandler() {

super();

log.warn("使用了自定义的PermissionHandler,如果是生产环境,使用这个类将会导致权限控制模块失效");

}

/**

* 重写权限认证方法,仅仅打印log,不做拦截处理

*

* @param a 注解

* @throws AuthorizationException 一个不可能抛出的异常

*/

@Override

public void assertAuthorized(Annotation a) throws AuthorizationException {

if (!(a instanceof RequiresPermissions)) return;

//如果是数组,打印效果不好,使用json序列化

log.warn("警告!! 跳过了权限:{}", JSON.toJSONString(getAnnotationValue(a)));

}

}

3.设置注解处理器

在 AnnotationsAuthorizingMethodInterceptor 这个抽象类的实现类中,添加了对注解的拦截器

package org.apache.shiro.spring.security.interceptor;

public class AopAllianceAnnotationsAuthorizingMethodInterceptor

extends AnnotationsAuthorizingMethodInterceptor implements MethodInterceptor {

//Shiro拦截器

public AopAllianceAnnotationsAuthorizingMethodInterceptor() {

List interceptors =

new ArrayList(5);

AnnotationResolver resolver = new SpringAnnotationResolver();

interceptors.add(new RoleAnnotationMethodInterceptor(resolver));

//注入了我们要破解的权限控制拦截器,

interceptors.add(new PermissionAnnotationMethodInterceptor(resolver));

interceptors.add(new AuthenticatedAnnotationMethodInterceptor(resolver));

interceptors.add(new UserAnnotationMethodInterceptor(resolver));

interceptors.add(new GuestAnnotationMethodInterceptor(resolver));

setMethodInterceptors(interceptors);

}

........

}

那么破解一下,自己继承一下AopAllianceAnnotationsAuthorizingMethodInterceptor,然后获取自身属性,修改值

package cn.lanhi.auth.starter.shiro;

import com.xfs.auth.starter.interceptor.ShiroPermissionHandler;

import org.apache.shiro.authz.aop.AuthorizingAnnotationMethodInterceptor;

import org.apache.shiro.authz.aop.PermissionAnnotationMethodInterceptor;

import org.apache.shiro.spring.security.interceptor.AopAllianceAnnotationsAuthorizingMethodInterceptor;

import java.util.List;

import java.util.stream.Collectors;

/**

*

shiro 权限重定义

*

* @author : snx cn.shennaixin@gmail.net

* @date : 2020-06-16 11:34

*/

public class ShiroMethodInterceptor extends AopAllianceAnnotationsAuthorizingMethodInterceptor {

public ShiroMethodInterceptor() {

super();

}

/**

* 跳过shiro RequirePremissions 注解验证

*/

public ShiroMethodInterceptor skipPremissionHandler() {

List interceptors = this.getMethodInterceptors().stream()

.filter(authorizingAnnotationMethodInterceptor ->

!(authorizingAnnotationMethodInterceptor instanceof PermissionAnnotationMethodInterceptor))

.collect(Collectors.toList());

PermissionAnnotationMethodInterceptor interceptor = new PermissionAnnotationMethodInterceptor();

//设置成自己的注解处理器!

interceptor.setHandler(new ShiroPermissionHandler());

interceptors.add(interceptor);

setMethodInterceptors(interceptors);

return this;

}

}

4.重写shiroAop

package org.apache.shiro.spring.config;

/**

* shiro AOP

* @since 1.4.0

*/

@Configuration

public class ShiroAnnotationProcessorConfiguration extends AbstractShiroAnnotationProcessorConfiguration{

@Bean

@DependsOn("lifecycleBeanPostProcessor")

protected DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {

return super.defaultAdvisorAutoProxyCreator();

}

@Bean

protected AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {

return super.authorizationAttributeSourceAdvisor(securityManager);

}

}

--------------------

--------------------

--------------------

这个 AuthorizationAttributeSourceAdvisor 提供了AOP的拦截器实现.接下来我们要覆盖他,

/**

* Create a new AuthorizationAttributeSourceAdvisor.

*/

public AuthorizationAttributeSourceAdvisor() {

setAdvice(new AopAllianceAnnotationsAuthorizingMethodInterceptor());

}

--------------------

--------------------

--------------------

5.覆盖Shiro Bean

判断了一下环境,跳过Shiro 权限验证,仅在测试和开发环境生效,且需要开启配置注意bean要设置成@primary

/**

* 跳过Shiro 权限验证,仅在测试和开发环境生效

*

* @param securityManager

* @return

*/

@Bean("authorizationAttributeSourceAdvisor")

@Primary

public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(

SecurityManager securityManager,

Environment environment,

@Value("${xfs.shiro.skipShiro:false}") boolean skipShiro) {

//获取当前运行环境

String profile = environment.getRequiredProperty("spring.profiles.active");

//创建要生成的Bean

AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor();

advisor.setSecurityManager(securityManager);

//判断是否可以跳过shiro

if (skipShiro && ("dev".equals(profile) || "test".equals(profile))) {

//运行跳过shiro权限验证方法

advisor.setAdvice(new ShiroMethodInterceptor().skipPremissionHandler());

}

return advisor;

}

到此为止,就大功告成啦.

相关文章

养森瘦瘦包怎么样 这样使用减肥效果更好
365bet网上手机投注

养森瘦瘦包怎么样 这样使用减肥效果更好

⌛ 07-23 👁️‍🗨️ 7665
3万元存银行利息多少
365bet网上手机投注

3万元存银行利息多少

⌛ 08-31 👁️‍🗨️ 6782
贵州省人民医院观山湖院区体检中心
bte365正规网站

贵州省人民医院观山湖院区体检中心

⌛ 07-29 👁️‍🗨️ 2228
LOL亚索皮肤对比:青铜玩家喜欢黑夜使者,王者大神都用它
英雄联盟怎么查看战绩 战绩查询攻略
bte365正规网站

英雄联盟怎么查看战绩 战绩查询攻略

⌛ 08-15 👁️‍🗨️ 3516
电信固定电话资费:2024年最新详解
bte365正规网站

电信固定电话资费:2024年最新详解

⌛ 07-15 👁️‍🗨️ 4347