久久久久久久av_日韩在线中文_看一级毛片视频_日本精品二区_成人深夜福利视频_武道仙尊动漫在线观看

Spring?Security實現接口放通的方法詳解

在用Spring?Security項目開發中,有時候需要放通某一個接口時,我們需要在配置中把接口地址配置上,這樣做有時候顯得麻煩。本文將通過一個注解的方式快速實現接口放通,感興趣的可

在用Spring Security項目開發中,有時候需要放通某一個接口時,我們需要在配置中把接口地址配置上,這樣做有時候顯得麻煩,而且不夠優雅。我們能不能通過一個注解的方式,在需要放通的接口上加上該注解,這樣接口就能放通了。答案肯定是可以的啦,今天我們一起來看看實現過程吧。

1.SpringBoot版本

本文基于的Spring Boot的版本是2.6.7

2.實現思路

新建一個AnonymousAccess注解,該注解是應用于Controller方法上的

新建一個存放所有請求方式的枚舉類

通過判斷Controller方法上是否存在該注解

SecurityConfig上進行策略的配置

3.實現過程

3.1新建注解

@Inherited
@Documented
@Target({ElementType.METHOD,ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface AnonymousAccess {
    
}

3.2新建請求枚舉類

該類是存放所有的請求類型的,代碼如下:

@Getter
@AllArgsConstructor
public enum RequestMethodEnum {
    /**
     * 搜尋 @AnonymousGetMapping
     */
    GET("GET"),

    /**
     * 搜尋 @AnonymousPostMapping
     */
    POST("POST"),

    /**
     * 搜尋 @AnonymousPutMapping
     */
    PUT("PUT"),

    /**
     * 搜尋 @AnonymousPatchMapping
     */
    PATCH("PATCH"),

    /**
     * 搜尋 @AnonymousDeleteMapping
     */
    DELETE("DELETE"),

    /**
     * 否則就是所有 Request 接口都放行
     */
    ALL("All");

    /**
     * Request 類型
     */
    private final String type;

    public static RequestMethodEnum find(String type) {
        for (RequestMethodEnum value : RequestMethodEnum.values()) {
            if (value.getType().equals(type)) {
                return value;
            }
        }
        return ALL;
    }
}

3.3判斷Controller方法上是否存在該注解

SecurityConfig類中定義一個私有方法getAnonymousUrl,該方法主要作用是判斷controller那些方法加上了AnonymousAccess的注解

    private Map<String, Set<String>> getAnonymousUrl(Map<RequestMappingInfo, HandlerMethod> handlerMethodMap) {
        Map<String, Set<String>> anonymousUrls = new HashMap<>(8);
        Set<String> get = new HashSet<>();
        Set<String> post = new HashSet<>();
        Set<String> put = new HashSet<>();
        Set<String> patch = new HashSet<>();
        Set<String> delete = new HashSet<>();
        Set<String> all = new HashSet<>();
        for (Map.Entry<RequestMappingInfo, HandlerMethod> infoEntry : handlerMethodMap.entrySet()) {

            HandlerMethod handlerMethod = infoEntry.getValue();
            AnonymousAccess anonymousAccess = handlerMethod.getMethodAnnotation(AnonymousAccess.class);
            if (null != anonymousAccess) {
                List<RequestMethod> requestMethods = new ArrayList<>(infoEntry.getKey().getMethodsCondition().getMethods());
                RequestMethodEnum request = RequestMethodEnum.find(requestMethods.size() == 0 ? RequestMethodEnum.ALL.getType() : requestMethods.get(0).name());
                switch (Objects.requireNonNull(request)) {
                    case GET:
                        get.addAll(infoEntry.getKey().getPatternsCondition().getPatterns());
                        break;
                    case POST:
                        post.addAll(infoEntry.getKey().getPatternsCondition().getPatterns());
                        break;
                    case PUT:
                        put.addAll(infoEntry.getKey().getPatternsCondition().getPatterns());
                        break;
                    case PATCH:
                        patch.addAll(infoEntry.getKey().getPatternsCondition().getPatterns());
                        break;
                    case DELETE:
                        delete.addAll(infoEntry.getKey().getPatternsCondition().getPatterns());
                        break;
                    default:
                        all.addAll(infoEntry.getKey().getPatternsCondition().getPatterns());
                        break;
                }
            }
        }
        anonymousUrls.put(RequestMethodEnum.GET.getType(), get);
        anonymousUrls.put(RequestMethodEnum.POST.getType(), post);
        anonymousUrls.put(RequestMethodEnum.PUT.getType(), put);
        anonymousUrls.put(RequestMethodEnum.PATCH.getType(), patch);
        anonymousUrls.put(RequestMethodEnum.DELETE.getType(), delete);
        anonymousUrls.put(RequestMethodEnum.ALL.getType(), all);
        return anonymousUrls;
    }

3.4在SecurityConfig上進行策略的配置

通過一個SpringUtil工具類獲取到requestMappingHandlerMappingBean,然后通過getAnonymousUrl方法把標注AnonymousAccess接口找出來。最后,通過antMatchers細膩化到每個 Request 類型。

    @Override
    protected void configure(HttpSecurity httpSecurity) throws Exception {
        // 搜尋匿名標記 url: @AnonymousAccess
        RequestMappingHandlerMapping requestMappingHandlerMapping = (RequestMappingHandlerMapping) SpringUtil.getBean("requestMappingHandlerMapping");
        Map<RequestMappingInfo, HandlerMethod> handlerMethodMap = requestMappingHandlerMapping.getHandlerMethods();
        // 獲取匿名標記
        Map<String, Set<String>> anonymousUrls = getAnonymousUrl(handlerMethodMap);
        httpSecurity
                //禁用CSRF
                .csrf().disable()
                .authorizeRequests()
                // 自定義匿名訪問所有url放行:細膩化到每個 Request 類型
                // GET
                .antMatchers(HttpMethod.GET,anonymousUrls.get(RequestMethodEnum.GET.getType()).toArray(new String[0])).permitAll()
                // POST
                .antMatchers(HttpMethod.POST,anonymousUrls.get(RequestMethodEnum.POST.getType()).toArray(new String[0])).permitAll()
                // PUT
                .antMatchers(HttpMethod.PUT,anonymousUrls.get(RequestMethodEnum.PUT.getType()).toArray(new String[0])).permitAll()
                // PATCH
                .antMatchers(HttpMethod.PATCH,anonymousUrls.get(RequestMethodEnum.PATCH.getType()).toArray(new String[0])).permitAll()
                // DELETE
                .antMatchers(HttpMethod.DELETE,anonymousUrls.get(RequestMethodEnum.DELETE.getType()).toArray(new String[0])).permitAll()
                // 所有類型的接口都放行
                .antMatchers(anonymousUrls.get(RequestMethodEnum.ALL.getType()).toArray(new String[0])).permitAll()
                // 所有請求都需要認證
                .anyRequest().authenticated();
        
    }

3.5在Controller方法上應用

在Controller上把需要的放通的接口上加上注解,即可不需要認證就可以訪問了,是不是很方便呢。例如,驗證碼不需要認證訪問的,代碼如下:

    @ApiOperation(value = "獲取驗證碼", notes = "獲取驗證碼")
    @AnonymousAccess
    @GetMapping("/code")
    public Object getCode(){

        Captcha captcha = loginProperties.getCaptcha();
        String uuid = "code-key-"+IdUtil.simpleUUID();
        //當驗證碼類型為 arithmetic時且長度 >= 2 時,captcha.text()的結果有幾率為浮點型
        String captchaValue = captcha.text();
        if(captcha.getCharType()-1 == LoginCodeEnum.ARITHMETIC.ordinal() && captchaValue.contains(".")){
            captchaValue = captchaValue.split("\\.")[0];
        }
        // 保存
        redisUtils.set(uuid,captchaValue,loginProperties.getLoginCode().getExpiration(), TimeUnit.MINUTES);
        // 驗證碼信息
        Map<String,Object> imgResult = new HashMap<String,Object>(2){{
            put("img",captcha.toBase64());
            put("uuid",uuid);
        }};
        return imgResult;

    }

3.6效果展示

以上就是Spring Security實現接口放通的方法詳解的詳細內容,更多關于Spring Security接口放通的資料請關注html5模板網其它相關文章!

【網站聲明】本站部分內容來源于互聯網,旨在幫助大家更快的解決問題,如果有圖片或者內容侵犯了您的權益,請聯系我們刪除處理,感謝您的支持!

相關文檔推薦

這篇文章主要介紹了SpringBoot整合MyBatis筆記記錄,大家需要注意在整合mybatis之前我們需要相對應的導入相關依賴,首先需要在java的目錄和resources下創建mapper文件夾,對SpringBoot整合MyBatis的
這篇文章主要介紹了springcloud整合seata的實現方法,整合步驟通過引入spring-cloud-starter-alibaba-seata?jar包,文中結合實例代碼給大家介紹的非常詳細,需要的朋友可以參考下
SpringBoot注冊服務到Nacos上,由Nacos來做服務的管理,本文主要介紹了springboot讀取nacos配置文件的實現,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參
這篇文章主要為大家詳細介紹了Spring如何使用注解開發,文中的示例代碼講解詳細,對我們學習或工作有一定幫助,需要的可以參考一下
這篇文章主要介紹了Springboot自動裝配之注入DispatcherServlet,Springboot向外界提供web服務,底層依賴了springframework中的web模塊來實現,那么springboot在什么時機向容器注入DispatcherServlet這個核心
本文給大家介紹springboot中必須要了解的自動裝配原理,spring-boot-dependencies:核心依賴都在父工程中,這個里面主要是管理項目的資源過濾及插件,本文對springboot自動裝配原理給大家介紹
主站蜘蛛池模板: eeuss国产一区二区三区四区 | 精品中文字幕在线 | 一区二区三区国产 | 97视频网站| 国产这里只有精品 | 久久99精品久久久久久国产越南 | 欧美中文在线 | 中文字幕高清av | 伊人二区 | 久久久久久国产 | 国产91亚洲精品 | 久久精品在线免费视频 | 欧美一级艳情片免费观看 | 精品国产一区二区三区免费 | 日韩成人av在线 | 国产高清视频在线观看 | 亚洲自拍偷拍av | 国产精品一区在线观看 | 不卡av电影在线播放 | 色一级| 美国黄色一级片 | 日韩图区| 中日韩毛片 | 欧美夜夜 | 久久av一区 | 国产一区二区三区四区 | 巨大黑人极品videos精品 | 亚洲高清久久 | 在线观看亚洲精品视频 | 性国产丰满麻豆videosex | 国产日韩欧美 | 国产亚洲精品精品国产亚洲综合 | 国产一区二区三区四区 | 7799精品视频天天看 | 国产精品视频在线播放 | 欧美日韩精品免费 | 日本精品一区二区三区在线观看视频 | 成年人在线视频 | 五月婷六月丁香 | 国产一区二区 | 国产伦精品一区二区三区精品视频 |