Я хочу защитить некоторые API-интерфейсы с помощью токена JWT, и я следую https://github.com/spring-projects/spring-security/tree/5.3.3.RELEASE/samples/boot/oauth2resourceserver ссылке для реализации сервера ресурсов, который будет проверять токен JWT, поступающий как часть заголовка авторизации.
У меня есть зависимости ниже в моем pom
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
<version>2.2.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-oauth2-jose</artifactId>
<version>5.3.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
<version>2.3.1.RELEASE</version>
</dependency>
Ниже приведен класс securityConfiguration.
@EnableWebSecurity
@Order(2)
public class OAuth2ResourceServerSecurityConfiguration extends WebSecurityConfigurerAdapter {
@Value("${spring.security.oauth2.resourceserver.jwt.jwk-set-uri}")
String jwkSetUri;
@Value("${spring.security.oauth2.resourceserver.jwt.issuer-uri}")
String jwkIssuerUri;
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.authorizeRequests(authorizeRequests ->
{
try {
authorizeRequests
.antMatchers(HttpMethod.GET, "/message/**").authenticated();
// .and().authorizeRequests().antMatchers(HttpMethod.POST, "/message/**").authenticated();
}
catch (Exception e) {
e.printStackTrace();
}
}
)
.oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt);
// @formatter:on
}
OAuth2TokenValidator<Jwt> audienceValidator() {
return new JwtClaimValidator<List<String>>("aud", aud -> aud.contains("something"));
}
@Bean
JwtDecoder jwtDecoder() {
NimbusJwtDecoder jwtDecoder = (NimbusJwtDecoder) JwtDecoders.fromIssuerLocation(this.jwkIssuerUri);
OAuth2TokenValidator<Jwt> audienceValidator = audienceValidator();
OAuth2TokenValidator<Jwt> withIssuer = JwtValidators.createDefaultWithIssuer(this.jwkIssuerUri);
OAuth2TokenValidator<Jwt> withAudience = new DelegatingOAuth2TokenValidator<>(withIssuer, audienceValidator);
jwtDecoder.setJwtValidator(withAudience);
return NimbusJwtDecoder.withJwkSetUri(this.jwkSetUri).build();
}
}
Вот мои application.properties
spring.security.oauth2.resourceserver.jwt.jwk-set-uri=https://login.microsoftonline.com/************/discovery/v2.0/keys
spring.security.oauth2.resourceserver.jwt.issuer-uri=https://login.microsoftonline.com/***************/v2.0
Мой API (ы) для тестирования
@GetMapping("/message")
public String message(@AuthenticationPrincipal Jwt jwt) {
return "secret message" + " " + jwt.getIssuerUri();
}
@PostMapping("/message")
public String createMessage(@RequestBody String message) {
return String.format("Message was created. Content: %s", message);
}
Теперь, когда я вызываю http://localhost: 8080 / сообщение без отправки какого-либо заголовка авторизации, он выдает HTTP 401. Однако, когда я создаю действительный токен и отправляю этот токен как часть заголовка «Авторизация» как токен-носитель приложение выдает статус HTTP 404
{
"timestamp": "2020-06-18T00:32:18.320+0000",
"status": 404,
"error": "Not Found",
"message": "No message available",
"path": "/message"
}
Во время отладки кода во время запуска я замечаю, что строка ниже возвращает объект с заполненным атрибутом Oauth2Error, который говорит «invalid_request : aud не является действительным заявлением "
OAuth2TokenValidator<Jwt> audienceValidator() {
return new JwtClaimValidator<List<String>>("aud", aud -> aud.contains("something"));
}
Я даже попытался прокомментировать это и запустить приложение, но все равно получаю ошибку 404, когда Authoriz Заголовок сообщения присутствует. Что может быть не так с моей настройкой?