如何在Spring Boot OAuth2资源服务器中使用密码授权处理CORS问题

huangapple go评论70阅读模式
英文:

How do I handle CORS in Spring Boot Oauth2 Resource Server with password grant

问题

以下是您要翻译的代码部分:

**Details:**
I am using spring boot oauth2 resource server which is giving me CORS even after trying different approaches to filter this off.

**How do my code look ?**

Its a simple resource server with spring boot with `spring-cloud-starter-oauth2` and `spring-cloud-starter-security` as two major dependencies.

I have used java annotations to make this a resource server :

@CrossOrigin(origins = "*", maxAge = 3600, allowedHeaders = "*")
@RestController
@RequestMapping("/api/v1")
@EnableResourceServer

**Here is how I tried to resolve this :**

I tried to add a custom filter which skips further filter calls with code below. After this I got "Authorization Header not allowed in preflight request on browser". After adding `CORS everyehere` extension to my browser my requests succeeded.

@EnableWebSecurity(debug = true)
@Order(Ordered.HIGHEST_PRECEDENCE)
public class WebSecurityConfig implements Filter {

    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) res;
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, PUT, OPTIONS, DELETE, PATCH");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
        response.setHeader("Access-Control-Expose-Headers", "Location");
        System.out.println(request.getMethod());
        System.out.println("-----------------");
        if(!request.getMethod().equals("OPTIONS")) {
            chain.doFilter(req, res);
        }
    }

    @Override
    public void init(FilterConfig filterConfig) {}

    @Override
    public void destroy() {}

}
英文:

Details:
I am using spring boot oauth2 resource server which is giving me CORS even after trying different approaches to filter this off.

How do my code look ?

Its a simple resource server with spring boot with spring-cloud-starter-oauth2 and spring-cloud-starter-security as two major dependencies.

I have used java annotations to make this a resource server :

@CrossOrigin(origins = "*", maxAge = 3600, allowedHeaders = "*")
@RestController
@RequestMapping("/api/v1")
@EnableResourceServer

Here is how I tried to resolve this :

I tried to add a custom filter which skips further filter calls with code below. After this I got "Authorization Header not allowed in preflight request on browser". After adding CORS everyehere extension to my browser my requests succeeded.

@EnableWebSecurity(debug = true)
@Order(Ordered.HIGHEST_PRECEDENCE)
public class WebSecurityConfig implements Filter {
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "POST, GET, PUT, OPTIONS, DELETE, PATCH");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
response.setHeader("Access-Control-Expose-Headers", "Location");
System.out.println(request.getMethod());
System.out.println("-----------------");
if(!request.getMethod().equals("OPTIONS")) {
chain.doFilter(req, res);
}
}
@Override
public void init(FilterConfig filterConfig) {}
@Override
public void destroy() {}
}

答案1

得分: 1

I had the same problem and that was the resolution.

public class ResourceServerCustom extends ResourceServerConfigurerAdapter {

	@Override
	public void configure(HttpSecurity http) throws Exception {
		http.csrf().disable().cors().disable().authorizeRequests().antMatchers("/oauth/token/**").permitAll()
				.anyRequest().authenticated().and().exceptionHandling()
				.authenticationEntryPoint(new AuthExceptionEntryPoint());

		http.cors().configurationSource(request -> new CorsConfiguration().applyPermitDefaultValues());

	}
}

And others configs.

public class WebSecurityCustom extends WebSecurityConfigurerAdapter {

	public TokenStore tokenStore;

	@Bean
	@Override
	protected AuthenticationManager authenticationManager() throws Exception {
		return super.authenticationManager();
	}

	@Override
	public void configure(WebSecurity web) throws Exception {
		web.ignoring().antMatchers("/v2/api-docs", "/configuration/ui", "/swagger-resources/**",
				"/configuration/security", "/swagger-ui.html", "/webjars/**");
		web.ignoring().antMatchers(HttpMethod.OPTIONS);
	}

}
public class CorsFilterCustom extends OncePerRequestFilter {

	@Override
	protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
			throws ServletException, IOException {
		response.setHeader("Access-Control-Allow-Origin", "*");
		response.setHeader("Access-Control-Allow-Credentials", "true");
		response.setHeader("Access-Control-Allow-Methods",
				"ACL, CANCELUPLOAD, CHECKIN, CHECKOUT, COPY, DELETE, GET, HEAD, LOCK, MKCALENDAR, MKCOL, MOVE, OPTIONS, POST, PROPFIND, PROPPATCH, PUT, REPORT, SEARCH, UNCHECKOUT, UNLOCK, UPDATE, VERSION-CONTROL");
		response.setHeader("Access-Control-Max-Age", "3600");
		response.setHeader("Access-Control-Allow-Headers",
				"Origin, X-Requested-With, Content-Type, Accept, Key, Authorization");

		if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
			response.setStatus(HttpServletResponse.SC_OK);
		} else {
			chain.doFilter(request, response);
		}
	}
}
public class AuthorizationServerCustom implements AuthorizationServerConfigurer {

	@Override
	public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
		security.checkTokenAccess("isAuthenticated()");
	}

	@Override
	public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
		endpoints.tokenStore(tokenStore()).authenticationManager(authenticationManager);
	}

}
public class AuthExceptionEntryPoint implements AuthenticationEntryPoint {

