feat: upgrade Keycloak to version 20
This commit is contained in:
parent
cc182d932b
commit
7d029b2a9e
|
@ -2,7 +2,7 @@ export const environment = {
|
|||
production: true,
|
||||
|
||||
// keycloak
|
||||
keycloakURL: 'http://localhost:8888/auth',
|
||||
keycloakURL: 'http://localhost:8080/auth',
|
||||
keycloakrealm: 'c4po_realm_local',
|
||||
keycloakclientId: 'c4po_local',
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ export const environment = {
|
|||
production: false,
|
||||
|
||||
// keycloak
|
||||
keycloakURL: 'http://localhost:8888/auth',
|
||||
keycloakURL: 'http://localhost:8080/auth',
|
||||
keycloakrealm: 'c4po_realm_local',
|
||||
keycloakclientId: 'c4po_local',
|
||||
|
||||
|
|
|
@ -91,6 +91,7 @@ dependencies {
|
|||
testImplementation("org.springframework.restdocs:spring-restdocs-webtestclient")
|
||||
testImplementation("com.github.spotbugs:spotbugs-annotations:4.1.2")
|
||||
testApi("org.testcontainers:junit-jupiter:1.15.2")
|
||||
testImplementation("com.github.dasniko:testcontainers-keycloak:2.3.0")
|
||||
}
|
||||
|
||||
jacoco {
|
||||
|
|
|
@ -175,12 +175,12 @@
|
|||
"method": "GET",
|
||||
"header": [],
|
||||
"url": {
|
||||
"raw": "http://localhost:8888/auth/realms/c4po_realm_local/.well-known/openid-configuration",
|
||||
"raw": "http://localhost:8080/auth/realms/c4po_realm_local/.well-known/openid-configuration",
|
||||
"protocol": "http",
|
||||
"host": [
|
||||
"localhost"
|
||||
],
|
||||
"port": "8888",
|
||||
"port": "8080",
|
||||
"path": [
|
||||
"auth",
|
||||
"realms",
|
||||
|
@ -235,12 +235,12 @@
|
|||
]
|
||||
},
|
||||
"url": {
|
||||
"raw": "http://localhost:8888/auth/realms/c4po_realm_local/protocol/openid-connect/token",
|
||||
"raw": "http://localhost:8080/auth/realms/c4po_realm_local/protocol/openid-connect/token",
|
||||
"protocol": "http",
|
||||
"host": [
|
||||
"localhost"
|
||||
],
|
||||
"port": "8888",
|
||||
"port": "8080",
|
||||
"path": [
|
||||
"auth",
|
||||
"realms",
|
||||
|
@ -837,4 +837,4 @@
|
|||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,4 +6,4 @@ keycloak.client.realm.path=auth/realms/c4po_realm_local/
|
|||
|
||||
## Database (MONGODB) Config ##
|
||||
spring.data.mongodb.host=c4po-db
|
||||
spring.data.mongodb.port=27017
|
||||
spring.data.mongodb.port=27017
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
## IdentityProvider (Keycloak) ##
|
||||
spring.security.oauth2.resourceserver.jwt.issuer-uri=http://localhost:8888/auth/realms/c4po_realm_local
|
||||
spring.security.oauth2.resourceserver.jwt.issuer-uri=http://localhost:8080/auth/realms/c4po_realm_local
|
||||
keycloakhost=localhost
|
||||
keycloak.client.url=http://localhost:8888/
|
||||
keycloak.client.url=http://localhost:8080/
|
||||
|
||||
## Database (MONGODB) Config ##
|
||||
spring.data.mongodb.host=localhost
|
||||
spring.data.mongodb.port=27017
|
||||
spring.data.mongodb.port=27017
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
## IdentityProvider (Keycloak) ##
|
||||
spring.security.oauth2.resourceserver.jwt.issuer-uri=http://localhost:9999/auth/realms/c4po_realm_local
|
||||
keycloakhost=localhost
|
||||
keycloak.client.url=http://localhost:9999
|
||||
keycloak.client.realm.path=auth/realms/c4po_realm_local/
|
||||
|
||||
## Database (MONGODB) Config ##
|
||||
spring.data.mongodb.host=localhost
|
||||
spring.data.mongodb.port=27021
|
||||
spring.data.mongodb.port=27021
|
||||
|
|
|
@ -16,11 +16,11 @@ spring.data.mongodb.database=c4po
|
|||
spring.data.mongodb.auto-index-creation=true
|
||||
|
||||
## IdentityProvider (Keycloak) ##
|
||||
spring.security.oauth2.resourceserver.jwt.issuer-uri=http://localhost:8888/auth/realms/c4po_realm_local
|
||||
spring.security.oauth2.resourceserver.jwt.issuer-uri=http://localhost:8080/auth/realms/c4po_realm_local
|
||||
keycloakhost=localhost
|
||||
keycloak.client.url=http://localhost:8888
|
||||
keycloak.client.url=http://localhost:8080
|
||||
keycloak.client.realm.path=auth/realms/c4po_realm_local/
|
||||
|
||||
## Total number of pentests listet in the OWASP testing guide
|
||||
## https://owasp.org/www-project-web-security-testing-guide/assets/archive/OWASP_Testing_Guide_v4.pdf
|
||||
owasp.web.pentests=95
|
||||
owasp.web.pentests=95
|
||||
|
|
|
@ -5,46 +5,48 @@ import com.github.dockerjava.api.model.ExposedPort
|
|||
import com.github.dockerjava.api.model.PortBinding
|
||||
import com.github.dockerjava.api.model.Ports
|
||||
import com.nimbusds.jwt.JWTParser
|
||||
import dasniko.testcontainers.keycloak.KeycloakContainer
|
||||
import org.junit.jupiter.api.TestInstance
|
||||
import org.springframework.beans.factory.annotation.Value
|
||||
import org.springframework.cloud.contract.wiremock.AutoConfigureWireMock
|
||||
import org.springframework.http.HttpEntity
|
||||
import org.springframework.http.HttpHeaders
|
||||
import org.springframework.http.MediaType
|
||||
import org.springframework.test.context.ActiveProfiles
|
||||
import org.springframework.test.context.DynamicPropertyRegistry
|
||||
import org.springframework.test.context.DynamicPropertySource
|
||||
import org.springframework.test.context.TestPropertySource
|
||||
import org.springframework.util.LinkedMultiValueMap
|
||||
import org.springframework.web.client.RestTemplate
|
||||
import org.testcontainers.shaded.com.fasterxml.jackson.databind.ObjectMapper
|
||||
import org.testcontainers.containers.GenericContainer
|
||||
import org.testcontainers.containers.wait.strategy.Wait
|
||||
import org.testcontainers.images.builder.ImageFromDockerfile
|
||||
import org.testcontainers.shaded.com.fasterxml.jackson.databind.ObjectMapper
|
||||
import org.testcontainers.utility.DockerImageName
|
||||
import org.testcontainers.utility.MountableFile
|
||||
import java.nio.file.Paths
|
||||
|
||||
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
||||
@AutoConfigureWireMock(port = 0)
|
||||
@TestPropertySource(properties = [
|
||||
"spring.data.mongodb.port=27017",
|
||||
"spring.data.mongodb.authentication-database=admin",
|
||||
"spring.data.mongodb.password=test",
|
||||
"spring.data.mongodb.username=testuser",
|
||||
"MONGO_DB_MAX_CONNECTION_IDLE_TIME=PT25M",
|
||||
"DATA_REFRESH_THRESHOLD_DURATION=PT30M",
|
||||
"CLEANUP_BATCH_SIZE_FOR_SELECTING_EXPIRED_USERS=100"
|
||||
])
|
||||
@TestPropertySource(
|
||||
properties = [
|
||||
"spring.data.mongodb.port=27017",
|
||||
"spring.data.mongodb.authentication-database=admin",
|
||||
"spring.data.mongodb.password=test",
|
||||
"spring.data.mongodb.username=testuser",
|
||||
"MONGO_DB_MAX_CONNECTION_IDLE_TIME=PT25M",
|
||||
"DATA_REFRESH_THRESHOLD_DURATION=PT30M",
|
||||
"CLEANUP_BATCH_SIZE_FOR_SELECTING_EXPIRED_USERS=100"
|
||||
]
|
||||
)
|
||||
abstract class BaseContainerizedTest {
|
||||
@Value("\${keycloakhost}")
|
||||
var keycloakhost: String? = null
|
||||
|
||||
companion object {
|
||||
val mongoDbContainer = KGenericContainer(ImageFromDockerfile("c4poapibasecontainerizedtest").withDockerfileFromBuilder {
|
||||
it.from("mongo:4.4.6")
|
||||
it.env("MONGO_INITDB_ROOT_USERNAME", "root")
|
||||
it.env("MONGO_INITDB_ROOT_PASSWORD", "cjwkbencowepoc324pon2mop3mp4")
|
||||
it.env("MONGO_INITDB_DATABASE", "admin")
|
||||
it.add("insert-mongodb-user.js", "/docker-entrypoint-initdb.d")
|
||||
}.withFileFromPath("insert-mongodb-user.js", Paths.get(MountableFile.forClasspathResource("insert-mongodb-user.js", 700).resolvedPath))
|
||||
val mongoDbContainer = KGenericContainer(
|
||||
ImageFromDockerfile("c4poapibasecontainerizedtest").withDockerfileFromBuilder {
|
||||
it.from("mongo:latest")
|
||||
it.env("MONGO_INITDB_ROOT_USERNAME", "root")
|
||||
it.env("MONGO_INITDB_ROOT_PASSWORD", "cjwkbencowepoc324pon2mop3mp4")
|
||||
it.env("MONGO_INITDB_DATABASE", "admin")
|
||||
it.add("insert-mongodb-user.js", "/docker-entrypoint-initdb.d")
|
||||
}.withFileFromPath("insert-mongodb-user.js", Paths.get(MountableFile.forClasspathResource("insert-mongodb-user.js", 700).resolvedPath))
|
||||
).apply {
|
||||
withCreateContainerCmdModifier {
|
||||
it.hostConfig?.withPortBindings(PortBinding(Ports.Binding.bindPort(27017), ExposedPort(27017)))
|
||||
|
@ -52,28 +54,29 @@ abstract class BaseContainerizedTest {
|
|||
start()
|
||||
}
|
||||
|
||||
val keycloakContainer = KGenericContainerFromImage(DockerImageName.parse("jboss/keycloak:11.0.3")).apply {
|
||||
withEnv("KEYCLOAK_USER", "admin")
|
||||
withEnv("KEYCLOAK_PASSWORD", "admin")
|
||||
withEnv("KEYCLOAK_IMPORT", "/tmp/realm.json")
|
||||
withEnv("DB_VENDOR", "h2")
|
||||
withCreateContainerCmdModifier {
|
||||
it.hostConfig?.withPortBindings(PortBinding(Ports.Binding.bindPort(8888), ExposedPort(8080)))
|
||||
}
|
||||
withCopyFileToContainer(MountableFile.forClasspathResource("realm-export.json", 700), "/tmp/realm.json")
|
||||
start()
|
||||
println("== Inserting users must wait until Keycloak is started completely ==")
|
||||
execInContainer("sh", "/opt/jboss/create-keycloak-user.sh")
|
||||
val keycloakContainer: KeycloakContainer = KeycloakContainer("quay.io/keycloak/keycloak:20.0.0")
|
||||
.withAdminUsername("admin")
|
||||
.withAdminPassword("admin")
|
||||
.withContextPath("/auth")
|
||||
.withRealmImportFile("realm-export.json")
|
||||
.waitingFor(
|
||||
Wait.forHttp("/auth")
|
||||
)
|
||||
|
||||
@DynamicPropertySource
|
||||
@JvmStatic
|
||||
fun jwtValidationProperties(registry: DynamicPropertyRegistry) {
|
||||
registry.add("spring.security.oauth2.resourceserver.jwt.issuer-uri") { keycloakContainer.authServerUrl + "/realms/c4po_realm_local" }
|
||||
|
||||
keycloakContainer.start()
|
||||
}
|
||||
}
|
||||
|
||||
var token = "n/a"
|
||||
var tokenAdmin = "n/a"
|
||||
var tokenUser = "n/a"
|
||||
var keycloakHost: String? = null
|
||||
|
||||
fun getAccessToken(username: String, password: String, clientId: String, realm: String): String {
|
||||
keycloakHost = "http://" + keycloakhost + ":" + keycloakContainer.getMappedPort(8080)
|
||||
val restTemplate = RestTemplate()
|
||||
val headers = HttpHeaders()
|
||||
headers.contentType = MediaType.APPLICATION_FORM_URLENCODED
|
||||
|
@ -84,8 +87,11 @@ abstract class BaseContainerizedTest {
|
|||
map.add("password", password)
|
||||
map.add("grant_type", "password")
|
||||
map.add("client_secret", "secret")
|
||||
val responseString = restTemplate.postForObject("$keycloakHost/auth/realms/$realm/protocol/openid-connect/token",
|
||||
HttpEntity<Any>(map, headers), String::class.java)
|
||||
val responseString = restTemplate.postForObject(
|
||||
keycloakContainer.authServerUrl + "/realms/$realm/protocol/openid-connect/token",
|
||||
HttpEntity<Any>(map, headers),
|
||||
String::class.java
|
||||
)
|
||||
val token = ObjectMapper().readValue(responseString, KeyCloakToken::class.java)
|
||||
return token.access_token!!
|
||||
}
|
||||
|
@ -101,4 +107,4 @@ abstract class BaseContainerizedTest {
|
|||
|
||||
class KGenericContainerFromImage(imageName: DockerImageName) : GenericContainer<KGenericContainerFromImage>(imageName)
|
||||
class KGenericContainer(dockerFile: ImageFromDockerfile) : GenericContainer<KGenericContainer>(dockerFile)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#!/usr/bin/env bash
|
||||
cd keycloak/bin
|
||||
sleep 20
|
||||
./kcadm.sh config credentials --server http://localhost:8888/auth --realm master --user admin --password admin
|
||||
./kcadm.sh config credentials --server http://localhost:8080/auth --realm master --user admin --password admin
|
||||
|
||||
USERID=$(./kcadm.sh create users -r c4po_realm_local -s username=test_admin \
|
||||
-s email=testadmin@test.de \
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
# cfg for local keycloak
|
||||
DB_VENDOR=postgres
|
||||
DB_ADDR=c4po-keycloak-postgress
|
||||
DB_PORT=5432
|
||||
DB_USER=c4po_kc_local
|
||||
DB_PASSWORD=Test1234!
|
||||
KEYCLOAK_USER=admin
|
||||
KEYCLOAK_PASSWORD=admin
|
||||
KEYCLOAK_IMPORT=/tmp/c4po_realm_export.json
|
|
@ -1,4 +0,0 @@
|
|||
# database.env
|
||||
POSTGRES_USER=c4po_kc_local
|
||||
POSTGRES_PASSWORD=Test1234!
|
||||
POSTGRES_DB=keycloak
|
|
@ -5,23 +5,11 @@ volumes:
|
|||
c4po-db:
|
||||
|
||||
services:
|
||||
# Database
|
||||
c4po-keycloak-postgres:
|
||||
container_name: c4po-keycloak-postgres
|
||||
image: postgres:latest
|
||||
env_file:
|
||||
- cfg/keycloakdb.env
|
||||
ports:
|
||||
- 5433:5432
|
||||
volumes:
|
||||
- /volumes/keycloak/data/:/var/lib/postgres/data
|
||||
networks:
|
||||
- c4po
|
||||
c4po-db:
|
||||
image: mongo:latest
|
||||
container_name: c4po-db
|
||||
volumes:
|
||||
- /volumes/mongodb/data/:/db/data
|
||||
- ./volumes/mongodb/data/:/db/data
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
|
@ -30,20 +18,15 @@ services:
|
|||
- 27017:27017
|
||||
networks:
|
||||
- c4po
|
||||
# Authentity Provider
|
||||
# Authentication Provider
|
||||
c4po-keycloak:
|
||||
container_name: c4po-keycloak
|
||||
depends_on:
|
||||
- c4po-keycloak-postgres
|
||||
links:
|
||||
- c4po-keycloak-postgres
|
||||
image: jboss/keycloak:11.0.3
|
||||
image: quay.io/keycloak/keycloak:20.0.0
|
||||
volumes:
|
||||
- /cfg/c4po_realm_export.json/:/tmp/c4po_realm_export.json
|
||||
- ./cfg/c4po_realm_export.json/:/opt/keycloak/data/import/c4po_realm_export.json
|
||||
ports:
|
||||
- 8888:8080
|
||||
env_file:
|
||||
- cfg/keycloak.env
|
||||
- 8080:8080
|
||||
entrypoint: /opt/keycloak/bin/kc.sh start-dev --import-realm --http-relative-path=/auth
|
||||
networks:
|
||||
- c4po
|
||||
# Services
|
||||
|
@ -53,8 +36,6 @@ services:
|
|||
container_name: c4po-angular
|
||||
depends_on:
|
||||
- c4po-keycloak
|
||||
links:
|
||||
- c4po-keycloak
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
|
@ -63,7 +44,6 @@ services:
|
|||
- 4200:4200
|
||||
networks:
|
||||
- c4po
|
||||
|
||||
c4po-api:
|
||||
build: '../security-c4po-api'
|
||||
image: security-c4po-api:latest
|
||||
|
@ -73,9 +53,6 @@ services:
|
|||
depends_on:
|
||||
- c4po-db
|
||||
- c4po-keycloak
|
||||
links:
|
||||
- c4po-db
|
||||
- c4po-keycloak
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
|
|
Loading…
Reference in New Issue