What’s demonstrated
- Form login — JSON body
POST /login, CSRF token supplied automatically from theXSRF-TOKENcookie, session cookie, fixation protection - Registration —
POST /api/registeradds a new user to the in-memory store at runtime (alwaysROLE_USER— self-service privilege selection at registration would be a privilege-escalation bug in a real app) - OAuth2 login — all four providers (Google, GitHub, Facebook, Zalo) via a
local
httpteststub - Bearer token (JWT) — a stateless resource-server leg composed alongside
the session chain (see Source highlights below):
mint a short-lived HS256 JWT for a seeded account, then call
GET /api/bearer/whoamiwithAuthorization: Bearer <token>. No cookie, no CSRF, no session — and session-only endpoints correctly 401 for a bearer-only caller, demonstrating the two mechanisms don’t interfere - CSRF — double-submit cookie strategy (
XSRF-TOKENcookie ↔X-CSRF-Tokenheader); the browser reads the cookie and echoes it on unsafe requests - Authorization —
/api/adminrequiresROLE_ADMIN,/api/userrequires any authenticated user,/api/whoamiis public,/api/bearer/whoamirequires a valid bearer token - Security headers — inspect response headers with DevTools
How the OAuth2 stub works
The playground starts a single*httptest.Server that handles three
endpoints, shared by all four providers:
ClientRegistration points all of its OAuth2 endpoints at
this stub, so the result is a fully functional PKCE authorization-code flow
that works offline, with no developer-console registration required. Every
OAuth2 login resolves to the same subject (oauth2-user-42) and gets a
synthesized ROLE_USER.
Source highlights
combinedUserService
OAuth2 principals (subjects) are not in the static user store. AcombinedUserService wraps the static service and synthesizes an
authn.User for unknown subjects:
Handler assembly
Login endpoint and every unsafe request are protected by the
double-submit CSRF repository; the OAuth2 callbacks use GET (a safe method)
and are exempt by design — the session-bound state parameter is their CSRF
defense.
Bearer token leg
The bearer/JWT method is a second, independent authn leg composed alongside the session chain above rather than merged into it — first-class composition of a bearer leg intosecurityhttp’s own chain is a documented future gap
(see securityhttp/README.md), so the playground demonstrates the pattern
examples/resource uses standalone: a route mounted with
resource.RequireBearer directly, outside securityhttp’s authorize step.
authz.Routes() rule for that path is PermitAll() — it just lets
the request through without requiring a session; RequireBearer does the
real authentication (and its own 401 challenge) once the request reaches the
app mux. POST /api/bearer/token mints a demo HS256 JWT for a seeded account,
standing in for an IdP’s token endpoint.
Log panel
The UI shows a real-time log of HTTP interactions as you use the playground. Each entry shows the method, path, status code, and the response body.Credentials
The same two seeded accounts drive both form login and bearer-token minting:
OAuth2 logins always resolve to
ROLE_USER via the stub userinfo endpoint.