I have oauth2 + jwt authorization in my project.
@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();
}
}
}
i followed example(https://medium.com/swlh/stateless-jwt-authentication-with-spring-boot-a-better-approach-1f5dbae6c30f) and used jks for keys, in this case everything works. In my case, this approach of using jks is not suitable and i need to use kid.crt. The most interesting thing is that kid is the name of the file and it matches the kid field in the jwt header. That is, having received the kid field from the header, we should get a file that looks like kid.crt. I don't know how to get rid of jks in favor crt. How to create such a .crt? and how to configure at what point to take the file with the key?
jks I created this way
keytool -genkey -alias jwtsigning -keyalg RSA -keystore keystore.jks -keysize 2048
my application.properties
app.security.jwt.keystore-password=password
app.security.jwt.key-alias=jwtsigning
app.security.jwt.keystore-location=keys/keystore.jks
dependecies
<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>