How use .crt for jwt?

Viewed 379

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>
1 Answers

The key that you need to validate an incoming JWT should come from the Authorization Server which issued you the JWT. You don't create it yourself, unless you are also in control of the Authorization Server, then you had to create a pair of private and public key. The private key is used to sign JWTs, and the public key should be distributed to APIs, so they can validate JWTs.

A perfect way is when the Authorization Server exposes a JWKS endpoint where your API can download the relevant key from. If this isn't possible in your case and you really need the key file, then you should get it from whoever manages the Authorization Server. You can then have a look e.g. here: Adding .crt to Spring Boot to enable SSL on how to add a crt into a keystore. Once you have the keystore, the code you have should work.

Related