Spring Security oauth2 cors 过滤器不起作用

Posted

技术标签:

【中文标题】Spring Security oauth2 cors 过滤器不起作用【英文标题】:Spring Security oauth2 cors filter isn't working 【发布时间】:2018-09-20 10:28:42 【问题描述】:

我的spring配置部署在Tomcat服务器上。

@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter 

    @Override
    public void addCorsMappings(CorsRegistry registry) 
            registry.addMapping("/**")
                .allowedOrigins("*")
                .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
                .allowedHeaders("Json-View","X-PINGOTHER","Content-Type","X-Requested-With","Accept","Origin",
                "Access-Control-Request-Method","Access-Control-Request-Headers","Authorization")
                .allowCredentials(false) //or true
                .maxAge(3600);
    

对于我的 api 的所有请求,服务器返回“Access-Control-Allow-Origin”标头,一切正常。但是对地址'/oauth/token'的授权请求有问题,授权被触发,但客户端无法读取答案,原因是“请求中不存在'Access-Control-Allow-Origin'标头资源……”。这可能是 Spring Framework 的配置问题。

GENERAL

Request URL: http://localhost:8080/oauth/token
Request Method: POST
Status Code: 200 
Remote Address: [::1]:8080
Referrer Policy: no-referrer-when-downgrade

RESPONSE HEADERS

Cache-Control: no-store
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Content-Type: application/json;charset=UTF-8
Date: Tue, 10 Apr 2018 17:20:34 GMT
Expires: 0
Pragma: no-cache
Pragma: no-cache
Transfer-Encoding: chunked
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-XSS-Protection: 1; mode=block

REQUEST HEADERS

Accept: application/json, text/plain, */*
Accept-Encoding: gzip, deflate, br
Accept-Language: ru,en-US;q=0.9,en;q=0.8
Connection: keep-alive
Content-Length: 85
Content-Type: application/x-www-form-urlencoded
Host: localhost:8080
Origin: http://localhost:8081
Referer: http://localhost:8081/
Save-Data: on
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (Khtml, like Gecko) Chrome/65.0.3325.181 Safari/537.36

FORM DATA

username: user
password: qwe
grant_type: password
client_id: web
client_secret: web

Chrome 控制台错误:

Failed to load http://localhost:8080/oauth/token: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8081' is therefore not allowed access.

这里有什么问题?为什么 Spring Security 不为“/oauth/token”请求返回“Access-Control-Allow-Origin”? Spring 版本 5.0.4,目前最新版本。

【问题讨论】:

你用过spring boot吗? 不,我正在构建战争并将其部署在 Tomcat 上。 那么您可以点击链接。 docs.spring.io/spring-security/site/docs/current/reference/html/… 我认为在 httpconfig 中使用 http.cors()...... 应该可以工作。 它没有帮助。工作原理类似,对地址“/oauth/token”的请求不返回“Access-Control-Allow-Origin”标头,而其他返回... 那么我建议添加一个过滤器imepelments OncePerRequestFilter 【参考方案1】:

我在 url-address /oauth/token 上找到的唯一解决方案是在 onStartup 覆盖 AbstractAnnotationConfigDispatcherServletInitializer 方法中注册自定义过滤器因此,可以在安全过滤器之前注册过滤器。

override fun onStartup(servletContext: ServletContext) 
    super.onStartup(servletContext)
    val corsFilterReg = servletContext.addFilter("CORSFilter", CORSFilter.class)
    corsFilterReg.addMappingForUrlPatterns(null, false, "/*")

和CORS过滤器

public class CORSFilter extends OncePerRequestFilter 

   protected void doFilterInternal(HttpServletRequest req, HttpServletResponse res, FilterChain chain) 
      if (path == "/oauth/token") 
        res.addHeader("Access-Control-Allow-Origin", "*");
        res.addHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
        res.addHeader("Access-Control-Max-Age", "3600");
        res.addHeader("Access-Control-Allow-Headers", "X-PINGOTHER,Content-Type,X-Requested-With,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers,Authorization");
        if (req.getMethod().equal(HttpMethod.OPTIONS.name())) 
           res.setStatus(HttpServletResponse.SC_OK);
         else 
           chain.doFilter((ServletRequest)req, (ServletResponse)res);
        
      else 
        chain.doFilter((ServletRequest)req, (ServletResponse)res);
     
   

此示例可作为 addCorsMappings 的补充或类似的标准方式,在 Spring Framework http.cors() 等的应用程序中包含 CORS。

【讨论】:

以上是关于Spring Security oauth2 cors 过滤器不起作用的主要内容,如果未能解决你的问题,请参考以下文章

Spring-Security OAuth2 设置 - 无法找到 oauth2 命名空间处理程序

Spring Security OAuth2 v5:NoSuchBeanDefinitionException:'org.springframework.security.oauth2.jwt.Jwt

针对授权标头的Spring Security OAuth2 CORS问题

OAuth2.0学习(4-1)Spring Security OAuth2.0 - 代码分析

Spring Security---Oauth2详解

如何使用spring-security,oauth2调整实体的正确登录?