From 17e04a3f8972fe5eca0bf3b236293e4a6998e56f Mon Sep 17 00:00:00 2001 From: Paul-Christian Volkmer Date: Wed, 31 Jan 2024 15:43:10 +0100 Subject: [PATCH] feat: add basic support for OIDC login --- build.gradle.kts | 1 + .../processor/config/AppConfigProperties.kt | 3 +- .../config/AppSecurityConfiguration.kt | 30 +++++++++++++++---- .../dnpm/etl/processor/web/LoginController.kt | 19 ++++++++++-- src/main/resources/static/style.css | 7 +++++ src/main/resources/templates/fragments.html | 5 ++++ src/main/resources/templates/login.html | 6 ++-- 7 files changed, 60 insertions(+), 11 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 8a66f5d..ea727c4 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -58,6 +58,7 @@ dependencies { implementation("org.springframework.boot:spring-boot-starter-web") implementation("org.springframework.boot:spring-boot-starter-data-jdbc") implementation("org.springframework.boot:spring-boot-starter-security") + implementation("org.springframework.boot:spring-boot-starter-oauth2-client") implementation("org.thymeleaf.extras:thymeleaf-extras-springsecurity6") implementation("com.fasterxml.jackson.module:jackson-module-kotlin") implementation("org.springframework.kafka:spring-kafka") diff --git a/src/main/kotlin/dev/dnpm/etl/processor/config/AppConfigProperties.kt b/src/main/kotlin/dev/dnpm/etl/processor/config/AppConfigProperties.kt index aacf97d..b18bc02 100644 --- a/src/main/kotlin/dev/dnpm/etl/processor/config/AppConfigProperties.kt +++ b/src/main/kotlin/dev/dnpm/etl/processor/config/AppConfigProperties.kt @@ -86,7 +86,8 @@ data class KafkaTargetProperties( data class SecurityConfigProperties( val adminUser: String?, val adminPassword: String?, - val enableTokens: Boolean = false + val enableTokens: Boolean = false, + val enableOidc: Boolean = false ) { companion object { const val NAME = "app.security" diff --git a/src/main/kotlin/dev/dnpm/etl/processor/config/AppSecurityConfiguration.kt b/src/main/kotlin/dev/dnpm/etl/processor/config/AppSecurityConfiguration.kt index 22a2e34..750ccbc 100644 --- a/src/main/kotlin/dev/dnpm/etl/processor/config/AppSecurityConfiguration.kt +++ b/src/main/kotlin/dev/dnpm/etl/processor/config/AppSecurityConfiguration.kt @@ -24,21 +24,15 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty import org.springframework.boot.context.properties.EnableConfigurationProperties import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration -import org.springframework.core.Ordered -import org.springframework.core.annotation.Order -import org.springframework.http.HttpMethod -import org.springframework.security.authentication.AuthenticationProvider 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.invoke -import org.springframework.security.config.http.SessionCreationPolicy import org.springframework.security.core.userdetails.User import org.springframework.security.core.userdetails.UserDetails import org.springframework.security.crypto.factory.PasswordEncoderFactories import org.springframework.security.crypto.password.PasswordEncoder import org.springframework.security.provisioning.InMemoryUserDetailsManager import org.springframework.security.web.SecurityFilterChain -import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy import java.util.* @@ -82,6 +76,30 @@ class AppSecurityConfiguration( } @Bean + @ConditionalOnProperty(value = ["app.security.enable-oidc"], havingValue = "true") + fun filterChainOidc(http: HttpSecurity, passwordEncoder: PasswordEncoder): SecurityFilterChain { + http { + authorizeRequests { + authorize("/configs/**", hasRole("ADMIN")) + authorize("/mtbfile/**", hasAnyRole("MTBFILE")) + authorize(anyRequest, permitAll) + } + httpBasic { + realmName = "ETL-Processor" + } + formLogin { + loginPage = "/login" + } + oauth2Login { + loginPage = "/login" + } + csrf { disable() } + } + return http.build() + } + + @Bean + @ConditionalOnProperty(value = ["app.security.enable-oidc"], havingValue = "false", matchIfMissing = true) fun filterChain(http: HttpSecurity, passwordEncoder: PasswordEncoder): SecurityFilterChain { http { authorizeRequests { diff --git a/src/main/kotlin/dev/dnpm/etl/processor/web/LoginController.kt b/src/main/kotlin/dev/dnpm/etl/processor/web/LoginController.kt index 02c98cf..954b23e 100644 --- a/src/main/kotlin/dev/dnpm/etl/processor/web/LoginController.kt +++ b/src/main/kotlin/dev/dnpm/etl/processor/web/LoginController.kt @@ -19,14 +19,29 @@ package dev.dnpm.etl.processor.web +import dev.dnpm.etl.processor.config.SecurityConfigProperties +import org.springframework.boot.autoconfigure.security.oauth2.client.OAuth2ClientProperties import org.springframework.stereotype.Controller +import org.springframework.ui.Model import org.springframework.web.bind.annotation.GetMapping +import java.security.Principal @Controller -class LoginController { +class LoginController( + private val securityConfigProperties: SecurityConfigProperties, + private val oAuth2ClientProperties: OAuth2ClientProperties? +) { @GetMapping(path = ["/login"]) - fun login(): String { + fun login(principal: Principal?, model: Model): String { + if (securityConfigProperties.enableOidc) { + model.addAttribute( + "oidcLogins", + oAuth2ClientProperties?.registration?.map { (key, value) -> Pair(key, value.clientName) }.orEmpty() + ) + } else { + model.addAttribute("oidcLogins", emptyList>()) + } return "login" } diff --git a/src/main/resources/static/style.css b/src/main/resources/static/style.css index 3249aad..c7a0b38 100644 --- a/src/main/resources/static/style.css +++ b/src/main/resources/static/style.css @@ -209,7 +209,14 @@ form.samplecode-input input:focus-visible { border-radius: 3px; } +.login-form form hr, +.token-form form hr { + padding: 0; + width: 100%; +} + .login-form button, +.login-form a.btn, .token-form button { margin: 1em 0; background: var(--bg-blue); diff --git a/src/main/resources/templates/fragments.html b/src/main/resources/templates/fragments.html index 7a9af2f..bfa36a2 100644 --- a/src/main/resources/templates/fragments.html +++ b/src/main/resources/templates/fragments.html @@ -21,6 +21,11 @@ Login diff --git a/src/main/resources/templates/login.html b/src/main/resources/templates/login.html index 9a63b46..4ef8ec9 100644 --- a/src/main/resources/templates/login.html +++ b/src/main/resources/templates/login.html @@ -13,9 +13,11 @@
Anmeldung nicht erfolgreich
Sie haben sich abgemeldet
- - + + +
+ OIDC Login - [[ ${oidcLogin.component2()} ]]