Introduce OidcProperty extension point#644
Conversation
In the context of CloudBees CI, I needed the ability to implement new optional behaviour customizing the OIDC configuration and client. The new extension point, named `OicProperty`, allows to capture a state through `OicPropertyExecution` that can be used for customize both the OIDC configuration and client. I have also taken the opportunity to fold some advanced options under their own class. Ultimately, all advanced fields could be implemeneted as `OicProperty` but for some of them it can be challenging due to the way they are currently integrated in the plugin. Migrated fields * Allowed token expiration clock skew * Disable nonce * Disable token verification * Escape hatch * Login query parameters * Logout query parameters * Enable PKCE
There was a problem hiding this comment.
Actually moved to EscapeHatch
| * Convert the OicServerConfiguration to {@link OIDCProviderMetadata} for use by the client. | ||
| */ | ||
| public abstract OIDCProviderMetadata toProviderMetadata(); | ||
| public final OIDCProviderMetadata toProviderMetadata() { |
There was a problem hiding this comment.
Moved from OicSecurityRealm
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## master #644 +/- ##
============================================
- Coverage 74.97% 74.74% -0.23%
- Complexity 289 326 +37
============================================
Files 24 33 +9
Lines 1179 1299 +120
Branches 167 179 +12
============================================
+ Hits 884 971 +87
- Misses 202 241 +39
+ Partials 93 87 -6 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
PereBueno
left a comment
There was a problem hiding this comment.
From the part of the plugin I'm familiar with (FIPS and nonce checks mainly) everything seems fine.
Only problem I found is migrating the clockskew property
| // set many more as needed... | ||
|
|
||
| OIDCProviderMetadata oidcProviderMetadata = serverConfiguration.toProviderMetadata(); | ||
| filterNonFIPS140CompliantAlgorithms(oidcProviderMetadata); |
There was a problem hiding this comment.
Moved to OicServerConfiguration
| OIDCProviderMetadata oidcProviderMetadata = serverConfiguration.toProviderMetadata(); | ||
| filterNonFIPS140CompliantAlgorithms(oidcProviderMetadata); | ||
| OidcOpMetadataResolver opMetadataResolver; | ||
| if (this.isDisableTokenVerification()) { |
There was a problem hiding this comment.
Moved to DisableTokenVerification
| // auto configuration does not need to supply scopes | ||
| conf.setScope(oidcProviderMetadata.getScopes().toString()); | ||
| } | ||
| conf.setUseNonce(!this.nonceDisabled); |
There was a problem hiding this comment.
Moved to DisableNonce.
| conf.setScope(oidcProviderMetadata.getScopes().toString()); | ||
| } | ||
| conf.setUseNonce(!this.nonceDisabled); | ||
| if (allowedTokenExpirationClockSkewSeconds != null) { |
There was a problem hiding this comment.
Moved AllowedTokenExpirationClockSkew
| conf.setMaxClockSkew(allowedTokenExpirationClockSkewSeconds.intValue()); | ||
| } | ||
| conf.setResourceRetriever(getResourceRetriever()); | ||
| if (this.isPkceEnabled()) { |
| conf.setDisablePkce(true); | ||
| } | ||
| opMetadataResolver.init(); | ||
| if (loginQueryParameters != null && !loginQueryParameters.isEmpty()) { |
There was a problem hiding this comment.
Moved to LoginQueryParameters
| return conf; | ||
| } | ||
|
|
||
| // Visible for testing |
There was a problem hiding this comment.
Moved to OicServerConfiguration
| return new SecurityComponents(new AuthenticationManager() { | ||
| public Authentication authenticate(Authentication authentication) throws AuthenticationException { | ||
| if (authentication instanceof AnonymousAuthenticationToken) return authentication; | ||
|
|
| uriComponentsBuilder.queryParam( | ||
| "post_logout_redirect_uri", URLEncoder.encode(postLogoutRedirectUrl, StandardCharsets.UTF_8)); | ||
| } | ||
| if (logoutQueryParameters != null && !logoutQueryParameters.isEmpty()) { |
There was a problem hiding this comment.
Moved to LogoutQueryParameters
| * Allows a property to authenticate the user. | ||
| * @see org.jenkinsci.plugins.oic.properties.EscapeHatch | ||
| */ | ||
| public Optional<Authentication> authenticate(Authentication authentication) { |
There was a problem hiding this comment.
For bearer token, I think you would need to add a way to plug a new filter into the authentication chain (doesn't exist currently, I only added the bare minumum for EscapeHatch to work), to convert the http headers to a BearerTokenAuthentication (to be written). And then an implementation of this method does what https://github.com/jenkinsci/oic-auth-plugin/pull/632/files#diff-9c2c6436b143fde652866ea92ee9bec48671b094dbb23ae4805621c5d40ed59bR1514-R1587 currently does I guess ?
|
spotless needs to be applied, otherwise LGTM |
OicProperty extension pointOidcProperty extension point
|
Still need to update the doc... |
As the on disk format has changed, update the compatibleSinceVersion last release was 4.524.v38858a_b_1c6a_4 so 4.525 will be enough.
| /** | ||
| * Represents a property that can be configured for OIDC authentication. | ||
| */ | ||
| public abstract class OidcProperty extends AbstractDescribableImpl<OidcProperty> { |
| import hudson.model.Descriptor; | ||
| import org.pac4j.oidc.config.OidcConfiguration; | ||
|
|
||
| public abstract class OidcPropertyDescriptor extends Descriptor<OidcProperty> implements ExtensionPoint { |
There was a problem hiding this comment.
Did you mean to narrow-override getDescriptor in OidcProperty?
| return new ExecutionImpl(valueSeconds); | ||
| } | ||
|
|
||
| private record ExecutionImpl(int valueSeconds) implements OidcPropertyExecution { |
There was a problem hiding this comment.
Is there some advantage over just using an anonymous inner class?
| } | ||
| } | ||
|
|
||
| @CheckForNull |
| - "pkce" | ||
| - loginQueryParameters: | ||
| items: | ||
| - key: "loginkey1x\"xx@me" |
There was a problem hiding this comment.
(ignore WS, even though it is significant)
|
BTW I find it helpful for both the author and reviewers to mark conversations resolved as promptly as possible, so it is easy to get an overview of all outstanding threads. (Enforcing this in branch protection is too draconian; sometimes there is a conversation you want to keep visible but still go ahead and merge.) |
Cloudbees-internal issue
In the context of CloudBees CI, I needed the ability to implement new
optional behaviour customizing the OIDC configuration and client.
The new extension point, named
OidcProperty, allows to capture a statethrough
OidcPropertyExecutionthat can be used for customize both theOIDC configuration and client.
I have also taken the opportunity to fold some advanced options under
their own class. Ultimately, all advanced fields could be implemented
as
OidcPropertybut for some of them it can be challenging due to theway they are currently integrated in the plugin.
Migrated fields
Screenshots
Testing done
Submitter checklist