При использовании OAuth 2 пути REST API из списка не требующих авторизацию требуют токен
У меня есть такой конфиг для Spring Security с OAuth 2. Мне нужно, чтобы пути /actuator и /api/v1/client/register были доступны без авторизации. Как это сделать? Фильтр с @Order(2) не дает доступ к этим путям, они по-прежнему требуют авторизацию при помощи OAuth 2 токена. Как исправить проблему?
Проблема, как я понимаю, в настройках, которые применяет OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http)
@Configuration
@EnableWebSecurity
public class SpringSecurityConfiguration {
@Value("${yandex.security.client-id}")
private String clientId;
@Value("${yandex.security.client-secret}")
private String clientSecret;
@Autowired
private ClientRepository clients;
@Bean
@Order(1)
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http);
return http.build();
}
@Bean
@Order(2)
public SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests((authorize) -> authorize
.requestMatchers("/actuator/**").permitAll()
.requestMatchers("/api/v1/client/register").permitAll()
.anyRequest().authenticated()
)
.oauth2ResourceServer((oauth) -> oauth.jwt(Customizer.withDefaults()));
return http.build();
}
@Bean
public RegisteredClientRepository registeredClientRepository() {
List<RegisteredClient> registeredClients = clients.findAll().stream()
.map(client -> {
return RegisteredClient.withId(UUID.randomUUID().toString())
.clientId(client.getClientId())
.clientSecret(client.getClientSecret())
.clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_POST)
.authorizationGrantType(AuthorizationGrantType.CLIENT_CREDENTIALS)
.scope("read")
.scope("write")
.clientSettings(ClientSettings.builder().requireAuthorizationConsent(true).build())
.tokenSettings(TokenSettings.builder()
.accessTokenFormat(OAuth2TokenFormat.SELF_CONTAINED)
.idTokenSignatureAlgorithm(SignatureAlgorithm.RS256)
.accessTokenTimeToLive(Duration.ofSeconds(30 * 60))
.refreshTokenTimeToLive(Duration.ofSeconds(60 * 60))
.reuseRefreshTokens(true)
.build())
.build();
}).toList();
return new InMemoryRegisteredClientRepository(registeredClients);
}
/*@Bean
public JdbcRegisteredClientRepository registeredClientRepository(JdbcTemplate jdbc) {
JdbcRegisteredClientRepository clientRepository = new JdbcRegisteredClientRepository(jdbc);
List<RegisteredClient> registeredClients = clients.findAll().stream()
.map(client -> {
return RegisteredClient.withId(UUID.randomUUID().toString())
.clientId(client.getClientId())
.clientSecret(client.getClientSecret())
.clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_POST)
.authorizationGrantType(AuthorizationGrantType.CLIENT_CREDENTIALS)
.scope("read")
.scope("write")
.clientSettings(ClientSettings.builder().requireAuthorizationConsent(true).build())
.tokenSettings(TokenSettings.builder()
.accessTokenFormat(OAuth2TokenFormat.SELF_CONTAINED)
.idTokenSignatureAlgorithm(SignatureAlgorithm.RS256)
.accessTokenTimeToLive(Duration.ofSeconds(30 * 60))
.refreshTokenTimeToLive(Duration.ofSeconds(60 * 60))
.reuseRefreshTokens(true)
.build())
.build();
})
.toList();
registeredClients.forEach(clientRepository::save);
return clientRepository;
}*/
@Bean
public JWKSource<SecurityContext> jwkSource() {
KeyPair keyPair = generateRsaKey();
RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
RSAKey rsaKey = new RSAKey.Builder(publicKey)
.privateKey(privateKey)
.keyID(UUID.randomUUID().toString())
.build();
JWKSet jwkSet = new JWKSet(rsaKey);
return new ImmutableJWKSet<>(jwkSet);
}
private static KeyPair generateRsaKey() {
KeyPair keyPair;
try {
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
keyPairGenerator.initialize(2048);
keyPair = keyPairGenerator.generateKeyPair();
}
catch (Exception ex) {
throw new IllegalStateException(ex);
}
return keyPair;
}
@Bean
public JwtDecoder jwtDecoder(JWKSource<SecurityContext> jwkSource) {
return OAuth2AuthorizationServerConfiguration.jwtDecoder(jwkSource);
}
@Bean
public AuthorizationServerSettings authorizationServerSettings() {
return AuthorizationServerSettings.builder()
.tokenEndpoint("/security/oauth/token")
.build();
}
}