Replace OpenID 2.0 with OAuth 2.0/OIDC login - #155
Open
mraible wants to merge 6 commits into
Open
Conversation
This was referenced Aug 12, 2026
mraible
force-pushed
the
feature/oidc-login
branch
from
August 13, 2026 03:13
acdf650 to
a0f10ac
Compare
Replace the obsolete OpenID 2.0 authentication (removed in Spring Security 6) with modern OAuth 2.0/OIDC login using spring-security-oauth2-client. OIDC providers are configured via roller-custom.properties with issuer discovery. The existing openIdUrl column is reused to store OIDC subjects (formatted as issuer#sub), avoiding schema changes. New OIDC users are redirected to registration with claims pre-populated; returning users go straight to the menu. AuthMethod enum values updated from OPENID/DB_OPENID to OIDC/DB_OIDC.
…est users The Dockerfile previously cloned the roller-6.1.0 tag from GitHub, so local changes never made it into the image; it now builds from the checkout. The Keycloak realm import gains an administrator (admin/admin) and a regular user (user/user) so both roles can be tried right after docker compose up, and the compose file accepts AUTHENTICATION_METHOD=db-oidc to offer form login next to the provider buttons.
…form registration Roller looks users up by principal name throughout the rendering layer and servlet filters, but an OidcUser's default name is the sub claim, an opaque provider ID that matches no Roller account; every rendered weblog page then failed with a Velocity NullPointerException for a signed-in OIDC user. The principal returned by RollerOidcUserService is now named after the resolved Roller account. Provisioning moves into the user service so the principal carries Roller roles from the first request, gets its own users.oidc.autoProvision.enabled toggle (default true, mirroring users.ldap.autoProvision.enabled) instead of piggybacking on the runtime form-registration setting that is off by default and blocked every provider user after the first, and requires a verified matching email before linking an existing account. Discovery needs jackson-databind on the classpath, and the login page lists providers from the resolved client registrations so it never advertises one whose discovery failed.
mraible
force-pushed
the
feature/oidc-login
branch
from
August 13, 2026 03:26
a0f10ac to
2b59bd4
Compare
There was a problem hiding this comment.
Pull request overview
Replaces obsolete OpenID 2.0 browser authentication with OAuth 2.0/OIDC, including account linking, provisioning, provider discovery, and local Keycloak support.
Changes:
- Adds OIDC login, Roller principal/role integration, and tests.
- Updates authentication configuration and login UI.
- Adds a Keycloak-backed Docker Compose demo.
Reviewed changes
Copilot reviewed 25 out of 25 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
Dockerfile |
Builds Roller from the working tree. |
.dockerignore |
Excludes local build data. |
docker-compose.yml |
Adds Keycloak and OIDC defaults. |
docker/entry-point.sh |
Writes OIDC runtime properties. |
docker/realm-config/roller-realm.json |
Seeds the demo realm and users. |
docker/realm-config/keycloak-health-check.sh |
Checks Keycloak readiness. |
app/pom.xml |
Adds OAuth2/OIDC dependencies. |
AuthMethod.java |
Replaces OpenID authentication modes. |
RollerContext.java |
Exposes registrations and adjusts PBKDF2 compatibility. |
RollerSession.java |
Resolves sessions by OIDC subject. |
RollerClientRegistrationRepository.java |
Discovers configured OIDC providers. |
RollerOidcUserService.java |
Links and provisions Roller users. |
RollerOAuth2SuccessHandler.java |
Redirects successful OIDC logins. |
Login.java |
Supplies provider data to the login page. |
Register.java |
Handles OIDC external-auth registration. |
Profile.java |
Updates OIDC profile behavior. |
ProfileBean.java |
Exposes issuer and subject fields. |
UserEdit.java |
Updates OIDC administration behavior. |
security.xml |
Configures Spring Security OIDC login. |
Login.jsp |
Renders provider sign-in buttons. |
roller.properties |
Documents OIDC configuration and provisioning. |
ApplicationResources.properties |
Adds OIDC UI messages. |
RollerOidcUserServiceTest.java |
Tests linking, provisioning, and roles. |
RollerOAuth2SuccessHandlerTest.java |
Tests post-login redirects. |
RollerClientRegistrationRepositoryTest.java |
Tests registration configuration handling. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
…IDC provisioning Hiding login forms and provider buttons is not an authentication control, so both sides of the filter chain now check authentication.method: the registration repository serves no providers unless the method is oidc or db-oidc (closing /oauth2/authorization/* under db, ldap, and cma), the OIDC user service rejects the flow outright, and the user details service refuses password lookups in pure oidc mode. users.firstUserAdmin would hand the admin role to whichever provider user reached a fresh install first, so auto-provisioned accounts no longer keep the bootstrap grant unless an admin role claim is asserted or the new users.oidc.firstUserAdmin property is enabled; the revocation is logged with the bootstrap alternatives. Provider discovery is now cached per provider with a bounded retry backoff, so one unreachable identity provider no longer blocks the others or turns every login page render into a discovery attempt. A confidential client without a client-secret is rejected at configuration time with a pointer to client-authentication-method=none for PKCE public clients. OAuth2 failures redirect with error=oidc so the login page stops diagnosing every provider failure as a wrong password. All raised by Copilot review.
…d auth methods These views still compared against the removed OPENID and DB_OPENID values and requested message keys deleted with them, so under the OIDC methods their password controls never rendered and the registration script never enabled submission. They now branch on OIDC and DB_OIDC, drop the OpenID URL entry fields, and show the provider-assigned identity read-only. The equivalent logic already existed one level up in the Bootstrap 5 UI conversion, which is why the stacked browser tests passed; it belongs at this level. Raised by Copilot review.
users.ldap.autoProvision.enabled has always shipped false, and the OIDC equivalent should not be more permissive: with the default on, everyone the identity provider authenticates received a Roller account. The docker entry point turns provisioning on when a provider is configured (override with OIDC_AUTO_PROVISION=false) so the Keycloak demo and CI matrix keep working, and the unit test configuration enables it so the provisioning path stays exercised.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stacked on #154 (1/3 in the stack); after it merges, this retargets to master. Replaces the obsolete OpenID 2.0 authentication (removed in Spring Security 6) with OAuth 2.0/OIDC login using
spring-security-oauth2-client. Phase 3 of the Jakarta EE 10 migration (ROL-2183).Removed / changed behavior — read before merging:
openidanddb-openidvalues ofauthentication.methodno longer exist; configs using them must move tooidcordb-oidc. OpenID 2.0 relay support does not survive in any form (the protocol is dead and Spring Security dropped it upstream).users.oidc.autoProvision.enableddefaults to false, matchingusers.ldap.autoProvision.enabled: only pre-created accounts, or accounts the provider links via a verified matching email, can sign in until it is enabled. The docker demo turns it on (override withOIDC_AUTO_PROVISION=false). Linking to an existing account always requires the provider to assert a verified email matching that account.users.firstUserAdminwould have handed the admin role to whichever provider user reached a fresh install first. Auto-provisioned accounts no longer keep that bootstrap grant unless the provider asserts anadminrole claim or the newusers.oidc.firstUserAdminproperty (default false) is enabled; the revocation is logged with the alternatives.authentication.methodis now enforced server side, not just in the UI: underdb,ldap, andcmano provider registrations are served and the OIDC flow is rejected outright, and under pureoidcthe form login refuses password lookups.db-oidcallows both.client-secretis rejected at configuration time with a clear log message;oidc.{id}.client-authentication-method=nonesupports public clients using PKCE.error=oidcmarker, so the login page reports them as provider failures instead of a wrong password.AUTHENTICATION_METHODtooidc, so the demo signs in through the bundled Keycloak by default; setdbfor the old form-login demo ordb-oidcfor both side by side.How it works:
RollerClientRegistrationRepositoryreads provider config (client-id, client-secret, issuer-uri) from Roller properties, with OIDC discovery at startupRollerOidcUserServiceresolves the Roller account behind an authenticated OIDC user via the existingopenIdUrlcolumn (storesissuer#sub) and provisions accounts just in time, so the principal carries Roller roles from the first requestsubclaim, which made every rendered weblog page fail with a Velocity error for signed-in OIDC usersAuthMethodgainsOIDC/DB_OIDC, and Login.jsp shows provider buttons built from the resolved registrations, so it never advertises a provider whose discovery failedTo try it: add
127.0.0.1 keycloakto /etc/hosts, thendocker compose up -dand log in at http://localhost:8080/ as admin/admin or user/user.