#Spring security failing to convert String to RSA keys

60 messages · Page 1 of 1 (latest)

prime birch
#

getting the following error: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'securityConfig': Unsatisfied dependency expressed through field 'privateKey': Failed to convert value of type 'java.lang.String' to required type 'java.security.interfaces.RSAPrivateKey'; Failed to convert from type [java.lang.String] to type [@org.springframework.beans.factory.annotation.Value java.security.interfaces.RSAPrivateKey] for value [${jwt.private.key]

not sure what to do and havent been able to find much on this, anyone have any idea? thanks

quick hazelBOT
#

This post has been reserved for your question.

Hey @prime birch! Please use /close or the Close Post button above when your problem is solved. Please remember to follow the help guidelines. This post will be automatically marked as dormant after 300 minutes of inactivity.

TIP: Narrow down your issue to simple and precise questions to maximize the chance that others will reply in here.

prime birch
#

i have generated both private and public keys and have them in these files under resources

modern quiver
#

Can you show your SecurityConfig class?

#

or the class of the securityConfig bean

prime birch
#

yea

modern quiver
#

Instead of injecting an RSAPrivateKey object, you can inject a resource

prime birch
#

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Value("${jwt.public.key}")
    private RSAPublicKey publicKey;
    @Value("${jwt.private.key")
    private RSAPrivateKey privateKey;

    @Bean
    SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http.csrf(csrf -> csrf.disable())
                .authorizeHttpRequests(
                auth -> auth.requestMatchers("/authenticate").permitAll()
                        .requestMatchers(HttpMethod.POST, "/users").permitAll()
                        .anyRequest().authenticated())
                .httpBasic(Customizer.withDefaults())
                .oauth2ResourceServer(
                        conf -> conf.jwt(Customizer.withDefaults()));
        return http.build();
    }

    @Bean
    JwtDecoder jwtDecoder() {
        return NimbusJwtDecoder.withPublicKey(publicKey).build();
    }

    @Bean
    JwtEncoder jwtEncoder() {
        var jwk = new RSAKey.Builder(publicKey).privateKey(privateKey).build();
        var jwks = new ImmutableJWKSet<>(new JWKSet(jwk));
        return new NimbusJwtEncoder(jwks);
    }

    @Bean
    PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}
modern quiver
#

yeah so Value("${jwt.public.key}") doesn't work for RSAPublicKey objects

prime birch
modern quiver
#

you can probably inject it using a constructor like that:

public SecurityConfig(@Value("${jwt.public.key}") Resource publicKey, @Value("${jwt.private.key") Resource privateKey){
  //TODO convert them
}
prime birch
#

i have seen it in spring security tutorials too

modern quiver
#

same Spring version?

prime birch
#

hmm maybe not but it wasnt too long ago

modern quiver
#

Maybe doing it automatically without any configuration requires some dependency

#

You are using Spring Boot, right?

prime birch
#

yea

#
<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>

        <dependency>
            <groupId>org.postgresql</groupId>
            <artifactId>postgresql</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
modern quiver
#

you might need spring-security-rsa or similar, idk

prime birch
#

am i missing something?

modern quiver
#

maybe it only happens automatically if spring-boot-starter-security or similar is in the dependencies

#

Did you also use Spring Resource Server in the project where it works?

modern quiver
#

But why can't you use the RSA support of Spring resource server directly?

modern quiver
#

that's the documentation of the thing you are using

#

@prime birch

#

or you might also follow that

#

I think that's actually the thing you need

#

(it's a bit above in the docs)

#
@Bean
BeanFactoryPostProcessor conversionServiceCustomizer() {
    return beanFactory ->
        beanFactory.getBean(RsaKeyConversionServicePostProcessor.class)
                .setResourceLoader(new CustomResourceLoader());
}
prime birch
#

i'll give it a read

#

thanks

quick hazelBOT
# prime birch thanks

If you are finished with your post, please close it.
If you are not, please ignore this message.
Note that you will not be able to send further messages here after this post have been closed but you will be able to create new posts.

modern quiver
#

If this doesn't work like you want to, please check whether you have a RsaKeyConversionServicePostProcessor bean registered in your application

#

Are you using Eclipse with Spring Tools 4, VSC with Spring Tools 4, any other Spring Tools 4 IDE or IntelliJ Ultimate?

prime birch
#

im using intellij community

modern quiver
#

so you'd need to check in the application

#

Do you have Spring actuator enabled for testing?

#

In any way, you can just try autowiring an RsaKeyConversionServicePostProcessor instance and you'll notice it if it doesn't work (unless the application crashes before that, then you wouldn't notice)

#

essentially the docs should be useful

prime birch
#

ffs

#

thanks a lot for the help anyway

quick hazelBOT
# prime birch thanks a lot for the help anyway

If you are finished with your post, please close it.
If you are not, please ignore this message.
Note that you will not be able to send further messages here after this post have been closed but you will be able to create new posts.