agentsclimarketplace

Implementing scalekit springboot auth

Skill scalekit-inc/skills/skills/implementing-scalekit-springboot-auth

35 skills that teach AI coding agents to integrate Scalekit auth — agent auth, full-stack login, MCP OAuth 2.1, enterprise SSO, and SCIM. Works with Claude Code, Cursor, Windsurf, and 35+ other agents.

Install
npx -y skills add scalekit-inc/skills --skill implementing-scalekit-springboot-auth

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

2 things to look at

  • no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
  • 2 stars2 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Guides Java developers integrating Scalekit OIDC authentication into Spring Boot 3.x apps. Use when the developer mentions Scalekit, enterprise SSO, OIDC login, OAuth2 client setup, protected routes, ID token claims, or logout in a Spring Boot project.

SKILL.md

9.9 KB, as published. Nobody here has run it

Scalekit Auth in Spring Boot

Scalekit acts as an OIDC provider. Spring Security's oauth2-client starter handles the full authorization code flow — no custom filters needed.

Required dependencies

Add to pom.xml (Spring Boot 3.2+, Java 17+):

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>
<!-- Scalekit JSDK -->
<dependency>
    <groupId>com.scalekit</groupId>
    <artifactId>scalekit-sdk-java</artifactId>
    <version>2.0.4</version>
</dependency>

Configuration

src/main/resources/application.yml:

scalekit:
  env-url: ${SCALEKIT_ENV_URL}
  client-id: ${SCALEKIT_CLIENT_ID}
  client-secret: ${SCALEKIT_CLIENT_SECRET}
  redirect-uri: ${SCALEKIT_REDIRECT_URI:http://localhost:8080/login/oauth2/code/scalekit}

spring:
  security:
    oauth2:
      client:
        registration:
          scalekit:
            client-id: ${scalekit.client-id}
            client-secret: ${scalekit.client-secret}
            authorization-grant-type: authorization_code
            redirect-uri: ${scalekit.redirect-uri}
            scope: openid,profile,email,offline_access
            client-name: Scalekit
        provider:
          scalekit:
            issuer-uri: ${scalekit.env-url}
            authorization-uri: ${scalekit.env-url}/oauth/authorize
            token-uri: ${scalekit.env-url}/oauth/token
            user-info-uri: ${scalekit.env-url}/userinfo
            jwk-set-uri: ${scalekit.env-url}/keys
            user-name-attribute: sub

For local dev, use application-local.properties — never commit secrets.

Scalekit SDK bean

@Configuration
public class ScalekitConfig {

    @Value("${scalekit.env-url}")
    private String envUrl;

    @Value("${scalekit.client-id}")
    private String clientId;

    @Value("${scalekit.client-secret}")
    private String clientSecret;

    @Bean
    public ScalekitClient scalekitClient() {
        return new ScalekitClient(envUrl, clientId, clientSecret);
    }
}

Security filter chain

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http,
            ClientRegistrationRepository clientRegistrationRepository) throws Exception {
        http
            .authorizeHttpRequests(authz -> authz
                .requestMatchers("/", "/login", "/error", "/css/**", "/js/**").permitAll()
                .anyRequest().authenticated()
            )
            .oauth2Login(oauth2 -> oauth2
                .loginPage("/login")
                .defaultSuccessUrl("/dashboard", true)
            )
            .logout(logout -> logout
                .logoutSuccessHandler(oidcLogoutSuccessHandler(clientRegistrationRepository))
                .invalidateHttpSession(true)
                .clearAuthentication(true)
            );
        return http.build();
    }

    private LogoutSuccessHandler oidcLogoutSuccessHandler(
            ClientRegistrationRepository clientRegistrationRepository) {
        OidcClientInitiatedLogoutSuccessHandler handler =
                new OidcClientInitiatedLogoutSuccessHandler(clientRegistrationRepository);
        handler.setPostLogoutRedirectUri("{baseUrl}");
        return handler;
    }
}

Accessing user identity in controllers

@GetMapping("/dashboard")
public String dashboard(@AuthenticationPrincipal OidcUser oidcUser, Model model) {
    model.addAttribute("name",    oidcUser.getFullName());
    model.addAttribute("email",   oidcUser.getEmail());
    model.addAttribute("subject", oidcUser.getSubject());
    model.addAttribute("claims",  oidcUser.getClaims());
    return "dashboard";
}

Key OidcUser accessors: getFullName(), getEmail(), getSubject(), getClaims(), getAuthorities().

Application routes

RouteAuth?Notes
/NoHome page
/loginNoCustom login page
/dashboardYesProtected; redirects to login
/oauth2/authorization/scalekitNoStarts OIDC flow
/auth/callbackNoHandled by Spring Security automatically
/logoutYesTriggers OIDC end-session

