security antMatchers(HttpMethod method, String... antPatterns)实现特定注解无需登录认证功能

文章目录

      • 场景
      • 解决方案
      • 代码实现

场景

项目中某些接口不需要认证, 通过注解实现相对于其他的security配置会更灵活。

解决方案

  1. 按照HTTP方法的维度 获取到uri集合
  2. 使用antMatchers(HttpMethod method, String… antPatterns) 完成搜集的uri配置

antMatchers(HttpMethod method, String… antPatterns) 是 Spring Security 中用于配置 特定 HTTP 方法和 URL 模式的安全规则。

HttpMethod method 表示要匹配的 HTTP 方法(例如 GET、POST、PUT 等)。
String… antPatterns 表示要匹配的 URL 模式,可以指定多个模式。 可以设置成ur数组

下面是个例子

http
            .authorizeRequests()
                .antMatchers(HttpMethod.GET, "/public/**").permitAll()  // 允许GET请求访问/public/**路径
                .antMatchers(HttpMethod.POST, "/admin/**").hasRole("ADMIN")  // 需要ADMIN角色才能POST访问/admin/**路径
                .anyRequest().authenticated()  // 其他请求需要进行身份验证

代码实现

  1. 获取PermitAll注解修饰的uri
    /**
     * 获取被PermitAll注解修饰的url地址
     * */
    private Multimap<RequestMethod, String> getUrlsFormPermitAllAnnotation() {
        Multimap<RequestMethod, String> methodMap = HashMultimap.create();

        RequestMappingHandlerMapping requestMappingHandlerMapping = (RequestMappingHandlerMapping) applicationContext.getBean("requestMappingHandlerMapping");
        for (Map.Entry<RequestMappingInfo, HandlerMethod> entry : requestMappingHandlerMapping.getHandlerMethods().entrySet()) {
            HandlerMethod method = entry.getValue();
            if (!method.hasMethodAnnotation(PermitAll.class)) {
                continue;
            }
            if (entry.getKey().getPatternsCondition() == null) {
                continue;
            }

            Set<String> url = entry.getKey().getPatternsCondition().getPatterns();

            for (RequestMethod requestMethod : entry.getKey().getMethodsCondition().getMethods()) {
                methodMap.putAll(requestMethod, url);
            }
        }
        log.info("PermitAll注解修饰的urls {}", methodMap);

        return methodMap;
    }
  1. 将uri设置成无需认证
        Multimap<RequestMethod, String> permitAllUrlMap = getUrlsFormPermitAllAnnotation();
        // 设置具体请求的权限
        httpSecurity.authorizeRequests()
                .antMatchers(HttpMethod.GET, "/*.html", "/**/*.html", "/**/*.css", "/**/*.js").permitAll() // 静态资源无需认证
                .antMatchers("/websocket/message").permitAll() // websocket无需认证
                .antMatchers(HttpMethod.GET, permitAllUrlMap.get(RequestMethod.GET).toArray(new String[0])).permitAll()
                .antMatchers(HttpMethod.POST, permitAllUrlMap.get(RequestMethod.POST).toArray(new String[0])).permitAll()
                .antMatchers(HttpMethod.PUT, permitAllUrlMap.get(RequestMethod.PUT).toArray(new String[0])).permitAll()
                .antMatchers(HttpMethod.DELETE, permitAllUrlMap.get(RequestMethod.DELETE).toArray(new String[0])).permitAll()
                .and().authorizeRequests().anyRequest().authenticated(); // 其他请求必须认证

你可能感兴趣的:(java,security)