Standalone Spring OAuth2 JWT-Autorisierungsserver + CORS
So habe ich den folgenden Authorization Server komprimiert vondieses Beispiel von 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()");
}
}
}
wenn ich es laufen lasse und es mit curl teste
curl acme@localhost:8110/oauth/token -d grant_type=password -d client_id=acme -d username=user -d password=password
Ich erhalte eine JWT als Antwort, aber sobald ich versuche, über mein Frontend (Angular JS an einem anderen Port) auf den AuthServer zuzugreifen, erhalte ich einen CORS-Fehler. Nicht, weil Header fehlen, sondern weil die OPTION-Anforderung abgelehnt wird und die Anmeldeinformationen fehlen.
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"
Ich wusste schon, dass ich einen CorsFilter hinzufügen muss und fand zusätzlichdieser Beitra wo ich das Snippet für die erste Antwort verwendet habe, um die OPTIONEN Zugriff anfordern zu lassen/oauth/token
ohne Anmeldeinformationen:
@Order(-1)
public class MyWebSecurity extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers(HttpMethod.OPTIONS, "/oauth/token").permitAll();
}
}
Nachdem ich mit curl folgenden Fehler bekommen habe:
{"timestamp":1433370068120,"status":403,"error":"Forbidden","message":"Expected CSRF token not found. Has your session expired?","path":"/oauth/token"}
Also, um es einfach zu machen, habe ich gerade hinzugefügthttp.csrf().disable()
zumconfigure
-Methode der MyWebSecurity-Klasse, die das Problem mit der OPTION-Anforderung löst, aber daher funktioniert die POST-Anforderung nicht mehr und ich erhalteThere is no client authentication. Try adding an appropriate authentication filter.
(auch mit Locken).
Ich habe versucht herauszufinden, ob ich die MyWebSecurity-Klasse irgendwie mit dem AuthServer verbinden muss, aber ohne Erfolg. Das ursprüngliche Beispiel (Link am Anfang) enthält auch den Authentifizierungs-Manager, aber das hat für mich nichts geändert.