Authentication
DSL options and code examples for each authentication method. Detailed reference for authentication methods configured via .form(), .rest(), .ott(), .passkey() in the Identity DSL.
Overview
Contexa Identity provides four authentication methods. Each method creates an independent SecurityFilterChain, and priority is controlled via order().
| Authentication Method | DSL Method | Default Order | Purpose |
|---|---|---|---|
| Form Login | .form() | 100 | Traditional web form login (server-rendered) |
| REST API | .rest() | 200 | JSON-based API authentication (SPA, mobile) |
| One-Time Token | .ott() | 300 | Magic Link / email authentication |
| WebAuthn / Passkey | .passkey() | 400 | Biometric authentication / hardware keys |
All authentication methods support access to the full Spring Security API via rawHttp(), and support common options (order, CSRF, CORS, headers, logout, etc.).
Form Login
Traditional web form-based login. Configures Spring Security's formLogin() via the DSL. Default order is 100.
All Options
| Method | Type | Default | Description |
|---|---|---|---|
loginPage(String) | String | Unset in single-auth mode; MFA builder preloads the primary login page | Login page URL |
usernameParameter(String) | String | "username" | Username parameter name |
passwordParameter(String) | String | "password" | Password parameter name |
loginProcessingUrl(String) | String | AuthUrlProvider.getSingleFormLoginProcessing() | Login processing URL |
defaultSuccessUrl(String) | String | — | Redirect URL after successful login |
defaultSuccessUrl(String, boolean) | String, boolean | — | Success URL + alwaysUse flag |
failureUrl(String) | String | — | Redirect URL on login failure |
permitAll() | — | false | Enable unauthenticated access to the configured login page |
successHandler(PlatformAuthenticationSuccessHandler) | Handler | Auto-selected | Custom success handler |
failureHandler(PlatformAuthenticationFailureHandler) | Handler | Auto-selected | Custom failure handler |
securityContextRepository(SecurityContextRepository) | Repository | Auto-selected by state type | Security context repository |
rawFormLogin(SafeHttpFormLoginCustomizer) | Customizer | — | Direct customization within formLogin() |
rawHttp(SafeHttpCustomizer<HttpSecurity>) | Customizer | — | Full Spring Security API access (cumulative) |
order(int) | int | 100 | Filter chain priority |
asep(Customizer<FormAsepAttributes>) | Customizer | — | ASEP annotation attribute configuration |
Basic Configuration
registry
.form(form -> form
.loginPage("/login")
.defaultSuccessUrl("/home")
.failureUrl("/login?error")
.permitAll()
)
.session(Customizer.withDefaults())
.build();
Custom Handlers
registry
.form(form -> form
.loginPage("/login")
.usernameParameter("email")
.passwordParameter("passwd")
.successHandler(customSuccessHandler)
.failureHandler(customFailureHandler)
)
.session(Customizer.withDefaults())
.build();
Advanced Configuration (rawHttp + rawFormLogin)
registry
.form(form -> form
.order(20)
.loginPage("/admin/login")
.rawFormLogin(formLogin -> formLogin
.usernameParameter("admin_user")
.passwordParameter("admin_pass"))
.rawHttp(http -> http
.securityMatcher("/admin/**")
.sessionManagement(session -> session
.maximumSessions(1)
.maxSessionsPreventsLogin(true)))
)
.session(Customizer.withDefaults())
.build();
rawFormLogin() only customizes the internals of HttpSecurity.formLogin(). rawHttp() provides access to the full Spring Security API (sessionManagement, securityMatcher, custom filter registration, etc.). Both methods support cumulative invocations.
REST API Authentication
JSON-based REST API authentication. Authenticates via JSON payloads from frontend clients such as SPAs and mobile apps. Default order is 200.
All Options
| Method | Type | Default | Description |
|---|---|---|---|
loginProcessingUrl(String) | String | AuthUrlProvider.getSingleRestLoginProcessing() | REST login processing URL |
defaultSuccessUrl(String) | String | — | Redirect URL after success |
defaultSuccessUrl(String, boolean) | String, boolean | — | Success URL + alwaysUse flag |
failureUrl(String) | String | — | Redirect URL on failure |
successHandler(PlatformAuthenticationSuccessHandler) | Handler | Auto-selected | Custom success handler |
failureHandler(PlatformAuthenticationFailureHandler) | Handler | Auto-selected | Custom failure handler |
securityContextRepository(SecurityContextRepository) | Repository | Auto-selected by state type | Security context repository |
rawHttp(SafeHttpCustomizer<HttpSecurity>) | Customizer | — | Full Spring Security API access (cumulative) |
order(int) | int | 200 | Filter chain priority |
asep(Customizer<RestAsepAttributes>) | Customizer | — | ASEP annotation attribute configuration |
Basic Configuration
registry
.rest(rest -> rest
.loginProcessingUrl("/api/auth/login")
)
.oauth2(Customizer.withDefaults())
.build();
Stateless API Configuration (rawHttp)
registry
.rest(rest -> rest
.order(50)
.loginProcessingUrl("/api/auth")
.rawHttp(http -> http
.securityMatcher("/api/**")
.sessionManagement(session ->
session.sessionCreationPolicy(SessionCreationPolicy.STATELESS)))
)
.oauth2(Customizer.withDefaults())
.build();
REST API authentication is typically combined with
.oauth2() for stateless JWT-based operation. It can also be combined with .session(), but OAuth2 is recommended for API servers.
One-Time Token (Magic Link)
Authentication via a one-time token sent by email or SMS. Passwordless authentication using the Magic Link approach. Default order is 300.
All Options
| Method | Type | Default | Description |
|---|---|---|---|
tokenGeneratingUrl(String) | String | — | Token generation request URL |
defaultSubmitPageUrl(String) | String | — | Token input page URL |
parameter names | String | "username" / "token" | The current public OTT DSL keeps the default parameter names. Custom parameter names require lower-level option customization rather than dedicated DSL setters. |
showDefaultSubmitPage(boolean) | boolean | true | Whether to display the default token submit page |
tokenService(OneTimeTokenService) | Service | Bean from the application context | Token generation/verification service implementation (required) |
tokenGenerationSuccessHandler(OneTimeTokenGenerationSuccessHandler) | Handler | — | Token generation success handler (e.g., email delivery) |
loginProcessingUrl(String) | String | AuthUrlProvider.getSingleOttLoginProcessing() | Token verification processing URL |
successHandler(PlatformAuthenticationSuccessHandler) | Handler | Auto-selected | Authentication success handler |
failureHandler(PlatformAuthenticationFailureHandler) | Handler | Auto-selected | Authentication failure handler |
rawHttp(SafeHttpCustomizer<HttpSecurity>) | Customizer | — | Full Spring Security API access (cumulative) |
order(int) | int | 300 | Filter chain priority |
asep(Customizer<OttAsepAttributes>) | Customizer | — | ASEP annotation attribute configuration |
Basic Configuration
registry
.ott(ott -> ott
.tokenService(customTokenService)
.tokenGenerationSuccessHandler(emailSendingHandler)
)
.session(Customizer.withDefaults())
.build();
Custom Pages + Email Delivery Handler
registry
.ott(ott -> ott
.tokenGeneratingUrl("/auth/magic-link/request")
.defaultSubmitPageUrl("/auth/magic-link/verify")
// The public OTT DSL keeps the default token parameter name: "token"
.showDefaultSubmitPage(false)
.tokenService(jpaOneTimeTokenService)
.tokenGenerationSuccessHandler((request, response, token) -> {
String email = request.getParameter("username");
emailService.sendMagicLink(email, token.getTokenValue());
response.sendRedirect("/auth/magic-link/sent");
})
)
.session(Customizer.withDefaults())
.build();
WebAuthn / Passkey
FIDO2 WebAuthn-based biometric and hardware security key authentication. The most secure form of passwordless authentication. Default order is 400.
All Options
| Method | Type | Default | Description |
|---|---|---|---|
rpName(String) | String | "contexa-identity" | Relying Party name (displayed to users) |
rpId(String) | String | "localhost" | Relying Party ID (domain) |
allowedOrigins(Set<String>) | Set<String> | ["http://localhost:${server.port}"] fallback when no explicit origins are configured | Allowed origins list |
allowedOrigins(String...) | String... | — | Allowed origins (varargs) |
assertionOptionsEndpoint(String) | String | AuthUrlProvider.getSinglePasskeyAssertionOptions() | Assertion options endpoint |
loginProcessingUrl(String) | String | AuthUrlProvider.getSinglePasskeyLoginProcessing() | Authentication processing URL |
successHandler(PlatformAuthenticationSuccessHandler) | Handler | Auto-selected | Authentication success handler |
failureHandler(PlatformAuthenticationFailureHandler) | Handler | Auto-selected | Authentication failure handler |
rawHttp(SafeHttpCustomizer<HttpSecurity>) | Customizer | — | Full Spring Security API access (cumulative) |
order(int) | int | 400 | Filter chain priority |
asep(Customizer<PasskeyAsepAttributes>) | Customizer | — | ASEP annotation attribute configuration |
Basic Configuration
registry
.passkey(passkey -> passkey
.rpName("My Application")
.rpId("example.com")
.allowedOrigins("https://example.com")
)
.session(Customizer.withDefaults())
.build();
Passkey Registration Flow
Passkey registration proceeds in three steps. The server stores credentials through Spring Security's UserCredentialRepository.
Client Server
| |
| 1. POST /webauthn/register |
| /options |
| ---------------------------> |
| | PublicKeyCredentialCreationOptions
| <--------------------------- | (rpId, rpName, userId, challenge)
| |
| 2. navigator.credentials |
| .create(options) |
| [Browser WebAuthn API] |
| |
| 3. POST /webauthn/register |
| ---------------------------> |
| (AuthenticatorAttestation | Verify + Store in
| Response) | UserCredentialRepository
| |
| <--- 201 Created ----------- |
Passkey Management REST API
| Method | URL | Description |
|---|---|---|
POST | /webauthn/register/options | Generate registration options (PublicKeyCredentialCreationOptions) |
POST | /webauthn/register | Register credential (AuthenticatorAttestationResponse verification) |
POST | /webauthn/authenticate/options | Generate authentication challenge (assertionOptionsEndpoint) |
DELETE | /webauthn/register/{id} | Delete credential |
Single Authentication vs MFA Second Factor
Passkey uses completely different URLs, adapters, and state management for single authentication versus MFA second-factor authentication.
| Aspect | Single Authentication | MFA Second Factor |
|---|---|---|
| Authentication URL | /login/webauthn | /login/mfa-webauthn |
| Adapter | PasskeyAuthenticationAdapter | MfaPasskeyAuthenticationAdapter |
| Filter | Spring Security built-in | MfaPasskeyAuthenticationFilter |
| State Management | SecurityContextRepository | MFA State Machine |
| DSL Configuration | .passkey() | .mfa(m -> m.passkey()) |
Automatic Handler Resolution
When no custom handler is specified for an authentication method, the appropriate handler is automatically selected based on the authentication flow and state type.
Success / Failure Handler Selection Rules
| Flow | State Type | Success Handler | Failure Handler |
|---|---|---|---|
| Single Auth | Session | Spring Security default | Spring Security default |
| Single Auth | OAuth2 | OAuth2SingleAuthSuccessHandler | OAuth2SingleAuthFailureHandler |
| MFA Primary | Any | PrimaryAuthenticationSuccessHandler | UnifiedAuthenticationFailureHandler |
| MFA Subsequent | Any | MfaFactorProcessingSuccessHandler | UnifiedAuthenticationFailureHandler |
SecurityContextRepository Selection Rules
| Flow | Phase | Repository |
|---|---|---|
| Single Auth | Session | HttpSessionSecurityContextRepository |
| Single Auth | OAuth2 | NullSecurityContextRepository |
| MFA | Primary (not final) | NullSecurityContextRepository |
| MFA | Final step | Auto-selected by state type |
| MFA | Intermediate step | NullSecurityContextRepository |
For custom handler implementation, refer to the Extension Points section in the Adaptive MFA documentation.