Spring oauth2 resource server
Skill hcussi/claude-code-toolkit/skills/spring-oauth2-resource-server
Reusable Claude Code agents and skills, ready to drop into any project.
npx -y skills add hcussi/claude-code-toolkit --skill spring-oauth2-resource-serverAssembled 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.
- 0 stars0 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
Configure a Spring Boot app as an OAuth2 resource server that validates JWT access tokens against any OIDC provider (Keycloak, Auth0, Okta, Cognito, Entra ID). Sets up the security filter chain, JWT decoder with audience validation, CORS, config properties, and a slice test. Use when adding token-based API authentication to a Spring Boot service.
SKILL.md
4.0 KB, as published. Nobody here has run it
spring-oauth2-resource-server
Wire a Spring Boot application to accept and validate OAuth2/OIDC JWT access tokens (resource-server role). This covers protecting an API with bearer tokens. It does not configure the login/authorization-code flow (that is the client role) or opaque-token introspection.
Provider-agnostic: it is driven entirely by an issuer-uri, so it works with
Keycloak, Auth0, Okta, Cognito, Entra ID, or any OIDC-compliant authorization
server.
Before you start
Discover the target project's shape rather than assuming it (use Glob/Grep):
- Build tool:
build.gradle/build.gradle.ktsvspom.xml, and whether Gradle uses a version catalog (gradle/libs.versions.toml). - Spring Boot version: read it from the build file. It changes two test
imports (see
references/dependencies.md). - Base package: the package under
src/main/java/...holding the main@SpringBootApplicationclass. New classes go in aconfigsubpackage of it. - Config format:
application.ymlvsapplication.properties.
Then gather the values to plug in:
- issuer-uri: the OIDC issuer base URL.
- audience: the value expected in the token's
audclaim (usually the API's client id / identifier). - allowed CORS origins: the browser origins that call this API.
Steps
Reference files live in this skill's references/ directory. Copy them into the
project, then substitute com.example.app with the real base package and adjust
placeholders.
-
Add dependencies. Add
spring-boot-starter-oauth2-resource-server(main) andspring-security-test(test) using the snippet inreferences/dependencies.mdthat matches the project's build tool. -
Add
SecurityConfig. Copyreferences/SecurityConfig.javainto<base-package>/config/. It defines a stateless filter chain (anyRequest().authenticated(),oauth2ResourceServer().jwt()), CORS scoped to configured origins, and aJwtDecoderthat adds audience validation on top of the default signature/issuer/expiry checks. -
Add
AudienceValidator. Copyreferences/AudienceValidator.javainto the sameconfig/package. Recommended: without it, a token minted for any other client of the same issuer is accepted. If you deliberately do not want audience checking, omit both this class and thejwtDecoderbean, and Spring auto-configures a decoder fromissuer-urialone. -
Add config properties. Merge
references/application.ymlinto the project's config (or translate to.properties), filling inissuer-uri,audience, andallowed-origins. Keep them env-overridable. -
Add a test. Copy
references/SecurityConfigTest.java, point@WebMvcTestat a protected controller, and set the request path. It proves anonymous requests get 401 and a valid JWT is accepted, without a live issuer (theJwtDecoderis mocked). -
Verify. Build and run the test suite (
./gradlew testormvn test). Then confirm at runtime: a request with no token returns 401, and a request with a valid bearer token from the issuer returns 200.
Notes
- CSRF is disabled in the template because a token-authenticated API holds no server-side session or auth cookie. If this same app also serves cookie/session-authenticated endpoints, do not blanket-disable CSRF.
- Roles/scopes: this sets up authentication (valid token required). To
authorize by scope or role, add a
JwtAuthenticationConverterand.hasAuthority(...)rules; out of scope here. - Follow-up: run the
security-revieweragent afterward to audit the result (audience, CORS, issuer, token handling).