Spring oauth/token 上的启动休息服务选项 401
Spring boot rest service options 401 on oauth/token
我正在使用 spring 启动来进行简单的休息服务。要在 Angular 2 中使用它,我在 oauth/token 端点上检索令牌时遇到 CORS 问题。
Chrome 中的错误信息如下。
error message
zone.js:101 OPTIONS http://192.168.0.9:8080/api/oauth/token
XMLHttpRequest cannot load http://192.168.0.9:8080/api/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://localhost:3000' is therefore not allowed access. The response had HTTP status code 401.
相关文件如下。
MyConfig.java
@Configuration
public class MyConfig {
@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurerAdapter() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("**")
.allowedOrigins("*").allowedMethods("POST, GET, HEAD, OPTIONS")
.allowCredentials(true)
.allowedHeaders("Content-Type,X-Requested-With,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers")
.exposedHeaders("Access-Control-Allow-Origin,Access-Control-Allow-Credentials")
.maxAge(10);
}
};
}
}
OAuth2ResourceServerConfig.java
@Configuration
@EnableResourceServer
class OAuth2ResourceServerConfig extends ResourceServerConfigurerAdapter {
@Override
public void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.anonymous()
.and()
.authorizeRequests()
.antMatchers(HttpMethod.OPTIONS,"**").permitAll()
.antMatchers("/authenticated/**").authenticated()
;
}
}
我是 java 和 spring 的新手。我发现了一些类似的问题,例如 ,但我真的不明白如何让它在 spring 启动时工作。
请注意正常的休息控制器端点工作正常。问题是 oauth/token,选项请求 returns 401 状态。
请在 spring 引导中显示一些工作代码。谢谢!
您可以将此 CORS 过滤器添加到您的项目中
@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class SimpleCORSFilter implements Filter {
@Override
public void init(FilterConfig fc) throws ServletException {
}
@Override
public void doFilter(ServletRequest req, ServletResponse resp,
FilterChain chain) throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) resp;
HttpServletRequest request = (HttpServletRequest) req;
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "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() {
}
}
这里是原生Spring框架解决方案:
@Bean
public CorsFilter corsFilter(CorsConfiguration config) {
log.debug("Registering CORS filter");
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/api/**", config);
source.registerCorsConfiguration("/v2/api-docs", config);
source.registerCorsConfiguration("/oauth/**", config);
return new CorsFilter(source);
}
如果您使用 spring boot + Spring OAuth,您必须添加
@Order(Ordered.HIGHEST_PRECEDENCE)
到您的 CORS 过滤器
@Configuration
@Order(Ordered.HIGHEST_PRECEDENCE)
public class CORSFilter implements Filter {
private FilterConfig config;
public static final String CREDENTIALS_NAME = "Access-Control-Allow-Credentials";
public static final String ORIGIN_NAME = "Access-Control-Allow-Origin";
public static final String METHODS_NAME = "Access-Control-Allow-Methods";
public static final String HEADERS_NAME = "Access-Control-Allow-Headers";
public static final String MAX_AGE_NAME = "Access-Control-Max-Age";
@Override
public void destroy() {
}
@Override
public void doFilter(ServletRequest req, ServletResponse resp,
FilterChain chain) throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) resp;
HttpServletRequest request = (HttpServletRequest) req;
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "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 init(FilterConfig filterConfig) throws ServletException {
config = filterConfig;
}
}
浏览器通过带有 OPTIONS header 的请求检查 CORS 设置。如果您配置了授权,OPTIONS 请求将被阻止为未授权。
您只需在 WebConfigurerAdapter 中添加 cors 支持即可。
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// ...
http.cors();
}
}
查看此 link 了解更多信息:https://www.baeldung.com/spring-security-cors-preflight
我正在使用 spring 启动来进行简单的休息服务。要在 Angular 2 中使用它,我在 oauth/token 端点上检索令牌时遇到 CORS 问题。
Chrome 中的错误信息如下。
error message
zone.js:101 OPTIONS http://192.168.0.9:8080/api/oauth/token
XMLHttpRequest cannot load http://192.168.0.9:8080/api/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://localhost:3000' is therefore not allowed access. The response had HTTP status code 401.
相关文件如下。
MyConfig.java
@Configuration
public class MyConfig {
@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurerAdapter() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("**")
.allowedOrigins("*").allowedMethods("POST, GET, HEAD, OPTIONS")
.allowCredentials(true)
.allowedHeaders("Content-Type,X-Requested-With,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers")
.exposedHeaders("Access-Control-Allow-Origin,Access-Control-Allow-Credentials")
.maxAge(10);
}
};
}
}
OAuth2ResourceServerConfig.java
@Configuration
@EnableResourceServer
class OAuth2ResourceServerConfig extends ResourceServerConfigurerAdapter {
@Override
public void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.anonymous()
.and()
.authorizeRequests()
.antMatchers(HttpMethod.OPTIONS,"**").permitAll()
.antMatchers("/authenticated/**").authenticated()
;
}
}
我是 java 和 spring 的新手。我发现了一些类似的问题,例如
请注意正常的休息控制器端点工作正常。问题是 oauth/token,选项请求 returns 401 状态。
请在 spring 引导中显示一些工作代码。谢谢!
您可以将此 CORS 过滤器添加到您的项目中
@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class SimpleCORSFilter implements Filter {
@Override
public void init(FilterConfig fc) throws ServletException {
}
@Override
public void doFilter(ServletRequest req, ServletResponse resp,
FilterChain chain) throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) resp;
HttpServletRequest request = (HttpServletRequest) req;
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "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() {
}
}
这里是原生Spring框架解决方案:
@Bean
public CorsFilter corsFilter(CorsConfiguration config) {
log.debug("Registering CORS filter");
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/api/**", config);
source.registerCorsConfiguration("/v2/api-docs", config);
source.registerCorsConfiguration("/oauth/**", config);
return new CorsFilter(source);
}
如果您使用 spring boot + Spring OAuth,您必须添加
@Order(Ordered.HIGHEST_PRECEDENCE)
到您的 CORS 过滤器
@Configuration
@Order(Ordered.HIGHEST_PRECEDENCE)
public class CORSFilter implements Filter {
private FilterConfig config;
public static final String CREDENTIALS_NAME = "Access-Control-Allow-Credentials";
public static final String ORIGIN_NAME = "Access-Control-Allow-Origin";
public static final String METHODS_NAME = "Access-Control-Allow-Methods";
public static final String HEADERS_NAME = "Access-Control-Allow-Headers";
public static final String MAX_AGE_NAME = "Access-Control-Max-Age";
@Override
public void destroy() {
}
@Override
public void doFilter(ServletRequest req, ServletResponse resp,
FilterChain chain) throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) resp;
HttpServletRequest request = (HttpServletRequest) req;
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "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 init(FilterConfig filterConfig) throws ServletException {
config = filterConfig;
}
}
浏览器通过带有 OPTIONS header 的请求检查 CORS 设置。如果您配置了授权,OPTIONS 请求将被阻止为未授权。
您只需在 WebConfigurerAdapter 中添加 cors 支持即可。
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// ...
http.cors();
}
}
查看此 link 了解更多信息:https://www.baeldung.com/spring-security-cors-preflight