I have oauth2 auth server and a resource server. Resource server is only validating request with auth server once

58 views Asked by At

auth server configuration

@EnableWebSecurity
@Configuration
class WebSecurityConfig {

    @Bean
    fun securityFilterChain(http: HttpSecurity): SecurityFilterChain {
        http
            .cors { cors -> cors.disable() }
            .csrf { csrf -> csrf.disable() }
            .authorizeRequests().anyRequest().authenticated()
        http.formLogin()
        return http.build()
    }

    @Bean
    fun passwordEncoder() = BCryptPasswordEncoder()

}

@Configuration
class AuthServerConfig {

    @Bean
    @Order(Ordered.HIGHEST_PRECEDENCE)
    fun clientSecurityFilterChain(http: HttpSecurity): SecurityFilterChain? {
        OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http)
        return http.formLogin().and().build()
    }

    @Bean
    fun providerSettings(): ProviderSettings = ProviderSettings
        .builder()
        .issuer("http://localhost:8283")
        .build()

    @Bean
    fun jwkSource(): JWKSource<SecurityContext> {
        val rsaKey = generateRsaKey()
        val set = JWKSet(rsaKey)
        return JWKSource { selector: JWKSelector, _: SecurityContext? ->
            selector.select(set)
        }
    }

    private fun generateRsaKey(): RSAKey {
        val keyPair = KeyPairGenerator.getInstance("RSA")
        keyPair.initialize(2048)
        val keys = keyPair.generateKeyPair()
        return try {
            RSAKey.Builder(keys.public as RSAPublicKey).privateKey(keys.private)
                .keyID(UUID.randomUUID().toString()).build()
        } catch (e: NoSuchAlgorithmException) {
            throw RuntimeException("Error while generating rsa keys")
        }
    }
}

UserdetailsService and RegisteredClientRepository

@Component
class CustomUserDetailsService(
    private val authUserRepository: AuthUserRepository
) : UserDetailsService {

    override fun loadUserByUsername(username: String) = authUserRepository.findByEmailAndDeletedFalse(username)

}

@Component
class CustomRegisteredClientRepository(
    private val clientRepository: ClientRepository,
    private val encoder: BCryptPasswordEncoder
) : RegisteredClientRepository {

    override fun save(registeredClient: RegisteredClient?) {
        registeredClient?.run {
            val client = CustomRegisteredClient(
                clientId,
                clientIdIssuedAt?.toEpochMilli(),
                encoder.encode(clientSecret),
                clientSecretExpiresAt?.toEpochMilli(),
                clientName,
                clientAuthenticationMethods.map { it.value },
                authorizationGrantTypes.map { it.value },
                redirectUris.toList(),
                scopes.toList(),
                clientSettings.isRequireAuthorizationConsent,
                tokenSettings.accessTokenTimeToLive,
                tokenSettings.refreshTokenTimeToLive
            )
            clientRepository.save(client)
        }

    }

    override fun findById(id: String?): RegisteredClient? {
        id?.let {
            val client = clientRepository.findById(it)
            if (client.isPresent) return client.get().toRegisteredClient()
        }
        return null
    }

    override fun findByClientId(clientId: String?): RegisteredClient? {
        clientId?.let {
            val client = clientRepository.findByClientId(clientId)
            return client?.toRegisteredClient()
        }
        return null
    }
}

// initilizing user and client, saving user and client to mongodb

@Component
class ContextRefreshEvent(
    private val clientRepository: ClientRepository,
    private val passwordEncoder: BCryptPasswordEncoder,
    private val userRepository: AuthUserRepository
) {

    @EventListener(ContextRefreshedEvent::class)
    fun contextRefreshedEvent() {
        if (clientRepository.findByClientName("demo") == null) {
            val client = CustomRegisteredClient(
                "demo",
                Date().time,
                passwordEncoder.encode("12345"),
                Date().time.plus(3600),
                "demo",
                listOf(ClientAuthenticationMethod.CLIENT_SECRET_BASIC.value),
                listOf(AuthorizationGrantType.AUTHORIZATION_CODE.value, AuthorizationGrantType.REFRESH_TOKEN.value),
                listOf("http://127.0.0.1:3000/authorized"),
                listOf(OidcScopes.OPENID),
                true,
                Duration.ofHours(1),
                Duration.ofHours(3),
            )
            clientRepository.save(client)
            println("====== auth client initialized =====")
        }
        if (userRepository.findByEmailAndDeletedFalse("botir") == null) {
            val user = AuthUser(
                "minfin",
                passwordEncoder.encode("12345"),
                "botir",
                true,
                UserRole.ADMIN
            )
            userRepository.save(user)
            println("User initialized")
        }

    }
}

Client app security configuration

@Configuration
class WebSecurityConfig {

    @Bean
    fun filterChain(http: HttpSecurity): SecurityFilterChain {
        http
            .cors { cors -> cors.disable() }
            .csrf { csrf -> csrf.disable() }
            .sessionManagement { session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS) }
            .oauth2ResourceServer { server ->
                server.jwt().jwkSetUri("http://localhost:8283/oauth2/jwks")
            }
            .authorizeRequests { auth ->
                auth.anyRequest().authenticated()
            }
        return http.build()
    }
}


@RestController
class TestController {

    @GetMapping
    fun test() = "Test ..."
}

Is there any way to make the client app validates every request with auth server. Now it is only validating for the first time, and it is working even if I shoot down the auth server.

0

There are 0 answers