You need to implement a full-stack SAML-based SSO solution that secures both the UI and the underlying REST APIs.
The goal is to implement SAML-based Single Sign-On (SSO) to secure the entire application.
Requirements:
Zero-Trust Access: No frontend screens should be accessible unless the user is authenticated via SAML. Unauthorized users must be redirected to the Identity Provider (IdP) login page immediately.
Backend Integration: Assuming a Kotlin/Spring Boot backend, configure Spring Security SAML 2.0 to handle the Service Provider (SP) metadata, assertions, and session management.
Frontend Guard: Implement an authentication guard (e.g., using React Router or a higher-order component) that checks for a valid session/token before rendering any protected routes.
Testing & Mocking: > - Extend existing frontend tests (Vitest/Jest/Cypress) to simulate a "logged-in" SAML state.
Create a mock for the SAML authentication provider/context so that UI tests can run without a live IdP.
Ensure backend tests use @WithMockUser or a custom SAML mock security context.
Instructions for the AI:
First, analyze the repository structure to identify the specific frontend framework (e.g., React, Vue) and backend setup (e.g., Spring Boot, Ktor).
Provide the necessary dependency additions (e.g., spring-security-saml2-service-provider).
Provide the configuration code for the SAML Security Filter Chain.
Provide the frontend logic for the AuthProvider and ProtectedRoute components.
Provide a specific example of how to update a test file to mock the SAML user.
Key Technical Considerations for this Implementation
If you are implementing this manually or reviewing the AI's output, here are the core components required for the OpenDataMask stack:
- Backend: Spring Security SAML 2.0
In a Kotlin-based tool like OpenDataMask, you will likely use the official Spring Security SAML support.
Dependencies: Add org.springframework.security:spring-security-saml2-service-provider to your build.gradle.kts.
Security Config:
@Bean
fun filterChain(http: HttpSecurity): SecurityFilterChain {
http
.authorizeHttpRequests { auth ->
auth.anyRequest().authenticated()
}
.saml2Login(Customizer.withDefaults())
return http.build()
}
2. Frontend: The "Auth Guard"
To ensure users cannot see screens before authentication, use a Wrapper component.
Logic: The frontend should ping a /api/me or /api/auth-status endpoint. If it returns a 401/403, the app should redirect to the /saml2/authenticate/idp-alias endpoint hosted by your backend.
3. Mocking SAML in Tests
SAML is notoriously difficult to test because it involves XML signatures and redirects.
Frontend Mocking: Instead of mocking the SAML protocol, mock the useAuth() hook or the global state.
JavaScript
// Example: Mocking the user in Vitest/Jest
const mockUser = { name: "Test User", email: "test@example.com", authenticated: true };
vi.mock('./hooks/useAuth', () => ({
useAuth: () => ({ user: mockUser })
}));
Backend Mocking: Use the @WithMockSaml2User annotation if available, or manually populate the SecurityContext in your @BeforeEach blocks to simulate a successful SAML assertion.
Requirements:
1. Frontend Security & UX:
Zero-Trust Guard: No frontend routes should render without a valid session. Redirect unauthorized users to the SAML IdP.
Session Awareness: Implement a frontend interceptor (e.g., Axios or Fetch) that handles 401 Unauthorized responses by triggering a re-login or refreshing the session.
2. Backend API Security (Crucial):
Authenticated Entry Points: Secure all /api/** endpoints. Ensure that every request is validated against the SAML-initiated Security Context.
Stateless vs. Stateful: Configure the backend to either use Session-based authentication (JSESSIONID) or convert the SAML assertion into a JWT for stateless API calls.
CSRF Protection: Since SAML often relies on cookies/sessions, implement CSRF (Cross-Site Request Forgery) protection for all mutating API calls (POST, PUT, DELETE).
CORS Configuration: Define a strict Cross-Origin Resource Sharing policy to allow only the trusted frontend domain to access the APIs.
Attribute Mapping: Map SAML attributes (e.g., groups, roles) to backend GrantedAuthorities for Role-Based Access Control (RBAC) on specific API endpoints.
3. Testing & Mocking:
Frontend: Provide a Vitest/Jest mock for the authenticated API state.
Backend: Provide a Spring Security test case using @WithMockUser or a custom @WithSamlUser to verify that /api/** endpoints correctly reject unauthenticated requests with a 401.
Instructions for the AI:
Analyze the repository to confirm the tech stack (likely Kotlin/Spring Boot and React/TypeScript).
Provide the SecurityFilterChain code including SAML login, API authorization rules, and CSRF configuration.
Show the frontend interceptor logic for handling expired SAML sessions.
Provide a sample controller test demonstrating a secured API call.
Technical Deep-Dive: How the API Security Works
When you extend SAML to secure APIs, you are essentially bridging a Browser-based Redirect protocol (SAML) with a Data-based request protocol (REST).
The Authentication Flow
The Handshake: The user tries to access the UI. The UI sees no session and redirects to the Backend. The Backend redirects to the IdP.
The Assertion: The IdP sends a SAML Assertion back to the Backend.
The Session: The Backend validates the assertion and creates a SecurityContext. It sets a Set-Cookie header (typically JSESSIONID) in the browser.
The API Call: The frontend calls /api/mask-data. The browser automatically attaches the JSESSIONID cookie.
The Verification: The Backend’s Spring Security filter intercepts the call, finds the session in the session store, and populates the SecurityContextHolder. If the session is missing or expired, it returns a 401.
Recommended Security Config (Kotlin/Spring)
Your implementation should look similar to this to ensure the API is locked down:
Kotlin
@Bean
fun filterChain(http: HttpSecurity): SecurityFilterChain {
http
.cors { it.configurationSource(corsConfigurationSource()) }
.csrf { it.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()) } // Required for SPA
.authorizeHttpRequests { auth ->
auth.requestMatchers("/api/**").authenticated() // Secure all APIs
auth.anyRequest().permitAll() // Allow the SPA to load its own assets
}
.saml2Login(Customizer.withDefaults())
.exceptionHandling { exceptions ->
// Prevent redirecting API calls to a login page; return 401 instead
exceptions.authenticationEntryPoint(HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED))
}
return http.build()
}
Why CSRF is vital here
Because SAML-based authentication usually relies on Cookies to maintain the session between the browser and the API, your application becomes vulnerable to CSRF attacks.
This ensures that the backend sends a XSRF-TOKEN cookie that the frontend must read and send back in a header (like X-XSRF-TOKEN) for every POST/PUT request, proving the request originated from your UI and not a malicious site.
You need to implement a full-stack SAML-based SSO solution that secures both the UI and the underlying REST APIs.
The goal is to implement SAML-based Single Sign-On (SSO) to secure the entire application.
Requirements:
Zero-Trust Access: No frontend screens should be accessible unless the user is authenticated via SAML. Unauthorized users must be redirected to the Identity Provider (IdP) login page immediately.
Backend Integration: Assuming a Kotlin/Spring Boot backend, configure Spring Security SAML 2.0 to handle the Service Provider (SP) metadata, assertions, and session management.
Frontend Guard: Implement an authentication guard (e.g., using React Router or a higher-order component) that checks for a valid session/token before rendering any protected routes.
Testing & Mocking: > - Extend existing frontend tests (Vitest/Jest/Cypress) to simulate a "logged-in" SAML state.
Create a mock for the SAML authentication provider/context so that UI tests can run without a live IdP.
Ensure backend tests use @WithMockUser or a custom SAML mock security context.
Instructions for the AI:
First, analyze the repository structure to identify the specific frontend framework (e.g., React, Vue) and backend setup (e.g., Spring Boot, Ktor).
Provide the necessary dependency additions (e.g., spring-security-saml2-service-provider).
Provide the configuration code for the SAML Security Filter Chain.
Provide the frontend logic for the AuthProvider and ProtectedRoute components.
Provide a specific example of how to update a test file to mock the SAML user.
Key Technical Considerations for this Implementation
If you are implementing this manually or reviewing the AI's output, here are the core components required for the OpenDataMask stack:
In a Kotlin-based tool like OpenDataMask, you will likely use the official Spring Security SAML support.
Dependencies: Add org.springframework.security:spring-security-saml2-service-provider to your build.gradle.kts.
Security Config: