1

I have a oauth flow in my project.

I retrieve in the front-end a jwt token and add it to each request in the authorization header.

Now I need to validate said token and verify the signature in my back-end which is a kotlin spring boot app.

I know how to validate the token with the jjwt library but I don't understand where the validation is done.

I have a certificate to validate the tokens with and just want to let the requests with a valid token to be treated.

I saw online that some people do it with a OncePerRequestFilter that they add to their SecurityConfiguration but I don't understand what's going on and how it works.

I tried searching for tutorials online but many of them make a backend that's both the authorization server and resource server. I just want the backend to be the resource server that checks with the certificate if the token is valid and treats the request if it is. How can I do that ?

For now this is my SecurityConfiguration :

package com.renaulttrucks.transfertprotocolbackend.security.config

import org.springframework.beans.factory.annotation.Value
import org.springframework.security.config.annotation.web.builders.HttpSecurity
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter

@EnableWebSecurity
class SecurityConfig : WebSecurityConfigurerAdapter() {

    @Value("\${security.enabled}")
    val securityEnabled : Boolean? = false

    @Throws(Exception::class)
    override fun configure(http: HttpSecurity) {

        if(!securityEnabled!!) {
            http.httpBasic()
                .and()
                .authorizeRequests()
                .antMatchers("/**").permitAll()
                .and()
                .csrf().disable()
                .formLogin().disable()
        } else {
            http.httpBasic()
                .and()
                .authorizeRequests()
                .antMatchers("/**").permitAll()
                .and()
                .csrf().disable()
                .formLogin().disable()
        }
    }

}
  • Check out spring-security's samples: https://github.com/spring-projects/spring-security-samples/tree/main/servlet/spring-boot/java/oauth2/resource-server/hello-security – sdoxsee May 06 '21 at 14:10

1 Answers1

1

Spring Security supports resource servers out-of-the-box when including the correct dependencies and configuration.

As @sdoxsee mentioned, there is a Spring Security sample that outlines how to create a resource server with a public key; however, I'll briefly summarize it here, though you can find more detail in the Spring Security reference.

First, you need to add the appropriate dependency. If you are a Spring Boot application, then you can add:

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
</dependency>

Second, you either specify your key as a Boot property:

spring:
  security:
    oauth2:
      resourceserver:
        jwt:
          public-key-location: classpath:my-key.pub

or, you configure a JwtDecoder with your public key directly:

@Configuration
class SecurityConfig {
    @Value("${public.key.property}") val key : RSAPublicKey;

    @Bean
    fun jwtDecoder() : JwtDecoder {
        return NimbusJwtDecoder.withPublicKey(this.key).build();
    }
}

Either the Boot property or the JwtDecoder @Bean will introduce a filter automatically into the filter chain called BearerTokenAuthenticationFilter, so you don't need to create your own.

jzheaux
  • 7,042
  • 3
  • 22
  • 36
  • I just tried it like you and @sdoxsee mentioned but it isn't working. I don't have a public key to validate the token but a certificate. I get the following errors using the certificate's path to the key : Caused by: org.springframework.beans.ConversionNotSupportedException: Failed to convert value of type 'java.lang.String' to required type 'java.security.interfaces.RSAPublicKey'; nested exception is java.lang.IllegalStateException: Cannot convert value of type 'java.lang.String' to required type 'java.security.interfaces.RSAPublicKey': no matching editors or conversion strategy found – Hadestructhor May 10 '21 at 09:52
  • I think you can convert a certificate into a public key. Both OpenSSL https://stackoverflow.com/questions/17143606/how-to-save-public-key-from-a-certificate-in-pem-format and Java https://stackoverflow.com/questions/6358555/obtaining-public-key-from-certificate have this capability. – jzheaux May 10 '21 at 14:34