欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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();
        //當驗證碼類型為 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)文章

  • Springdoc替換swagger的實現(xiàn)步驟分解

    Springdoc替換swagger的實現(xiàn)步驟分解

    最近在spring看到的,spring要對api文檔動手了,有些人說swagger不好用,其實也沒那么不好用,有人說代碼還是有點侵入性,這倒是真的,我剛試了springdoc可以說還是有侵入性但是也可以沒有侵入性,這就看你對文檔有什么要求了
    2023-02-02
  • 解決SpringBoot打成jar運行后無法讀取resources里的文件問題

    解決SpringBoot打成jar運行后無法讀取resources里的文件問題

    這篇文章主要介紹了解決SpringBoot打成jar運行后無法讀取resources里的文件問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-08-08
  • 使用maven profile指定配置文件打包適用多環(huán)境的方法

    使用maven profile指定配置文件打包適用多環(huán)境的方法

    這篇文章主要介紹了使用maven profile指定配置文件打包適用多環(huán)境的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-08-08
  • java向上轉(zhuǎn)型與向下轉(zhuǎn)型詳解

    java向上轉(zhuǎn)型與向下轉(zhuǎn)型詳解

    這篇文章主要為大家詳細介紹了java向上轉(zhuǎn)型與向下轉(zhuǎn)型,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-09-09
  • 深入解析kafka 架構(gòu)原理

    深入解析kafka 架構(gòu)原理

    Kafka使用領(lǐng)域非常廣泛,在大數(shù)據(jù)時代kafka使用真香,LinkedIn、Microsoft和Netflix每天都用Kafka處理萬億級的信息。本文就讓我們一起來大白話kafka的架構(gòu)原理,感興趣的朋友一起看看吧
    2021-11-11
  • springmvc請求轉(zhuǎn)發(fā)和重定向問題(攜帶參數(shù)和不攜帶參數(shù))

    springmvc請求轉(zhuǎn)發(fā)和重定向問題(攜帶參數(shù)和不攜帶參數(shù))

    這篇文章主要介紹了springmvc請求轉(zhuǎn)發(fā)和重定向問題(攜帶參數(shù)和不攜帶參數(shù)),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-10-10
  • 初識JAVA數(shù)組

    初識JAVA數(shù)組

    java語言中,數(shù)組是一種最簡單的復(fù)合數(shù)據(jù)類型。數(shù)組是有序數(shù)據(jù)的集合,數(shù)組中的每個元素具有相同的數(shù)據(jù)類型,可以用一個統(tǒng)一的數(shù)組名和下標來唯一地確定數(shù)組中的元素。數(shù)組有一維數(shù)組和多維數(shù)組。
    2014-08-08
  • Struts2攔截器Interceptor的原理與配置實例詳解

    Struts2攔截器Interceptor的原理與配置實例詳解

    攔截器是一種AOP(面向切面編程)思想的編程方式.它提供一種機制是開發(fā)者能夠把相對獨立的代碼抽離出來,配置到Action前后執(zhí)行。下面這篇文章主要給大家介紹了關(guān)于Struts2攔截器Interceptor的原理與配置的相關(guān)資料,需要的朋友可以參考下。
    2017-11-11
  • Java泛型詳解

    Java泛型詳解

    本文給大家匯總介紹了下java中的泛型的相關(guān)資料,包括引入泛型機制的原因,泛型類,泛型方法,泛型的實現(xiàn)以及泛型的注意事項,非常的詳細,有需要的小伙伴可以參考下
    2016-03-03
  • springboot?neo4j的配置代碼

    springboot?neo4j的配置代碼

    小編最近的工作中遇到了一些知識圖譜的工作,自然就用到了圖數(shù)據(jù)庫,這一NoSQL?數(shù)據(jù)庫可以很好的展示節(jié)點之間的關(guān)聯(lián)關(guān)系,對于一些圖譜的關(guān)系操作是很好的選擇,下面來介紹下?Springboot?配置Neo4J的問題
    2021-12-12

最新評論