or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

authentication.mdindex.mdkotlin-dsl.mdmethod-security.mdoauth2.mdreactive-web-security.mdsaml2.mdservlet-web-security.md
tile.json

kotlin-dsl.mddocs/

Kotlin DSL

Type-safe Kotlin DSL for all Spring Security configuration options, providing idiomatic Kotlin syntax for security configuration.

Capabilities

Enabling Kotlin DSL

Import the invoke operator extension function to enable Kotlin DSL syntax.

import org.springframework.security.config.annotation.web.invoke

Servlet Security DSL (HttpSecurity)

Configure servlet-based security using Kotlin DSL.

// HttpSecurity extension function
fun HttpSecurity.invoke(httpConfiguration: HttpSecurityDsl.() -> Unit): HttpSecurity

// Main DSL
class HttpSecurityDsl {
    fun authorizeHttpRequests(authorizeHttpRequestsConfig: AuthorizeHttpRequestsDsl.() -> Unit)
    fun formLogin(formLoginConfig: FormLoginDsl.() -> Unit)
    fun httpBasic(httpBasicConfig: HttpBasicDsl.() -> Unit)
    fun oauth2Login(oauth2LoginConfig: OAuth2LoginDsl.() -> Unit)
    fun oauth2Client(oauth2ClientConfig: OAuth2ClientDsl.() -> Unit)
    fun oauth2ResourceServer(oauth2ResourceServerConfig: OAuth2ResourceServerDsl.() -> Unit)
    fun saml2Login(saml2LoginConfig: Saml2Dsl.() -> Unit)
    fun saml2Logout(saml2LogoutConfig: Saml2LogoutDsl.() -> Unit)
    fun saml2Metadata(saml2MetadataConfig: Saml2MetadataDsl.() -> Unit)
    fun oidcLogout(oidcLogoutConfig: OidcLogoutDsl.() -> Unit)
    fun oneTimeTokenLogin(oneTimeTokenLoginConfig: OneTimeTokenLoginDsl.() -> Unit)
    fun rememberMe(rememberMeConfig: RememberMeDsl.() -> Unit)
    fun x509(x509Config: X509Dsl.() -> Unit)
    fun webAuthn(webAuthnConfig: WebAuthnDsl.() -> Unit)
    fun jee(jeeConfig: JeeDsl.() -> Unit)
    fun anonymous(anonymousConfig: AnonymousDsl.() -> Unit)
    fun logout(logoutConfig: LogoutDsl.() -> Unit)
    fun sessionManagement(sessionManagementConfig: SessionManagementDsl.() -> Unit)
    fun csrf(csrfConfig: CsrfDsl.() -> Unit)
    fun cors(corsConfig: CorsDsl.() -> Unit)
    fun headers(headersConfig: HeadersDsl.() -> Unit)
    fun exceptionHandling(exceptionHandlingConfig: ExceptionHandlingDsl.() -> Unit)
    fun requestCache(requestCacheConfig: RequestCacheDsl.() -> Unit)
    fun securityContext(securityContextConfig: SecurityContextDsl.() -> Unit)
    fun servletApi(servletApiConfig: ServletApiDsl.() -> Unit)
    fun portMapper(portMapperConfig: PortMapperDsl.() -> Unit)
    fun requiresChannel(requiresChannelConfig: RequiresChannelDsl.() -> Unit)
    fun httpsRedirect(httpsRedirectConfig: HttpsRedirectDsl.() -> Unit)
    fun passwordManagement(passwordManagementConfig: PasswordManagementDsl.() -> Unit)
}

Usage Example:

@Configuration
@EnableWebSecurity
class SecurityConfig {

    @Bean
    fun filterChain(http: HttpSecurity): SecurityFilterChain {
        http {
            authorizeHttpRequests {
                authorize("/public/**", permitAll)
                authorize("/admin/**", hasRole("ADMIN"))
                authorize("/api/**", hasAnyAuthority("READ", "WRITE"))
                authorize(anyRequest, authenticated)
            }
            formLogin {
                loginPage = "/login"
                defaultSuccessUrl("/dashboard", true)
                permitAll()
            }
            logout {
                logoutUrl = "/logout"
                logoutSuccessUrl = "/"
                invalidateHttpSession = true
                deleteCookies("JSESSIONID")
            }
            csrf {
                csrfTokenRepository = CookieCsrfTokenRepository.withHttpOnlyFalse()
            }
            sessionManagement {
                sessionCreationPolicy = SessionCreationPolicy.IF_REQUIRED
                sessionFixation {
                    changeSessionId()
                }
                sessionConcurrency {
                    maximumSessions = 1
                    maxSessionsPreventsLogin = true
                }
            }
            headers {
                contentSecurityPolicy {
                    policyDirectives = "default-src 'self'"
                }
                frameOptions {
                    sameOrigin()
                }
            }
        }
        return http.build()
    }
}

Authorization DSL

class AuthorizeHttpRequestsDsl {
    fun authorize(pattern: String, access: AuthorizationManager<RequestAuthorizationContext>)
    fun authorize(matcher: RequestMatcher, access: AuthorizationManager<RequestAuthorizationContext>)

    // Convenience constants
    val permitAll: AuthorizationManager<RequestAuthorizationContext>
    val denyAll: AuthorizationManager<RequestAuthorizationContext>
    val authenticated: AuthorizationManager<RequestAuthorizationContext>
    val anonymous: AuthorizationManager<RequestAuthorizationContext>
    val anyRequest: RequestMatcher

    // Convenience functions
    fun hasRole(role: String): AuthorizationManager<RequestAuthorizationContext>
    fun hasAnyRole(vararg roles: String): AuthorizationManager<RequestAuthorizationContext>
    fun hasAuthority(authority: String): AuthorizationManager<RequestAuthorizationContext>
    fun hasAnyAuthority(vararg authorities: String): AuthorizationManager<RequestAuthorizationContext>
}

Form Login DSL

class FormLoginDsl {
    var loginPage: String?
    var loginProcessingUrl: String?
    var usernameParameter: String?
    var passwordParameter: String?
    var failureUrl: String?
    var authenticationSuccessHandler: AuthenticationSuccessHandler?
    var authenticationFailureHandler: AuthenticationFailureHandler?

    fun defaultSuccessUrl(defaultSuccessUrl: String, alwaysUse: Boolean = false)
    fun permitAll()
}

OAuth2 Login DSL

class OAuth2LoginDsl {
    var loginPage: String?
    var clientRegistrationRepository: ClientRegistrationRepository?
    var authorizedClientRepository: OAuth2AuthorizedClientRepository?
    var authorizedClientService: OAuth2AuthorizedClientService?

    fun authorizationEndpoint(config: AuthorizationEndpointDsl.() -> Unit)
    fun tokenEndpoint(config: TokenEndpointDsl.() -> Unit)
    fun redirectionEndpoint(config: RedirectionEndpointDsl.() -> Unit)
    fun userInfoEndpoint(config: UserInfoEndpointDsl.() -> Unit)
}

OAuth2 Resource Server DSL

class OAuth2ResourceServerDsl {
    var authenticationEntryPoint: AuthenticationEntryPoint?
    var bearerTokenResolver: BearerTokenResolver?
    var accessDeniedHandler: AccessDeniedHandler?

    fun jwt(jwtConfig: JwtDsl.() -> Unit)
    fun opaqueToken(opaqueTokenConfig: OpaqueTokenDsl.() -> Unit)
}

class JwtDsl {
    var decoder: JwtDecoder?
    var jwkSetUri: String?
    var jwtAuthenticationConverter: Converter<Jwt, out AbstractAuthenticationToken>?
}

class OpaqueTokenDsl {
    var introspectionUri: String?
    var introspector: OpaqueTokenIntrospector?

    fun introspectionClientCredentials(clientId: String, clientSecret: String)
}

CSRF DSL

class CsrfDsl {
    var csrfTokenRepository: CsrfTokenRepository?
    var csrfTokenRequestHandler: CsrfTokenRequestHandler?
    var requireCsrfProtectionMatcher: RequestMatcher?

    fun disable()
    fun ignoringRequestMatchers(vararg requestMatchers: RequestMatcher)
    fun ignoringRequestMatchers(vararg patterns: String)
}

Session Management DSL

class SessionManagementDsl {
    var sessionCreationPolicy: SessionCreationPolicy?
    var invalidSessionUrl: String?
    var sessionAuthenticationErrorUrl: String?

    fun sessionFixation(config: SessionFixationDsl.() -> Unit)
    fun sessionConcurrency(config: SessionConcurrencyDsl.() -> Unit)
}

class SessionFixationDsl {
    fun newSession()
    fun migrateSession()
    fun changeSessionId()
    fun none()
}

class SessionConcurrencyDsl {
    var maximumSessions: Int?
    var maxSessionsPreventsLogin: Boolean?
    var expiredUrl: String?
    var sessionRegistry: SessionRegistry?
}

Headers DSL

class HeadersDsl {
    fun cacheControl(config: CacheControlDsl.() -> Unit)
    fun contentSecurityPolicy(config: ContentSecurityPolicyDsl.() -> Unit)
    fun contentTypeOptions(config: ContentTypeOptionsDsl.() -> Unit)
    fun frameOptions(config: FrameOptionsDsl.() -> Unit)
    fun httpStrictTransportSecurity(config: HttpStrictTransportSecurityDsl.() -> Unit)
    fun xssProtection(config: XssProtectionConfigDsl.() -> Unit)
    fun referrerPolicy(config: ReferrerPolicyDsl.() -> Unit)
    fun permissionsPolicy(config: PermissionsPolicyDsl.() -> Unit)
    fun crossOriginEmbedderPolicy(config: CrossOriginEmbedderPolicyDsl.() -> Unit)
    fun crossOriginOpenerPolicy(config: CrossOriginOpenerPolicyDsl.() -> Unit)
    fun crossOriginResourcePolicy(config: CrossOriginResourcePolicyDsl.() -> Unit)
    fun defaultsDisabled()
}

class ContentSecurityPolicyDsl {
    var policyDirectives: String?
    var reportOnly: Boolean?
}

class FrameOptionsDsl {
    fun deny()
    fun sameOrigin()
    fun disable()
}

class HttpStrictTransportSecurityDsl {
    var maxAgeInSeconds: Long?
    var includeSubDomains: Boolean?
    var preload: Boolean?
}

Reactive Security DSL (ServerHttpSecurity)

Configure reactive security using Kotlin DSL.

// ServerHttpSecurity extension function
fun ServerHttpSecurity.invoke(httpConfiguration: ServerHttpSecurityDsl.() -> Unit): ServerHttpSecurity

// Main Reactive DSL
class ServerHttpSecurityDsl {
    fun authorizeExchange(authorizeExchangeConfig: AuthorizeExchangeDsl.() -> Unit)
    fun formLogin(formLoginConfig: ServerFormLoginDsl.() -> Unit)
    fun httpBasic(httpBasicConfig: ServerHttpBasicDsl.() -> Unit)
    fun oauth2Login(oauth2LoginConfig: ServerOAuth2LoginDsl.() -> Unit)
    fun oauth2Client(oauth2ClientConfig: ServerOAuth2ClientDsl.() -> Unit)
    fun oauth2ResourceServer(oauth2Config: ServerOAuth2ResourceServerDsl.() -> Unit)
    fun csrf(csrfConfig: ServerCsrfDsl.() -> Unit)
    fun cors(corsConfig: ServerCorsDsl.() -> Unit)
    fun headers(headersConfig: ServerHeadersDsl.() -> Unit)
    fun exceptionHandling(exceptionHandlingConfig: ServerExceptionHandlingDsl.() -> Unit)
    fun logout(logoutConfig: ServerLogoutDsl.() -> Unit)
    fun requestCache(requestCacheConfig: ServerRequestCacheDsl.() -> Unit)
    fun x509(x509Config: ServerX509Dsl.() -> Unit)
    fun anonymous(anonymousConfig: ServerAnonymousDsl.() -> Unit)
    fun sessionManagement(sessionManagementConfig: ServerSessionManagementDsl.() -> Unit)
    fun oidcLogout(oidcLogoutConfig: ServerOidcLogoutDsl.() -> Unit)
    fun passwordManagement(passwordManagementConfig: ServerPasswordManagementDsl.() -> Unit)
    fun oneTimeTokenLogin(oneTimeTokenLoginConfig: ServerOneTimeTokenLoginDsl.() -> Unit)
}

Usage Example:

@Configuration
@EnableWebFluxSecurity
class ReactiveSecurityConfig {

    @Bean
    fun springSecurityFilterChain(http: ServerHttpSecurity): SecurityWebFilterChain {
        http {
            authorizeExchange {
                authorize("/public/**", permitAll)
                authorize("/admin/**", hasRole("ADMIN"))
                authorize(anyExchange, authenticated)
            }
            formLogin { }
            httpBasic { }
            csrf {
                disable()
            }
            cors {
                disable()
            }
        }
        return http.build()
    }
}

Reactive Authorization DSL

class AuthorizeExchangeDsl {
    fun authorize(pattern: String, access: ReactiveAuthorizationManager<AuthorizationContext>)
    fun authorize(matcher: ServerWebExchangeMatcher, access: ReactiveAuthorizationManager<AuthorizationContext>)

    // Convenience constants
    val permitAll: ReactiveAuthorizationManager<AuthorizationContext>
    val denyAll: ReactiveAuthorizationManager<AuthorizationContext>
    val authenticated: ReactiveAuthorizationManager<AuthorizationContext>
    val anyExchange: ServerWebExchangeMatcher

    // Convenience functions
    fun hasRole(role: String): ReactiveAuthorizationManager<AuthorizationContext>
    fun hasAnyRole(vararg roles: String): ReactiveAuthorizationManager<AuthorizationContext>
    fun hasAuthority(authority: String): ReactiveAuthorizationManager<AuthorizationContext>
    fun hasAnyAuthority(vararg authorities: String): ReactiveAuthorizationManager<AuthorizationContext>
}

Complete Examples

Servlet Application

@Configuration
@EnableWebSecurity
class CompleteSecurityConfig {

    @Bean
    fun filterChain(http: HttpSecurity): SecurityFilterChain {
        http {
            // Authorization
            authorizeHttpRequests {
                authorize("/", permitAll)
                authorize("/public/**", permitAll)
                authorize("/api/admin/**", hasRole("ADMIN"))
                authorize("/api/**", hasAnyAuthority("READ", "WRITE"))
                authorize(anyRequest, authenticated)
            }

            // Authentication
            formLogin {
                loginPage = "/login"
                defaultSuccessUrl("/dashboard", true)
                failureUrl = "/login?error"
                usernameParameter = "email"
                passwordParameter = "pwd"
                permitAll()
            }

            httpBasic {
                realmName = "My Application"
            }

            // OAuth2
            oauth2Login {
                loginPage = "/login"
                userInfoEndpoint {
                    userService = customOAuth2UserService
                }
            }

            oauth2ResourceServer {
                jwt {
                    decoder = jwtDecoder()
                }
            }

            // Security Features
            csrf {
                csrfTokenRepository = CookieCsrfTokenRepository.withHttpOnlyFalse()
            }

            cors {
                configurationSource = corsConfigurationSource()
            }

            sessionManagement {
                sessionCreationPolicy = SessionCreationPolicy.IF_REQUIRED
                sessionFixation {
                    changeSessionId()
                }
                sessionConcurrency {
                    maximumSessions = 1
                    maxSessionsPreventsLogin = true
                    expiredUrl = "/session-expired"
                }
            }

            headers {
                contentSecurityPolicy {
                    policyDirectives = "default-src 'self'; script-src 'self' 'unsafe-inline'"
                }
                frameOptions {
                    sameOrigin()
                }
                httpStrictTransportSecurity {
                    maxAgeInSeconds = 31536000
                    includeSubDomains = true
                }
            }

            logout {
                logoutUrl = "/logout"
                logoutSuccessUrl = "/"
                invalidateHttpSession = true
                deleteCookies("JSESSIONID", "remember-me")
                clearAuthentication = true
            }

            exceptionHandling {
                authenticationEntryPoint = Http403ForbiddenEntryPoint()
                accessDeniedPage = "/access-denied"
            }
        }
        return http.build()
    }

    @Bean
    fun userDetailsService(): UserDetailsService {
        val user = User.withUsername("user")
            .password("{bcrypt}..." + "...")
            .roles("USER")
            .build()

        val admin = User.withUsername("admin")
            .password("{bcrypt}..." + "...")
            .roles("USER", "ADMIN")
            .build()

        return InMemoryUserDetailsManager(user, admin)
    }
}

Reactive Application

@Configuration
@EnableWebFluxSecurity
class ReactiveCompleteSecurityConfig {

    @Bean
    fun springSecurityFilterChain(http: ServerHttpSecurity): SecurityWebFilterChain {
        http {
            authorizeExchange {
                authorize("/", permitAll)
                authorize("/public/**", permitAll)
                authorize("/api/admin/**", hasRole("ADMIN"))
                authorize(anyExchange, authenticated)
            }

            formLogin {
                loginPage = "/login"
            }

            oauth2Login { }

            oauth2ResourceServer {
                jwt {
                    decoder = ReactiveJwtDecoders.fromIssuerLocation("https://idp.example.com")
                }
            }

            csrf {
                csrfTokenRepository = CookieCsrfTokenRepository.withHttpOnlyFalse()
            }

            cors {
                configurationSource = corsConfigurationSource()
            }

            headers {
                contentSecurityPolicy {
                    policyDirectives = "default-src 'self'"
                }
            }

            logout {
                logoutUrl = "/logout"
            }
        }
        return http.build()
    }

    @Bean
    fun userDetailsService(): ReactiveUserDetailsService {
        val user = User.withUsername("user")
            .password("{noop}password")
            .roles("USER")
            .build()

        return MapReactiveUserDetailsService(user)
    }
}

Multiple Security Filter Chains

@Configuration
@EnableWebSecurity
class MultiFilterChainConfig {

    @Bean
    @Order(1)
    fun apiFilterChain(http: HttpSecurity): SecurityFilterChain {
        http {
            securityMatcher("/api/**")
            authorizeHttpRequests {
                authorize(anyRequest, authenticated)
            }
            oauth2ResourceServer {
                jwt { }
            }
            csrf {
                disable()
            }
        }
        return http.build()
    }

    @Bean
    @Order(2)
    fun webFilterChain(http: HttpSecurity): SecurityFilterChain {
        http {
            authorizeHttpRequests {
                authorize("/public/**", permitAll)
                authorize(anyRequest, authenticated)
            }
            formLogin { }
            csrf { }
        }
        return http.build()
    }
}