pbootcms网站模板|日韩1区2区|织梦模板||网站源码|日韩1区2区|jquery建站特效-html5模板网

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自動裝配原理給大家介紹
主站蜘蛛池模板: 玄米影院| 武汉EPS线条_EPS装饰线条_EPS构件_湖北博欧EPS线条厂家 | 微型驱动系统解决方案-深圳市兆威机电股份有限公司 | 翅片管散热器价格_钢制暖气片报价_钢制板式散热器厂家「河北冀春暖气片有限公司」 | 粘度计,数显粘度计,指针旋转粘度计 | 蔬菜清洗机_环速洗菜机_异物去除清洗机_蔬菜清洗机_商用洗菜机 - 环速科技有限公司 | 纯水电导率测定仪-万用气体检测仪-低钠测定仪-米沃奇科技(北京)有限公司www.milwaukeeinst.cn 锂辉石检测仪器,水泥成分快速分析仪-湘潭宇科分析仪器有限公司 手术室净化装修-手术室净化工程公司-华锐手术室净化厂家 | 浙江清风侠环保设备有限公司 | 学生作文网_中小学生作文大全与写作指导 | 铝机箱_铝外壳加工_铝外壳厂家_CNC散热器加工-惠州市铂源五金制品有限公司 | 加盟店-品牌招商加盟-创业项目商机平台 | 滑板场地施工_极限运动场地设计_滑板公园建造_盐城天人极限运动场地建设有限公司 | uv机-uv灯-uvled光固化机-生产厂家-蓝盾机电 | 油罐车_加油机_加油卷盘_加油机卷盘_罐车人孔盖_各类球阀_海底阀等车用配件厂家-湖北华特专用设备有限公司 | 不锈钢搅拌罐_高速搅拌罐厂家-无锡市凡格德化工装备科技有限公司 | 外贸资讯网 - 洞悉全球贸易,把握市场先机 | 手术室净化厂家_成都实验室装修公司_无尘车间施工单位_洁净室工程建设团队-四川华锐16年行业经验 | 电解抛光加工_不锈钢电解抛光_常州安谱金属制品有限公司 | 绿萝净除甲醛|深圳除甲醛公司|测甲醛怎么收费|培训机构|电影院|办公室|车内|室内除甲醛案例|原理|方法|价格立马咨询 | 广州/东莞小字符喷码机-热转印打码机-喷码机厂家-广州瑞润科技 | 中控室大屏幕-上海亿基自动化控制系统工程有限公司 | 暴风影音| ETFE膜结构_PTFE膜结构_空间钢结构_膜结构_张拉膜_浙江萬豪空间结构集团有限公司 | 智能终端_RTU_dcm_北斗星空自动化科技 | 高压直流电源_特种变压器_变压器铁芯-希恩变压器定制厂家 | 在线浊度仪_悬浮物污泥浓度计_超声波泥位计_污泥界面仪_泥水界面仪-无锡蓝拓仪表科技有限公司 | 临时厕所租赁_玻璃钢厕所租赁_蹲式|坐式厕所出租-北京慧海通 | 大流量卧式砂磨机_强力分散机_双行星双动力混合机_同心双轴搅拌机-莱州市龙跃化工机械有限公司 | 南京和瑞包装有限公司| 防潮防水通风密闭门源头实力厂家 - 北京酷思帝克门窗 | 纳米二氧化硅,白炭黑,阴离子乳化剂-臻丽拾科技 | 细砂提取机,隔膜板框泥浆污泥压滤机,螺旋洗砂机设备,轮式洗砂机械,机制砂,圆锥颚式反击式破碎机,振动筛,滚筒筛,喂料机- 上海重睿环保设备有限公司 | 武汉高温老化房,恒温恒湿试验箱,冷热冲击试验箱-武汉安德信检测设备有限公司 | MVR蒸发器厂家-多效蒸发器-工业废水蒸发器厂家-康景辉集团官网 | 河南正规膏药生产厂家-膏药贴牌-膏药代加工-修康药业集团官网 | 筛分机|振动筛分机|气流筛分机|筛分机厂家-新乡市大汉振动机械有限公司 | 上海办公室设计_办公楼,写字楼装修_办公室装修公司-匠御设计 | 间甲酚,间甲酚厂家-山东祥东新材料| 篷房|仓储篷房|铝合金篷房|体育篷房|篷房厂家-华烨建筑科技官网 知名电动蝶阀,电动球阀,气动蝶阀,气动球阀生产厂家|价格透明-【固菲阀门官网】 | 广东高华家具-公寓床|学生宿舍双层铁床厂家【质保十年】 | TPU薄膜_TPU薄膜生产厂家_TPU热熔胶膜厂家定制_鑫亘环保科技(深圳)有限公司 |