若依-匿名注解@Anonymous解析

9 篇文章 0 订阅

1、实现绕过权限认证,可以直接访问某些接口。
这些部分可以直接在Spring Security中的配置去写,也可以像这个主角这样给添加了注解的方法或类进行放行。
  原理:在spring security设置拦截前,获取到所有添加了该注解的请求,把这些请求添加到放开拦截的配置中。
2、实现
a)新增注解(注解中内容是可以空的)

@Target({ElementType.TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Anonymous {
}

b)在spring security进行配置的时候,获取到添加了注解的类或方法

之前使用注解的时候都是在切面中,也就是当程序执行到添加了注解时程序能运行到切面里的代码。现在要在spring初始化bean后获取到全部的请求信息,在spring的生命周期 afterPropertiesSet时 通过调用

  RequestMappingHandlerMapping mapping = applicationContext.getBean(RequestMappingHandlerMapping.class);
  Map<RequestMappingInfo, HandlerMethod> map = mapping.getHandlerMethods();

可以获取到。这个逻辑封装到了工具类 PermitAllUrlProperties中。

@Configuration
public class PermitAllUrlProperties implements InitializingBean, ApplicationContextAware {
    /**
     * 正则表达式 匹配path variable
     * 如: @GetMapping(value = "/configKey/{configKey}") 进行匹配后替换为/configKey/*
     *
     */
    private static final Pattern PATTERN = Pattern.compile("\\{(.*?)\\}");

    /**
     * spring 上下文
     * 从中可以获取到各种bean
     */
    private ApplicationContext applicationContext;
    /**
     * 该集合中保存了全部标记过匿名注解的url请求
     */
    private List<String> urls = new ArrayList<>();

    public String ASTERISK = "*";

    @Override
    public void afterPropertiesSet()  {
        // 获取全部的handlerMappings
        RequestMappingHandlerMapping mapping = applicationContext.getBean(RequestMappingHandlerMapping.class);
        Map<RequestMappingInfo, HandlerMethod> map = mapping.getHandlerMethods();

        map.keySet().forEach(info->{
            HandlerMethod handlerMethod = map.get(info);
            // 获取方法上的注解 替代path variable 为 *
            Anonymous method = AnnotationUtils.findAnnotation(handlerMethod.getMethod(), Anonymous.class);
            Optional.ofNullable(method).ifPresent(anonymous->info.getPatternsCondition().getPatterns()
                    .forEach(url->urls.add(RegExUtils.replaceAll(url,PATTERN,ASTERISK))));

            // 获取类上的注解
            Anonymous controller = AnnotationUtils.findAnnotation(handlerMethod.getBeanType(), Anonymous.class);
            Optional.ofNullable(controller).ifPresent(anonymous->info.getPatternsCondition().getPatterns()
                    .forEach(url->urls.add(RegExUtils.replaceAll(url,PATTERN,ASTERISK))));

        });
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    public List<String> getUrls() {
        return urls;
    }

    public void setUrls(List<String> urls) {
        this.urls = urls;
    }
}

c)配置放开拦截

@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    ...
    @Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
    // 注解标记允许匿名访问的url
    ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry registry = httpSecurity.authorizeRequests();
    permitAllUrl.getUrls().forEach(url -> registry.antMatchers(url).permitAll());
    ... 其他配置
 }

3、 测试

目前对于没有添加匿名注解的都会拦截不允许访问。

4、总结

公共的方法很多都是通过注解、切面进行实现的;结合spring的生命周期函数,实现公共逻辑的处理。很多时候是结合了servlet和过程和spring的能力进行处理的。

代码中添加了很多spring security的配置,以及涉及到的一些工具类。framework.config.SecurityConfig是Spring Security的配置的核心,从这个类会把对security的扩展配置进去的。UserDetailsServiceImpl是重点类,实现认证过的关键类。spring security的配置和扩展很多,需要理解下原理去梳理下常见的配置内容,但是总之就是去配置和扩展框架。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
> vue-cli-service serve INFO Starting development server... ERROR Error: Cannot find module 'webpack' Require stack: - D:\Front_end\pc\node_modules\[email protected]@webpack-dev-server\lib\Server.js - D:\Front_end\pc\node_modules\_@[email protected]@@vue\cli-service\lib\commands\serve.js - D:\Front_end\pc\node_modules\_@[email protected]@@vue\cli-service\lib\Service.js - D:\Front_end\pc\node_modules\_@[email protected]@@vue\cli-service\bin\vue-cli-service.js Error: Cannot find module 'webpack' Require stack: - D:\Front_end\pc\node_modules\[email protected]@webpack-dev-server\lib\Server.js - D:\Front_end\pc\node_modules\_@[email protected]@@vue\cli-service\lib\commands\serve.js - D:\Front_end\pc\node_modules\_@[email protected]@@vue\cli-service\lib\Service.js - D:\Front_end\pc\node_modules\_@[email protected]@@vue\cli-service\bin\vue-cli-service.js at Function.Module._resolveFilename (internal/modules/cjs/loader.js:902:15) at Function.Module._load (internal/modules/cjs/loader.js:746:27) at Module.require (internal/modules/cjs/loader.js:974:19) at require (internal/modules/cjs/helpers.js:93:18) at Object.<anonymous> (D:\Front_end\pc\node_modules\[email protected]@webpack-dev-server\lib\Server.js:23:17) at Module._compile (internal/modules/cjs/loader.js:1085:14) at Object.Module._extensions..js (internal/modules/cjs/loader.js:1114:10) at Module.load (internal/modules/cjs/loader.js:950:32) at Function.Module._load (internal/modules/cjs/loader.js:790:12) at Module.require (internal/modules/cjs/loader.js:974:19) at require (internal/modules/cjs/helpers.js:93:18) at serve (D:\Front_end\pc\node_modules\_@[email protected]@@vue\cli-service\lib\commands\serve.js:38:30) at Service.run (D:\Front_end\pc\node_modules\_@[email protected]@@vue\cli-service\lib\Service.js:221:12) at Object.<anonymous> (D:\Front_end\pc\node_modules\_@[email protected]@@vue\cli-service\bin\vue-cli-service.js:36:9) at Module._compile (internal/modules/cjs/loader.js:1085:14) at Object.Module._extensions..js (internal/modules/cjs/loader.js:1114:10)
06-02

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值