Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proxy jwt bearer to support corporate trust #3309

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from

Conversation

strehle
Copy link
Member

@strehle strehle commented Feb 25, 2025

Feature: Forward JWT bearer grant to trusted identity provider. Very similar to password grant.

Refactorings done, so that REST method to call trusted identity provider is re-used (from password grant) .
Reason: JWT bearer and Password grant need similar checks and parameters.

Why:
In a community CF usage the trust maybe is done origin by origin.
trust-by-origin

SAP uses the corporate origin trust model, so that access to CF is granted by a dedicated IdP which is controlled by SAP. Customers control their own corporate IdP and therefore the authentication requests need to be forward through the corporate Origin to the customer IdP. This model was created with #2505
See
trust-by-corporate-origin

@strehle strehle linked an issue Feb 25, 2025 that may be closed by this pull request
@strehle strehle force-pushed the proxyJwtBearer branch 5 times, most recently from 33caea5 to 8276e37 Compare February 27, 2025 10:44
@strehle strehle marked this pull request as ready for review February 27, 2025 11:04
@strehle strehle changed the title [WIP] Proxy jwt bearer to support corporate trust Proxy jwt bearer to support corporate trust Feb 27, 2025
try {
oidcMetadataFetcher.fetchMetadataAndUpdateDefinition(definition);
} catch (OidcMetadataFetchingException e) {
logger.warn("OidcMetadataFetchingException", e);
}
}

public IdentityProvider<OIDCIdentityProviderDefinition> getOidcProxyTokenExchange(HttpServletRequest request) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we improve the name of this method? IMO, it indicates that we already perform a token exchange, even though that is not the case.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for example: "getOidcProxyIdpForTokenExchange"

if (clientAuth == null) {
throw new BadCredentialsException("No client authentication found.");
}
List<String> allowedProviders = null;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please eliminate this variable by directly returning the result or null

@@ -254,7 +256,17 @@ protected Authentication attemptTokenAuthentication(HttpServletRequest request,
log.debug(GRANT_TYPE_JWT_BEARER + " found. Attempting authentication with assertion");
String assertion = request.getParameter("assertion");
if (assertion != null && externalOAuthAuthenticationManager != null) {
log.debug("Attempting OIDC JWT authentication for token endpoint.");
IdentityProvider<OIDCIdentityProviderDefinition> oidcProxy = externalOAuthAuthenticationManager.getOidcProxyTokenExchange(request);
if (oidcProxy != null) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do I understand the general idea correctly?

We receive a JWT bearer request with a login_hint parameter. If the IdP described by that param has tokenExchangeEnabled, we forward the incoming JWT to the corporate IdP (also via a JWT bearer grant).

In contrast to that: if the flag is not enabled, we directly try to issue an access token for the user described by the incoming JWT.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The "regular" JWT bearer flow against UAA can still be used if no login_hint parameter is passed in the request.

@@ -32,6 +32,7 @@ public class OIDCIdentityProviderDefinition extends AbstractExternalOAuthIdentit
private URL discoveryUrl;
private boolean passwordGrantEnabled;
private boolean setForwardHeader;
private Boolean tokenExchangeEnabled;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you please add a Javadoc comment that describes the purpose of this flag?

} else {
log.debug("Attempting OIDC JWT authentication for token endpoint.");
}

ExternalOAuthCodeToken token = new ExternalOAuthCodeToken(null, null, null, assertion, null, null);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it make sense to introduce a static factory method here? e.g. ExternalOAuthCodeToken.forAssertion(...)

return retrieveTokenExchangeIdp(UaaLoginHint.parseRequestParameter(request.getParameter("login_hint")), getAllowedProviders());
}

public List<String> getAllowedProviders() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we make this method static?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Development

Successfully merging this pull request may close these issues.

Proxy / Forward JWT Bearer in UAA to allow central trust anchor
2 participants