mirror of
https://github.com/pcvolkmer/etl-processor.git
synced 2025-04-19 17:26:51 +00:00
feat: add basic support for OIDC login
This commit is contained in:
parent
f71a775e12
commit
17e04a3f89
@ -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")
|
||||
|
@ -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"
|
||||
|
@ -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 {
|
||||
|
@ -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<Pair<String, String>>())
|
||||
}
|
||||
return "login"
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -21,6 +21,11 @@
|
||||
<a th:href="@{/login}">Login</a>
|
||||
</li>
|
||||
<li class="login" sec:authorize="isAuthenticated()">
|
||||
<span>
|
||||
<span>👤</span>
|
||||
<span sec:authentication="name">?</span>
|
||||
</span>
|
||||
|
||||
<a th:href="@{/logout}">Abmelden</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
@ -13,9 +13,11 @@
|
||||
<div class="centered notification error" th:if="${param.error}">Anmeldung nicht erfolgreich</div>
|
||||
<div class="centered notification success" th:if="${param.logout}">Sie haben sich abgemeldet</div>
|
||||
<form method="post" th:action="@{/login}">
|
||||
<input type="text" id="username" name="username" class="form-control" placeholder="Username" required="" autofocus="">
|
||||
<input type="password" id="password" name="password" class="form-control" placeholder="Password" required="">
|
||||
<input type="text" id="username" name="username" class="form-control" placeholder="Username" required="" autofocus="" />
|
||||
<input type="password" id="password" name="password" class="form-control" placeholder="Password" required="" />
|
||||
<button type="submit">Anmelden</button>
|
||||
<hr th:if="${not oidcLogins.isEmpty()}" />
|
||||
<a th:each="oidcLogin : ${oidcLogins}" class="btn" th:href="@{/oauth2/authorization/{provider}(provider=${oidcLogin.component1()})}">OIDC Login - [[ ${oidcLogin.component2()} ]]</a>
|
||||
</form>
|
||||
</div>
|
||||
</main>
|
||||
|
Loading…
x
Reference in New Issue
Block a user