【发布时间】:2019-08-08 07:07:56
【问题描述】:
尝试将现有资源服务从 Spring Boot 1.x 升级到 2.x。 Spring Security 4.5 在身份验证服务器上运行,并像这样对 JWT 令牌进行编码:
@Bean
public JwtAccessTokenConverter jwtAccessTokenConverter() {
JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
converter.setSigningKey(privateKey);
converter.setVerifierKey(publicKey);
return converter;
}
升级到 Spring Boot 2.1.3.RELEASE 的资源服务器抛出此错误:
OAuth2AuthenticationProcessingFilter:165 :
Authentication request failed: error="invalid_token",
error_description="Invalid access token:****..."
日志显示 OAuth2AuthenticationProcessingFilter 正在使用 MappingJackson2HttpMessageConverter 提取 JWT 令牌。 Spring Security 自动配置应该提供 JwtAccessTokenConverter bean 而不是 MappingJackson2HttpMessageConverter bean,因为我的属性文件中有一个键值:
security:
oauth2:
resource:
jwt:
key-value: |
-----BEGIN PUBLIC KEY-----
...
-----END PUBLIC KEY-----
这是应该检测到它的 Spring Security ResourceServerTokenServiceConfiguration 类。该属性匹配“security.oauth2.resource.jwt.key-value”。
public ConditionOutcome getMatchOutcome(ConditionContext context,
AnnotatedTypeMetadata metadata) {
ConditionMessage.Builder message = ConditionMessage
.forCondition("OAuth JWT Condition");
Environment environment = context.getEnvironment();
String keyValue = environment
.getProperty("security.oauth2.resource.jwt.key-value");
String keyUri = environment
.getProperty("security.oauth2.resource.jwt.key-uri");
if (StringUtils.hasText(keyValue) || StringUtils.hasText(keyUri)) {
return ConditionOutcome
.match(message.foundExactly("provided public key"));
}
return ConditionOutcome
.noMatch(message.didNotFind("provided public key").atAll());
}
这些是资源服务器安全依赖项:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security.oauth.boot</groupId>
<artifactId>spring-security-oauth2-autoconfigure</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security.oauth</groupId>
<artifactId>spring-security-oauth2</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-oauth2</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
这是资源服务器配置。它与 Spring Boot 1.5.x 基本相同。
@Configuration
@EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
private static final String RESOURCE_ID = "my-service";
@Override
public void configure(final HttpSecurity http) throws Exception {
http.authorizeRequests().anyRequest().authenticated();
}
@Override
public void configure(ResourceServerSecurityConfigurer resources) {
resources.resourceId(RESOURCE_ID);
}
}
我错过了什么?
【问题讨论】:
标签: spring-boot spring-security jwt spring-security-oauth2