Scalekit Dashboard setup checklist

- [ ] Get Environment URL (e.g., https://your-env.scalekit.dev)
- [ ] Get Client ID and Client Secret from Settings > API Credentials
- [ ] Add allowed redirect URI: http://localhost:8080/login/oauth2/code/scalekit
- [ ] Optionally add post-logout redirect: http://localhost:8080

Workflows

Add Scalekit auth to an existing Spring Boot app

Progress:
- [ ] Step 1: Add Maven dependencies
- [ ] Step 2: Add application.yml OAuth2 provider/registration config
- [ ] Step 3: Create ScalekitConfig bean
- [ ] Step 4: Create SecurityConfig filter chain
- [ ] Step 5: Inject @AuthenticationPrincipal OidcUser in protected controllers
- [ ] Step 6: Configure redirect URIs in Scalekit dashboard
- [ ] Step 7: Run app and verify login → dashboard → logout flow

Troubleshooting

JWKS timeout / JWT verification errors: Spring Security fetches JWKS on every token validation. Increase the decoder timeout — see Spring docs on JWT decoder timeouts.

Redirect URI mismatch: The redirect-uri in application.yml must exactly match what is registered in the Scalekit dashboard.

Enable debug logging in application.yml:

logging:
  level:
    org.springframework.security.oauth2: TRACE
    com.example.scalekit: DEBUG

Reference

Tactics

SameSite=Lax on the session cookie

Spring Boot does not set SameSite by default. Add to application.yml:

server:
  servlet:
    session:
      cookie:
        same-site: lax      # Required — 'strict' breaks OAuth callbacks
        http-only: true
        secure: true        # Set to true in production (HTTPS)

Without SameSite: Lax, some browsers drop the session cookie on the cross-origin redirect from Scalekit back to your app, causing the OAuth state to be lost.

Deep link preservation — use SavedRequestAwareAuthenticationSuccessHandler

The default defaultSuccessUrl("/dashboard", true) ignores the originally requested URL. Remove true to restore the saved-request redirect:

.oauth2Login(oauth2 -> oauth2
    .loginPage("/login")
    .defaultSuccessUrl("/dashboard")   // without `true` — respects saved request
)

Spring Security stores the pre-login URL in the session automatically via RequestCache. The user lands on /dashboard only if no prior request was saved.

CORS for browser clients

Add CORS support in SecurityFilterChain:

@Bean
public SecurityFilterChain filterChain(HttpSecurity http,
        ClientRegistrationRepository clientRegistrationRepository) throws Exception {
    http
        .cors(cors -> cors.configurationSource(corsConfigurationSource()))
        ...
    return http.build();
}

@Bean
public CorsConfigurationSource corsConfigurationSource() {
    CorsConfiguration config = new CorsConfiguration();
    config.setAllowedOrigins(List.of("http://localhost:3000"));
    config.setAllowedMethods(List.of("GET", "POST", "PUT", "DELETE", "OPTIONS"));
    config.setAllowedHeaders(List.of("*"));
    config.setAllowCredentials(true);   // required for session cookies
    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    source.registerCorsConfiguration("/**", config);
    return source;
}

AJAX: 401 instead of redirect

Spring Security redirects unauthenticated requests to the login page by default. Browser AJAX clients expect 401, not 302. Override the entry point in SecurityFilterChain:

.exceptionHandling(ex -> ex
    .authenticationEntryPoint((request, response, authException) -> {
        String accept = request.getHeader("Accept");
        if (accept != null && accept.contains("application/json")) {
            response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Authentication required");
        } else {
            response.sendRedirect("/login");
        }
    }))

Cache-Control: no-store on protected responses

@GetMapping("/dashboard")
public String dashboard(@AuthenticationPrincipal OidcUser oidcUser,
                        Model model, HttpServletResponse response) {
    response.setHeader("Cache-Control", "no-store");
    model.addAttribute("name",  oidcUser.getFullName());
    model.addAttribute("email", oidcUser.getEmail());
    return "dashboard";
}

CSRF and OAuth2 — what Spring Security does automatically

Spring Security disables CSRF protection for OAuth2 login endpoints (/oauth2/authorization/** and /login/oauth2/code/**) by default. The state parameter in the authorization URL serves as the CSRF token for the OAuth flow. You do not need to add any CSRF configuration for basic Scalekit auth.

OIDC logout vs local logout

OidcClientInitiatedLogoutSuccessHandler calls the Scalekit end-session endpoint and revokes the IdP session. If you use a plain logoutSuccessUrl() instead, only the local Spring session is cleared — the user will be silently re-authenticated on the next login attempt. Always use the OIDC handler.

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.