Spring security 4.2.3,OAUTH 2,/oauth/token 端点,CORS 不工作
Posted
技术标签:
【中文标题】Spring security 4.2.3,OAUTH 2,/oauth/token 端点,CORS 不工作【英文标题】:Spring security 4.2.3, OAUTH 2, /oauth/token endpoint, CORS not working 【发布时间】:2018-10-16 19:50:14 【问题描述】:Angular 5 应用需要登录用户。令牌请求被发送到 /oauth/token。由于 CORS,预检 OPTIONS 请求(由 Chrome 发送)失败。
我尝试按照 Spring Security 4.2 的示例以及 *** 上的各种问题和响应进行操作。
这是我的代码:
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter
@Override
protected void configure(HttpSecurity http) throws Exception
http
.cors().and()
.csrf().disable()
.anonymous().disable()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers("/signup").permitAll()
.antMatchers("/oauth/token").permitAll()
.antMatchers("/fapi/**").authenticated()
.and()
.httpBasic()
.realmName("MY_REALM");
@Bean
CorsConfigurationSource corsConfigurationSource()
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(Arrays.asList("http://example.com"));
configuration.setAllowedMethods(Arrays.asList("HEAD", "GET", "PUT", "POST", "DELETE", "PATCH", "OPTIONS"));
configuration.addAllowedHeader("*");
configuration.setAllowCredentials(true);
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
............
这是来自 Chrome 的请求
General Headers
Request URL: http://api.example.com/oauth/token
Request Method: OPTIONS
Status Code: 401
Remote Address: 127.65.43.21:80
Referrer Policy: no-referrer-when-downgrade
Request headers
Accept: */*
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9
Access-Control-Request-Headers: authorization
Access-Control-Request-Method: POST
Cache-Control: no-cache
Connection: keep-alive
Host: api.example.com
Origin: http://example.com
Pragma: no-cache
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (Khtml, like Gecko) Chrome/66.0.3359.139 Safari/537.36
回复:
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Content-Language: en
Content-Length: 1111
Content-Type: text/html;charset=utf-8
Date: Mon, 07 May 2018 03:23:15 GMT
Expires: 0
Pragma: no-cache
WWW-Authenticate: Basic realm="MY_REALM"
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-XSS-Protection: 1; mode=block
以及控制台中的错误:
Failed to load http://api.example.com/oauth/token: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://example.com' is therefore not allowed access. The response had HTTP status code 401.
【问题讨论】:
查看我对类似问题的回答***.com/a/55463965/1848555 【参考方案1】:我无法使用 Spring 提供的 CorsFilter。
这里的工作有所帮助。
Spring security, cors error when enable Oauth2
最终代码部分
@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
@WebFilter("/*")
public class SimpleCORSFilter implements Filter
public SimpleCORSFilter()
@Override
public void init(FilterConfig fc) throws ServletException
@Override
public void doFilter(ServletRequest req, ServletResponse resp,
FilterChain chain) throws IOException, ServletException
System.out.println("doFilter");
HttpServletResponse response = (HttpServletResponse) resp;
HttpServletRequest request = (HttpServletRequest) req;
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Credentials", "true");
response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE, PUT");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "Origin, origin, x-requested-with, authorization, Content-Type, Authorization, credential, X-XSRF-TOKEN");
if ("OPTIONS".equalsIgnoreCase(request.getMethod()))
response.setStatus(HttpServletResponse.SC_OK);
else
chain.doFilter(req, resp);
@Override
public void destroy()
在安全配置中:
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter
@Override
public void configure(WebSecurity web) throws Exception
web.ignoring().antMatchers(HttpMethod.OPTIONS, "/oauth/token");
@Override
protected void configure(HttpSecurity http) throws Exception
http
//.cors().and()
.csrf().disable()
.anonymous().disable()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers("/signup").permitAll()
.antMatchers("/oauth/token").permitAll()
.antMatchers("/fapi/**").authenticated()
.and()
.httpBasic()
.realmName("MY_REALM");
/*
@Bean
CorsConfigurationSource corsConfigurationSource()
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(Arrays.asList("http://example.com"));
configuration.setAllowedMethods(Arrays.asList("HEAD", "GET", "PUT", "POST", "DELETE", "PATCH", "OPTIONS"));
configuration.addAllowedHeader("*");
configuration.setAllowCredentials(true);
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
*/
............
我仍在等待一个可以与 Spring Security 的 CorsFilter 一起使用的示例。
【讨论】:
/oauth/token
使用基本身份验证进行保护。客户端 ID 和机密用于此目的。为什么要删除该身份验证?这破坏了 OAuth2 提供的安全性。【参考方案2】:
编写一个自定义的 cors 过滤器,而不是您所做的,如下所示
@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class SimpleCorsFilter implements Filter
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException
HttpServletResponse response = (HttpServletResponse) res;
HttpServletRequest request = (HttpServletRequest) req;
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE, PUT");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "Origin, x-requested-with, authorization, Content-Type, Authorization, credential, X-XSRF-TOKEN);
if ("OPTIONS".equalsIgnoreCase(request.getMethod()))
response.setStatus(HttpServletResponse.SC_OK);
else
chain.doFilter(req, res);
@Override
public void init(FilterConfig filterConfig)
@Override
public void destroy()
并将您的 configure(HttpSecurity http)
覆盖修改为
@Override
protected void configure(HttpSecurity http) throws Exception
http
.and()
.csrf().disable()
.anonymous().disable()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers("/signup").permitAll()
.antMatchers("/oauth/token").permitAll()
.antMatchers("/fapi/**").authenticated()
.and()
.httpBasic()
.realmName("MY_REALM");
【讨论】:
努力工作。这个做了***.com/questions/44625488/…以上是关于Spring security 4.2.3,OAUTH 2,/oauth/token 端点,CORS 不工作的主要内容,如果未能解决你的问题,请参考以下文章
无法修复 spring-security-oauth2-resource-server 上的漏洞
带有 WSO2 身份服务器的 Spring Cloud Security
Spring Security 4.2.3 Filters 解析
如何使用带有 WebClient 的 spring-security-oauth2 自定义 OAuth2 令牌请求的授权标头?