Skip to content

Commit

Permalink
Allows to set public url
Browse files Browse the repository at this point in the history
  • Loading branch information
fkneier-bikeleasing committed May 22, 2024
1 parent eabd784 commit de557ed
Show file tree
Hide file tree
Showing 8 changed files with 66 additions and 21 deletions.
6 changes: 3 additions & 3 deletions src/main/kotlin/de/solugo/oidc/ConfigurationProvider.kt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package de.solugo.oidc

import org.springframework.web.util.UriComponentsBuilder
import org.springframework.web.server.ServerWebExchange

interface ConfigurationProvider {
fun provide(builder: UriComponentsBuilder): Map<String, Any>
}
fun provide(exchange: ServerWebExchange): Map<String, Any>
}
10 changes: 9 additions & 1 deletion src/main/kotlin/de/solugo/oidc/ServerProperties.kt
Original file line number Diff line number Diff line change
@@ -1,8 +1,16 @@
package de.solugo.oidc

import de.solugo.oidc.util.uri
import org.springframework.boot.context.properties.ConfigurationProperties
import org.springframework.web.server.ServerWebExchange
import org.springframework.web.util.UriComponentsBuilder

@ConfigurationProperties("server")
data class ServerProperties(
val publicUrl: String? = null,
val claims: Map<String, Any?> = emptyMap(),
)
) {
fun ServerWebExchange.issuerUri(
block: UriComponentsBuilder.() -> Unit,
) = uri(publicUrl ?: request.uri.toString(), block)
}
Original file line number Diff line number Diff line change
@@ -1,21 +1,28 @@
package de.solugo.oidc.controller

import de.solugo.oidc.ConfigurationProvider
import de.solugo.oidc.ServerProperties
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RestController
import org.springframework.web.util.UriComponentsBuilder
import org.springframework.web.server.ServerWebExchange

@RestController
class ConfigurationController(
private val configurationProviders: List<ConfigurationProvider>,
private val properties: ServerProperties,
) {

@GetMapping(".well-known/openid-configuration")
fun configuration(builder: UriComponentsBuilder) = buildMap {
put("issuer", builder.replacePath("/").toUriString())
configurationProviders.forEach {
putAll(it.provide(builder))
fun configuration(exchange: ServerWebExchange) = with(properties) {
buildMap {
put("issuer", exchange.issuerUri {
replacePath("/")
})
configurationProviders.forEach {
putAll(it.provide(exchange))
}
}
}

}

}
16 changes: 11 additions & 5 deletions src/main/kotlin/de/solugo/oidc/controller/KeySetController.kt
Original file line number Diff line number Diff line change
@@ -1,22 +1,28 @@
package de.solugo.oidc.controller

import de.solugo.oidc.ConfigurationProvider
import de.solugo.oidc.ServerProperties
import de.solugo.oidc.service.KeySetService
import org.jose4j.jwk.JsonWebKey
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RestController
import org.springframework.web.util.UriComponentsBuilder
import org.springframework.web.server.ServerWebExchange

@RestController
@ConditionalOnBean(KeySetService::class)
class KeySetController(
private val keySetService: KeySetService,
private val properties: ServerProperties,
) : ConfigurationProvider {

override fun provide(builder: UriComponentsBuilder) = mapOf(
"jwks_uri" to builder.replacePath(".well-known/jwks.json").toUriString(),
)
override fun provide(exchange: ServerWebExchange) = with(properties) {
mapOf(
"jwks_uri" to exchange.issuerUri {
replacePath("/.well-known/jwks.json")
},
)
}

@GetMapping(".well-known/jwks.json")
fun getJwks() = mapOf(
Expand All @@ -25,4 +31,4 @@ class KeySetController(
}
)

}
}
14 changes: 10 additions & 4 deletions src/main/kotlin/de/solugo/oidc/controller/TokenController.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package de.solugo.oidc.controller


import de.solugo.oidc.ConfigurationProvider
import de.solugo.oidc.ServerProperties
import de.solugo.oidc.service.TokenService
import de.solugo.oidc.token.*
import de.solugo.oidc.util.plus
Expand All @@ -23,13 +24,18 @@ class TokenController(
private val grants: List<TokenGrant>,
private val tokenService: TokenService,
private val tokenProcessors: List<TokenProcessor>,
private val properties: ServerProperties,
) : ConfigurationProvider {

private val logger = LoggerFactory.getLogger(javaClass)

override fun provide(builder: UriComponentsBuilder) = mapOf(
"token_endpoint" to builder.replacePath("/token").toUriString(),
)
override fun provide(exchange: ServerWebExchange) = with(properties) {
mapOf(
"token_endpoint" to exchange.issuerUri {
replacePath("/token")
}
)
}

@PostMapping("/token", consumes = [MediaType.APPLICATION_FORM_URLENCODED_VALUE])
suspend fun createToken(
Expand Down Expand Up @@ -126,4 +132,4 @@ class TokenController(
}
}

}
}
5 changes: 5 additions & 0 deletions src/main/kotlin/de/solugo/oidc/util/Util.kt
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
package de.solugo.oidc.util

import org.springframework.web.util.UriComponentsBuilder
import java.util.*

fun uuid(value: String? = null) = when {
value != null -> UUID.nameUUIDFromBytes(value.toByteArray()).toString()
else -> UUID.randomUUID().toString()
}

fun uri(uri: String, block: UriComponentsBuilder.() -> Unit) = UriComponentsBuilder.fromUriString(uri).run {
block()
toUriString()
}
4 changes: 3 additions & 1 deletion src/test/kotlin/IntegrationTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,10 @@ abstract class IntegrationTest {
companion object {
@JvmStatic
@DynamicPropertySource
@Suppress("unused")
fun configure(registry: DynamicPropertyRegistry) {
registry.add("server.publicUrl") { "https://my_issuer" }
}
}

}
}
13 changes: 12 additions & 1 deletion src/test/kotlin/de/solugo/oidc/controller/TokenControllerTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,17 @@ import org.junit.jupiter.api.Test

class TokenControllerTest : IntegrationTest() {

@Test
fun `Get openid configuration`() = runTest {
rest.get(".well-known/openid-configuration").apply {
status shouldBe HttpStatusCode.OK
body<ObjectNode>().apply {
at("/issuer").textValue() shouldBe "https://my_issuer/"
}
}
}


@Test
fun `Create token using password grant`() = runTest {
val parameters = parametersOf(
Expand Down Expand Up @@ -93,4 +104,4 @@ class TokenControllerTest : IntegrationTest() {
}
}
}
}
}

0 comments on commit de557ed

Please sign in to comment.