	@Override
	public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException arg2)
			throws ServletException, IOException {
		final Map<String, Object> mapBodyException = new HashMap<>();

		mapBodyException.put("error", "Error from AuthenticationEntryPoint");
		mapBodyException.put("message", "Message from AuthenticationEntryPoint");
		mapBodyException.put("exception", "My stack trace exception");
		mapBodyException.put("path", request.getServletPath());
		mapBodyException.put("timestamp", (new Date()).getTime());

		response.setContentType("application/json");
		response.setStatus(HttpServletResponse.SC_FORBIDDEN);

		final ObjectMapper mapper = new ObjectMapper();
		mapper.writeValue(response.getOutputStream(), mapBodyException);
	}
}
英文:

I had the same problem and
that was the resolution.

public class ResourceServerCustom extends ResourceServerConfigurerAdapter {
@Override
public void configure(HttpSecurity http) throws Exception {
http.csrf().disable().cors().disable().authorizeRequests().antMatchers(&quot;/oauth/token/**&quot;).permitAll()
.anyRequest().authenticated().and().exceptionHandling()
.authenticationEntryPoint(new AuthExceptionEntryPoint());
http.cors().configurationSource(request -&gt; new CorsConfiguration().applyPermitDefaultValues());
}

}

And others configs.

public class WebSecurityCustom extends WebSecurityConfigurerAdapter {
public TokenStore tokenStore;
@Bean
@Override
protected AuthenticationManager authenticationManager() throws Exception {
return super.authenticationManager();
}
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers(&quot;/v2/api-docs&quot;, &quot;/configuration/ui&quot;, &quot;/swagger-resources/**&quot;,
&quot;/configuration/security&quot;, &quot;/swagger-ui.html&quot;, &quot;/webjars/**&quot;);
web.ignoring().antMatchers(HttpMethod.OPTIONS);
}

}

public class CorsFilterCustom extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
throws ServletException, IOException {
response.setHeader(&quot;Access-Control-Allow-Origin&quot;, &quot;*&quot;);
response.setHeader(&quot;Access-Control-Allow-Credentials&quot;, &quot;true&quot;);
response.setHeader(&quot;Access-Control-Allow-Methods&quot;,
&quot;ACL, CANCELUPLOAD, CHECKIN, CHECKOUT, COPY, DELETE, GET, HEAD, LOCK, MKCALENDAR, MKCOL, MOVE, OPTIONS, POST, PROPFIND, PROPPATCH, PUT, REPORT, SEARCH, UNCHECKOUT, UNLOCK, UPDATE, VERSION-CONTROL&quot;);
response.setHeader(&quot;Access-Control-Max-Age&quot;, &quot;3600&quot;);
response.setHeader(&quot;Access-Control-Allow-Headers&quot;,
&quot;Origin, X-Requested-With, Content-Type, Accept, Key, Authorization&quot;);
if (&quot;OPTIONS&quot;.equalsIgnoreCase(request.getMethod())) {
response.setStatus(HttpServletResponse.SC_OK);
} else {
chain.doFilter(request, response);
}
}

}

public class AuthorizationServerCustom implements AuthorizationServerConfigurer {
@Override
public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
security.checkTokenAccess(&quot;isAuthenticated()&quot;);
}
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.tokenStore(tokenStore()).authenticationManager(authenticationManager);
}

}

public class AuthExceptionEntryPoint implements AuthenticationEntryPoint {
@Override
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException arg2)
throws ServletException, IOException {
final Map&lt;String, Object&gt; mapBodyException = new HashMap&lt;&gt;();
mapBodyException.put(&quot;error&quot;, &quot;Error from AuthenticationEntryPoint&quot;);
mapBodyException.put(&quot;message&quot;, &quot;Message from AuthenticationEntryPoint&quot;);
mapBodyException.put(&quot;exception&quot;, &quot;My stack trace exception&quot;);
mapBodyException.put(&quot;path&quot;, request.getServletPath());
mapBodyException.put(&quot;timestamp&quot;, (new Date()).getTime());
response.setContentType(&quot;application/json&quot;);
response.setStatus(HttpServletResponse.SC_FORBIDDEN);
final ObjectMapper mapper = new ObjectMapper();
mapper.writeValue(response.getOutputStream(), mapBodyException);
}

}

答案2

得分: 0

你可以通过添加一个配置类来配置CORS,类似于以下不同变化的方式:

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

  @Override
  protected void configure(HttpSecurity http) throws Exception {
    CorsConfiguration config = new CorsConfiguration();
    config.setAllowedMethods(Collections.singletonList("*"));

    http.cors().configurationSource(request -> config);
  }
}

或者像这样禁用CORS:

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

  @Override
  protected void configure(HttpSecurity http) throws Exception {
    http.cors().disable();
  }
}
英文:

You could configure cors by adding a configuration class with different variations like this

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
CorsConfiguration config = new CorsConfiguration();
config.setAllowedMethods(Collections.singletonList(&quot;*&quot;));
http.cors().configurationSource(request -&gt; config);
}
}

or just disable like this

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.cors().disable();
}
}

huangapple
  • 本文由 发表于 2020年8月6日 22:20:55
  • 转载请务必保留本文链接:https://go.coder-hub.com/63285634.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定