最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Spring?Security實現(xiàn)接口放通的方法詳解

 更新時間:2022年05月20日 11:58:54   作者:北根娃  
在用Spring?Security項目開發(fā)中,有時候需要放通某一個接口時,我們需要在配置中把接口地址配置上,這樣做有時候顯得麻煩。本文將通過一個注解的方式快速實現(xiàn)接口放通,感興趣的可以了解一下

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

1.SpringBoot版本

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

2.實現(xiàn)思路

新建一個AnonymousAccess注解,該注解是應(yīng)用于Controller方法上的

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

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

SecurityConfig上進行策略的配置

3.實現(xiàn)過程

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方法上應(yīng)用

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

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

        Captcha captcha = loginProperties.getCaptcha();
        String uuid = "code-key-"+IdUtil.simpleUUID();
        //當(dāng)驗證碼類型為 arithmetic時且長度 >= 2 時,captcha.text()的結(jié)果有幾率為浮點型
        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實現(xiàn)接口放通的方法詳解的詳細內(nèi)容,更多關(guān)于Spring Security接口放通的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Java的Lock接口與讀寫鎖詳解

    Java的Lock接口與讀寫鎖詳解

    這篇文章主要介紹了Java的Lock接口與讀寫鎖詳解,鎖是用來控制多個線程訪問共享資源的方式,一般來說,一個鎖能夠防止多個線程同時訪問共享資源,但是有些鎖可以允許多個線程并發(fā)的訪問共享資源,比如讀寫鎖,需要的朋友可以參考下
    2023-12-12
  • 你知道Tomcat安裝之前為什么要安裝JDK

    你知道Tomcat安裝之前為什么要安裝JDK

    這篇文章主要介紹了你知道Tomcat安裝之前為什么要安裝JDK嗎?具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-03-03
  • 淺析SpringBoot自動化配置原理實現(xiàn)

    淺析SpringBoot自動化配置原理實現(xiàn)

    這篇文章主要介紹了淺析SpringBoot自動化配置原理實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-06-06
  • LinkedList學(xué)習(xí)示例模擬堆棧與隊列數(shù)據(jù)結(jié)構(gòu)

    LinkedList學(xué)習(xí)示例模擬堆棧與隊列數(shù)據(jù)結(jié)構(gòu)

    這篇文章主要介紹了LinkedList學(xué)習(xí)示例,模擬一個堆棧與隊列數(shù)據(jù)結(jié)構(gòu),大家參考使用吧
    2014-01-01
  • SpringBoot開發(fā)技巧之使用AOP記錄日志示例解析

    SpringBoot開發(fā)技巧之使用AOP記錄日志示例解析

    這篇文章主要為大家介紹了SpringBoot開發(fā)技巧之如何利用AOP記錄日志的示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步
    2021-10-10
  • Java計算球從100米高度自由落下問題

    Java計算球從100米高度自由落下問題

    這篇文章主要介紹了Java球從100米高度自由落下問題,需要的朋友可以參考下
    2017-02-02
  • java利用數(shù)組隨機抽取幸運觀眾

    java利用數(shù)組隨機抽取幸運觀眾

    這篇文章主要為大家詳細介紹了java利用數(shù)組隨機抽取幸運觀眾,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-05-05
  • 詳解feign調(diào)用session丟失解決方案

    詳解feign調(diào)用session丟失解決方案

    這篇文章主要介紹了詳解feign調(diào)用session丟失解決方案,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-02-02
  • JAVA圖形界面(GUI)之表格的示例代碼

    JAVA圖形界面(GUI)之表格的示例代碼

    這篇文章主要介紹了JAVA圖形界面(GUI)之表格的示例代碼,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-08-08
  • SpringBoot整合郵件發(fā)送的四種方法

    SpringBoot整合郵件發(fā)送的四種方法

    這篇文章主要介紹了SpringBoot整合郵件發(fā)送的四種方法,SpringBoot中集成了發(fā)送郵件的功能,本文做了進一步優(yōu)化,需要的朋友可以參考下
    2023-03-03

最新評論

闽侯县| 十堰市| 海宁市| 青浦区| 安塞县| 久治县| 横峰县| 铜鼓县| 泗水县| 山东省| 富裕县| 绥化市| 康保县| 颍上县| 于都县| 昌邑市| 合肥市| 莱西市| 上蔡县| 嘉定区| 盐池县| 临武县| 仁化县| 江山市| 长海县| 得荣县| 柳河县| 庄浪县| 河间市| 双牌县| 杭锦后旗| 乌什县| 普宁市| 盐山县| 岳池县| 华安县| 建水县| 农安县| 娄底市| 泾源县| 丰镇市|