91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Spring?Security怎么實現接口放通

發布時間:2022-05-20 14:32:05 來源:億速云 閱讀:638 作者:iii 欄目:開發技術

本文小編為大家詳細介紹“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怎么實現接口放通”文章已經介紹完畢,想要掌握這篇文章的知識點還需要大家自己動手實踐使用過才能領會,如果想了解更多相關內容的文章,歡迎關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

常宁市| 积石山| 黄大仙区| 阿勒泰市| 万荣县| 长乐市| 柘荣县| 怀宁县| 抚松县| 崇礼县| 衡东县| 巨鹿县| 德昌县| 理塘县| 开化县| 那曲县| 珲春市| 高青县| 南部县| 常州市| 泗水县| 碌曲县| 海安县| 信阳市| 罗甸县| 富蕴县| 沙湾县| 社会| 和田市| 阿克| 浪卡子县| 临夏县| 泾川县| 额敏县| 麦盖提县| 台湾省| 仲巴县| 射洪县| 古田县| 内丘县| 宁明县|