だから私は この例 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でテストすると
_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要求が拒否され、資格情報が欠落しているためです。
_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
_にアクセスできるようにしました。
_@Order(-1)
public class MyWebSecurity extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers(HttpMethod.OPTIONS, "/oauth/token").permitAll();
}
}
_
その後、私はcurlで次のエラーを受け取りました:
_{"timestamp":1433370068120,"status":403,"error":"Forbidden","message":"Expected CSRF token not found. Has your session expired?","path":"/oauth/token"}
_
簡単にするために、MyWebSecurityクラスのconfigure
メソッドにhttp.csrf().disable()
を追加しました。これはOPTIONリクエストで問題を解決しますが、POSTリクエストはもう機能しておらず、_There is no client authentication. Try adding an appropriate authentication filter.
_を取得します(curlとも)。
MyWebSecurityクラスとAuthServerを何らかの方法で接続する必要があるかどうかを調べましたが、運はありませんでした。元の例(冒頭のリンク)はauthenticationManagerも挿入しますが、これは私にとって何も変わりませんでした。
私の問題の理由を見つけました!
OPTIONSリクエストがCorsFilterによって処理された場合、フィルターチェーンを終了し、すぐに結果を返す必要がありました!
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プリフライトリクエストを無視できます。
そのため、サーバーは上記のように機能し、最初はMyWebSecurityクラスでブロックコメントを無視できます。
質問の解決策を使用して解決策を見つけました。しかし、ソリューションを説明する別の方法があります:
@Configuration
public class WebSecurityGlobalConfig extends WebSecurityConfigurerAdapter {
....
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring()
.antMatchers(HttpMethod.OPTIONS);
}
...
}
私は次を使用して同様の問題に遭遇しました
Spring Boot 1.5.8.RELEASE
_Spring OAuth 2.2.0.RELEASE
_ wVuejs
アプリaxios
ajaxリクエストライブラリを使用postman
ですべてが機能します! Vuejs
アプリからリクエストを開始すると、次のエラーが発生しました
オプション http:// localhost:8080/springboot/oauth/token 401()
そして
XMLHttpRequestはロードできません http:// localhost:8080/springboot/oauth/token 。プリフライトの応答に無効なHTTPステータスコード401が含まれています
少し読んだ後、次のようにOPTIONS
実装クラスのconfigure
をオーバーライドすることにより、WebSecurityConfigurerAdapter
リクエストを無視するように_Spring OAuth
_に指示できることがわかりました。
_@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers(HttpMethod.OPTIONS);
}
_
上記の追加は助けましたが、その後、CORS
特定のエラーに遭遇しました
オプション http:// localhost:8080/springboot/oauth/token 403()
そして
XMLHttpRequestはロードできません http:// localhost:8080/springboot/oauth/token 。プリフライトリクエストへの応答がアクセスコントロールチェックに合格しません。リクエストされたリソースに「Access-Control-Allow-Origin」ヘッダーがありません。したがって、オリジン ' http:// localhost:80 'はアクセスを許可されません。応答にはHTTPステータスコード403が含まれていました。
そして、以下に示すようにCorsConfig
を使用して上記の問題を解決しました
_@Configuration
public class CorsConfig {
@Bean
public FilterRegistrationBean corsFilterRegistrationBean() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.applyPermitDefaultValues();
config.setAllowCredentials(true);
config.setAllowedOrigins(Arrays.asList("*"));
config.setAllowedHeaders(Arrays.asList("*"));
config.setAllowedMethods(Arrays.asList("*"));
config.setExposedHeaders(Arrays.asList("content-length"));
config.setMaxAge(3600L);
source.registerCorsConfiguration("/**", config);
FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source));
bean.setOrder(0);
return bean;
}
}
_
上記のクラスを追加すると、期待どおりに機能します。 prod
に進む前に、使用のconsequences
を調査します
web.ignoring().antMatchers(HttpMethod.OPTIONS);
上記のCors
構成の_best practices
_も同様です。今のところ_*
_は仕事をしますが、実稼働環境では安全ではありません。
Cyrilの答えはpartially
を助けてくれました。そして、この Github の問題でCorsConfig
のアイデアに出会いました。
まあ、あなたは正しいです!それは解決策であり、私にとってもうまくいきました(私は同じ問題を抱えていました)
しかし、JavaのよりスマートなCORSフィルター実装を使用するように頑張ってみましょう: http://software.dzhuvinov.com/cors-filter.html
これはJavaアプリケーションの非常に完全なソリューションです。
実際には、 here ポイントの解決方法を見ることができます。
ここでSpring Boot 2を使用します。
私はAuthorizationServerConfigurerAdapter
でこれをしなければなりませんでした
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
Map<String, CorsConfiguration> corsConfigMap = new HashMap<>();
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
//TODO: Make configurable
config.setAllowedOrigins(Collections.singletonList("*"));
config.setAllowedMethods(Collections.singletonList("*"));
config.setAllowedHeaders(Collections.singletonList("*"));
corsConfigMap.put("/oauth/token", config);
endpoints.getFrameworkEndpointHandlerMapping()
.setCorsConfigurations(corsConfigMap);
//additional settings...
}