如何将 .crt 用于 jwt?
How use .crt for jwt?
我的项目中有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是文件名,它和jwtheader中的kid字段匹配。也就是说,从 header 接收到 kid 字段后,我们应该得到一个看起来像 kid.crt 的文件。我不知道如何摆脱 jks 以支持 crt。如何创建这样的.crt?以及如何配置在什么时候用密钥取文件?
jks 我是这样创建的
keytool -genkey -alias jwtsigning -keyalg RSA -keystore keystore.jks -keysize 2048
我的application.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>
验证传入 JWT 所需的密钥应来自向您颁发 JWT 的授权服务器。您不会自己创建它,除非您也控制着授权服务器,否则您必须创建一对私钥和 public 密钥。私钥用于签署 JWT,public 密钥应分发给 APIs,以便他们可以验证 JWT。
一个完美的方法是当授权服务器公开一个 JWKS 端点时,您的 API 可以从中下载相关密钥。如果这在您的情况下是不可能的,并且您确实需要密钥文件,那么您应该从管理授权服务器的人那里获取它。然后你可以看看例如此处: 关于如何将 crt 添加到密钥库中。拥有密钥库后,您拥有的代码应该可以工作。
我的项目中有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是文件名,它和jwtheader中的kid字段匹配。也就是说,从 header 接收到 kid 字段后,我们应该得到一个看起来像 kid.crt 的文件。我不知道如何摆脱 jks 以支持 crt。如何创建这样的.crt?以及如何配置在什么时候用密钥取文件?
jks 我是这样创建的
keytool -genkey -alias jwtsigning -keyalg RSA -keystore keystore.jks -keysize 2048
我的application.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>
验证传入 JWT 所需的密钥应来自向您颁发 JWT 的授权服务器。您不会自己创建它,除非您也控制着授权服务器,否则您必须创建一对私钥和 public 密钥。私钥用于签署 JWT,public 密钥应分发给 APIs,以便他们可以验证 JWT。
一个完美的方法是当授权服务器公开一个 JWKS 端点时,您的 API 可以从中下载相关密钥。如果这在您的情况下是不可能的,并且您确实需要密钥文件,那么您应该从管理授权服务器的人那里获取它。然后你可以看看例如此处: