我在我的项目中有oauth2+jwt授权。
@Component
@RequiredArgsConstructor
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.cors()
.and()
.csrf().disable()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.exceptionHandling().disable()
.oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt);
}
}
@Slf4j
@Configuration
public class JwtConfiguration {
@Value("${app.security.jwt.keystore-location}")
private String keyStorePath;
@Value("${app.security.jwt.keystore-password}")
private String keyStorePassword;
@Value("${app.security.jwt.key-alias}")
private String keyAlias;
@Bean
public KeyStore keyStore() {
try {
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
InputStream resourceAsStream = Thread.currentThread().getContextClassLoader().getResourceAsStream(keyStorePath);
keyStore.load(resourceAsStream, keyStorePassword.toCharArray());
return keyStore;
} catch (IOException | CertificateException | NoSuchAlgorithmException | KeyStoreException e) {
log.error("Unable to load keystore: {}", keyStorePath, e);
}
throw new IllegalArgumentException("Unable to load keystore");
}
@Bean
public RSAPublicKey jwtValidationKey(KeyStore keyStore) {
try {
Certificate certificate = keyStore.getCertificate(keyAlias);
PublicKey publicKey = certificate.getPublicKey();
if (publicKey instanceof RSAPublicKey) {
return (RSAPublicKey) publicKey;
}
} catch (KeyStoreException e) {
log.error("Unable to load private key from keystore: {}", keyStorePath, e);
}
throw new IllegalArgumentException("Unable to load RSA public key");
}
@Bean
public JwtDecoder jwtDecoder(RSAPublicKey rsaPublicKey) {
NimbusJwtDecoder jwtDecoder = NimbusJwtDecoder.withPublicKey(rsaPublicKey).build();
OAuth2TokenValidator<Jwt> validator = new Validator();
jwtDecoder.setJwtValidator(validator);
return jwtDecoder;
}
class Validator implements OAuth2TokenValidator<Jwt> {
OAuth2Error error = new OAuth2Error("error", "error description", null);
@Override
public OAuth2TokenValidatorResult validate(Jwt jwt) {
......
return OAuth2TokenValidatorResult.success();
}
}
}
我仿效了这个例子(https://medium.com/swlh/stateless-jwt-authentication-with-spring-boot-a-better-approach-1f5dbae6c30f)使用jks作为键,在这种情况下,一切正常。在我的例子中,这种使用jks的方法不合适,我需要使用kid.crt。最有趣的是kid是文件名,它与jwt头中的kid字段匹配。也就是说,从头部接收到kid字段后,我们应该得到一个类似kid.crt的文件。我不知道如何摆脱jks而代之以crt。如何创建这样的.crt?以及如何配置在什么位置使用密钥获取文件?
我是这样创造的
keytool -genkey -alias jwtsigning -keyalg RSA -keystore keystore.jks -keysize 2048
我的应用程序.properties
app.security.jwt.keystore-password=password
app.security.jwt.key-alias=jwtsigning
app.security.jwt.keystore-location=keys/keystore.jks
依赖
<dependency>
<groupId>org.springframework.security.oauth</groupId>
<artifactId>spring-security-oauth2</artifactId>
<version>2.5.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
</dependency>
1条答案
按热度按时间rekjcdws1#
验证传入jwt所需的密钥应该来自向您发出jwt的授权服务器。您不需要自己创建它,除非您同时控制授权服务器,否则您必须创建一对私钥和公钥。私钥用于对JWT进行签名,公钥应分发到API,以便API能够验证JWT。
一个完美的方法是授权服务器公开jwks端点,您的api可以从该端点下载相关密钥。如果在您的情况下这是不可能的,并且您确实需要密钥文件,那么您应该从管理授权服务器的人那里获得它。然后,您可以查看一下,例如:将.crt添加到spring boot,以启用ssl,了解如何将crt添加到密钥库中。一旦你有了密钥库,你的代码就可以工作了。