独立 Spring OAuth2 JWT 授权服务器 + CORS [英] Standalone Spring OAuth2 JWT Authorization Server + CORS
问题描述
所以我从 这个例子来自 Dave Syer
So I have the following Authorization Server condensed from this example from Dave Syer
@SpringBootApplication
public class AuthserverApplication {
public static void main(String[] args) {
SpringApplication.run(AuthserverApplication.class, args);
}
/* added later
@Configuration
@Order(Ordered.HIGHEST_PRECEDENCE)
protected static class MyWebSecurity extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http //.csrf().disable()
.authorizeRequests()
.antMatchers(HttpMethod.OPTIONS, "/oauth/token").permitAll();
}
}*/
@Configuration
@EnableAuthorizationServer
protected static class OAuth2AuthorizationConfig extends
AuthorizationServerConfigurerAdapter {
@Autowired
private AuthenticationManager authenticationManager;
@Bean
public JwtAccessTokenConverter jwtAccessTokenConverter() {
JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
KeyPair keyPair = new KeyStoreKeyFactory(
new ClassPathResource("keystore.jks"), "foobar".toCharArray())
.getKeyPair("test");
converter.setKeyPair(keyPair);
return converter;
}
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory()
.withClient("acme")
//.secret("acmesecret")
.authorizedGrantTypes(//"authorization_code", "refresh_token",
"password").scopes("openid");
}
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints)
throws Exception {
endpoints.authenticationManager(authenticationManager).accessTokenConverter(
jwtAccessTokenConverter());
}
@Override
public void configure(AuthorizationServerSecurityConfigurer oauthServer)
throws Exception {
oauthServer.tokenKeyAccess("permitAll()").checkTokenAccess(
"isAuthenticated()");
}
}
}
当我运行它并用 curl 测试时
when I run it and test it with curl
curl acme@localhost:8110/oauth/token -d grant_type=password -d client_id=acme -d username=user -d password=password
我收到了 JWT 作为响应,但是一旦我尝试从我的前端(不同端口上的 Angular JS)访问 AuthServer,我就会收到 CORS 错误.不是因为缺少标题,而是因为 OPTION 请求被拒绝并且缺少凭据.
I get a JWT as respons, but as soon as I try to access the AuthServer from my Frontend (Angular JS on a different port) I get CORS error. Not becauce of missing Headers, but because the OPTION request is rejected and is missing the credentials.
Request URL:http://localhost:8110/oauth/token
Request Method:OPTIONS
Status Code:401 Unauthorized
WWW-Authenticate:Bearer realm="oauth", error="unauthorized", error_description="Full authentication is required to access this resource"
我已经知道我必须添加一个 CorsFilter 并且另外发现 在这篇文章中,我使用了第一个答案的片段,让 OPTIONS 请求无需凭据即可访问 /oauth/token
:
I already knew that I have to add a CorsFilter and additionally found this post where I used the the snippet for the first Answer to let the OPTIONS request access /oauth/token
without credentials:
@Order(-1)
public class MyWebSecurity extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers(HttpMethod.OPTIONS, "/oauth/token").permitAll();
}
}
之后我用 curl 得到以下错误:
After that I got with curl the following error:
{"timestamp":1433370068120,"status":403,"error":"Forbidden","message":"Expected CSRF token not found. Has your session expired?","path":"/oauth/token"}
为了简单起见,我只是将 http.csrf().disable()
添加到 MyWebSecurity 类的 configure
方法中,这解决了 OPTION 请求的问题,但因此 POST 请求不再起作用,我得到 没有客户端身份验证.尝试添加适当的身份验证过滤器.
(也使用 curl).
So to make it simple I just added http.csrf().disable()
to the configure
method of MyWebSecurity class, which solves the Problem with the OPTION request, but therefore the POST request isn't working anymore and I get There is no client authentication. Try adding an appropriate authentication filter.
(also with curl).
我试图找出是否必须以某种方式连接 MyWebSecurity 类和 AuthServer,但没有任何运气.原始示例(开头的链接)也注入了 authenticationManager,但这对我没有任何改变.
I tried to find out if I have to somehow connect MyWebSecurity class and the AuthServer, but without any luck. The original example (link in the beginning) injects as well the authenticationManager, but this changed nothing for me.
推荐答案
找到我的问题的原因!
我只需要结束过滤器链并在 CorsFilter 处理 OPTIONS 请求时立即返回结果!
I just needed to end the filterchain and return the result immediatly if a OPTIONS request is processed by the CorsFilter!
SimpleCorsFilter.java
SimpleCorsFilter.java
@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class SimpleCorsFilter implements Filter {
public SimpleCorsFilter() {
}
@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");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "x-requested-with, authorization");
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() {
}
}
之后我可以忽略我的 AuthServer =D 中的 OPTIONS 预检请求
After that I could ignore the OPTIONS preflight request in my AuthServer =D
因此服务器的工作方式与上面的片段相同,您可以在开头使用 MyWebSecurity 类忽略块注释.
So the Server works as in the snipped above and you can ignore the block comment with MyWebSecurity class in the beginning.
这篇关于独立 Spring OAuth2 JWT 授权服务器 + CORS的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!