0


基于注解方式实现Spring Security忽略拦截

文章目录

1.Spring Security忽略拦截配置

关于Spring Securite的使用可以参考我写的这篇博客: 【SpringBoot框架篇】16.security整合jwt实现对前后端分离的项目进行权限认证

像这种需要忽略某个接口需要在Spring Security配置类中在代码中写死,非常的不灵活。
在这里插入图片描述

2.基于配置文件注入

2.1.添加配置

一般像一些静态资源文件需要过滤掉安全认证,例如图片,.css,.js等静态资源文件,像这种在配置文件中指定比较方便。
application.yml配置

#不需要认证的接口地址security:ignore:get:- /image/**post:all:

添加配置类注入配置的参数

@Configuration@ConfigurationProperties(prefix ="security.ignore")publicclassIgnoreSecurityPropetties{/**
     * 需要忽略的接口路径 不限制请求类型
     */privateList<String> all;/**
     * 需要忽略的Get请求类型接口路径
     */privateList<String> get;/**
     * 需要忽略的Post请求类型接口路径
     */privateList<String> post;//省略 get,set方法

2.2.修改Spring Security配置类

publicclassWebSecurityConfigextendsWebSecurityConfigurerAdapter{@ResourceprivateIgnoreSecurityPropetties ignoreSecurityPropetties;@Overrideprotectedvoidconfigure(HttpSecurity httpSecurity)throwsException{String[] all =newString[ignoreSecurityPropetties.getAll().size()];String[] get =newString[ignoreSecurityPropetties.getGet().size()];String[] post =newString[ignoreSecurityPropetties.getPost().size()];
        ignoreSecurityPropetties.getGet().toArray(get);
        ignoreSecurityPropetties.getPost().toArray(post);
        ignoreSecurityPropetties.getAll().toArray(all);if(all.length >0){
            authorizeRequest.antMatchers(all).permitAll();}if(get.length >0){
            authorizeRequest.antMatchers(HttpMethod.GET, get).permitAll();}if(post.length >0){
            authorizeRequest.antMatchers(HttpMethod.POST, post).permitAll();}// 其它接口都要认证
        authorizeRequest.anyRequest().authenticated();}}

2.3. 测试

@RestController@RequestMapping("/test")publicclassTestIgnoreController{@GetMapping("/image/{id}")publicStringimage(@PathVariableString id){return id;}}

在这里插入图片描述

如果从配置文件中删除了过滤的接口名称则访问接口会返回403
在这里插入图片描述

3.基于注解的方式过滤接口

3.1.添加忽略拦截注解

@Target({ElementType.TYPE,ElementType.METHOD})@Retention(RetentionPolicy.RUNTIME)@Documentedpublic@interfaceIgnoreWebSecurity{/**
     * 忽略接口的名称,默认使用Controller访问路径+接口的的访问路径
     * 使用场景匹配url传参的动态参数匹配 例如: /user/{id},像这种需要配置注解值为 /user/*
     */Stringvalue()default"";}

3.2.获取所有使用了@IgnoreWebSecurity注解的接口访问路径

  • 用到了2.2中的IgnoreSecurityPropetties类存放忽略的接口名称
  • 用到了2.3中的修改security配置类
@ConfigurationpublicclassInitIgnoreWebSecurityConfigimplementsApplicationContextAware{@AutowiredprivateIgnoreSecurityPropetties ignoreSecurityPropetties;@OverridepublicvoidsetApplicationContext(ApplicationContext applicationContext)throwsBeansException{Map<String,Object> beanMap = applicationContext.getBeansWithAnnotation(RestController.class);
        beanMap.forEach((k, v)->{//Controllers配置的访问路径String baseUrl ="";Class<?> controllerClass = v.getClass();RequestMapping annotation =AnnotatedElementUtils.findMergedAnnotation(controllerClass,RequestMapping.class);//如果RequestMapping注解存在,使用RequestMapping里配置的路径名称if(annotation !=null){
                baseUrl = annotation.value().length >0? annotation.value()[0]:"";}//判断访问路径前缀是否包含/if(!baseUrl.startsWith("/")){
                baseUrl ="/"+ baseUrl;}//获取所有声明的方法Method[] allMethods = controllerClass.getMethods();IgnoreWebSecurity ignoreWebSecurity;PostMapping postMapping;GetMapping getMapping;String methodType;for(Method method : allMethods){
                methodType ="";//判断方法是否使用忽略权限认证注解
                ignoreWebSecurity =AnnotatedElementUtils.findMergedAnnotation(method,IgnoreWebSecurity.class);if(ignoreWebSecurity !=null){String url ="";//当注解没配置接口名称时候使用接口名称(Controller访问路径+接口访问路径)//目前只适配了PostMapping和GetMapping注解,其它类型请自行扩展
                    postMapping =AnnotatedElementUtils.findMergedAnnotation(method,PostMapping.class);if(postMapping !=null){
                        url = postMapping.value().length >0? postMapping.value()[0]:"";
                        methodType ="post";}else{
                        getMapping =AnnotatedElementUtils.findMergedAnnotation(method,GetMapping.class);if(getMapping !=null){
                            url = getMapping.value().length >0? getMapping.value()[0]:"";
                            methodType ="get";}}//注解如果配置了接口路径则使用注解内的if(StringUtils.hasText(ignoreWebSecurity.value())){
                        url = ignoreWebSecurity.value();}if(url.trim().length()>0){
                        url =(baseUrl +"/"+ url).replaceAll("/+","/");}else{
                        url = baseUrl;}if("post".equals(methodType)){
                        ignoreSecurityPropetties.getPost().add(url);}elseif("get".equals(methodType)){
                        ignoreSecurityPropetties.getGet().add(url);}}}});System.out.println("需要忽略的get请求类型接口路径如下");for(String get: ignoreSecurityPropetties.getGet()){System.out.println(get);}System.out.println("需要忽略的post请求类型接口路径如下");for(String post: ignoreSecurityPropetties.getPost()){System.out.println(post);}}}

启动后会输出
在这里插入图片描述

忽略的接口访问路径规则以下文3.3的测试接口为例,
String baseUrl=@RestController控制器的访问路径(/test)
优先级1: String url=baseUrl+IgnoreWebSecurity(注解内值) =/test/css/*
优先级2: String url=baseUrl+接口访问路径(/login) =/test/login

3.3.测试

在需要忽略认证的接口上面添加@IgnoreWebSecurity注解

@RestController@RequestMapping("/test")publicclassTestIgnoreController{@IgnoreWebSecurity("/css/*")@GetMapping("/css/{id}")publicStringcss(@PathVariableString id){return id;}@IgnoreWebSecurity@GetMapping("/login")publicStringlogin(){return"登录成功";}}

测试用注解修饰的接口路径,可以正常访问,由此可看配置是正常。
在这里插入图片描述

标签: spring java spring boot

本文转载自: https://blog.csdn.net/ming19951224/article/details/128408651
版权归原作者 皓亮君 所有, 如有侵权,请联系我们删除。

“基于注解方式实现Spring Security忽略拦截”的评论:

还没有评论