<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
在用Spring Security專案開發中,有時候需要放通某一個介面時,我們需要在設定中把介面地址設定上,這樣做有時候顯得麻煩,而且不夠優雅。我們能不能通過一個註解的方式,在需要放通的介面上加上該註解,這樣介面就能放通了。答案肯定是可以的啦,今天我們一起來看看實現過程吧。
本文基於的Spring Boot的版本是2.6.7
新建一個AnonymousAccess
註解,該註解是應用於Controller
方法上的
新建一個存放所有請求方式的列舉類
通過判斷Controller
方法上是否存在該註解
在SecurityConfig
上進行策略的設定
@Inherited @Documented @Target({ElementType.METHOD,ElementType.ANNOTATION_TYPE}) @Retention(RetentionPolicy.RUNTIME) public @interface AnonymousAccess { }
該類是存放所有的請求型別的,程式碼如下:
@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; } }
在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; }
通過一個SpringUtil
工具類獲取到requestMappingHandlerMapping
的Bean
,然後通過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(); }
在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; }
以上就是Spring Security實現介面放通的方法詳解的詳細內容,更多關於Spring Security介面放通的資料請關注it145.com其它相關文章!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45