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

Add MTLS Aliases endpoints to the discovery endpoint #2440

Merged
merged 4 commits into from
Apr 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -370,4 +370,11 @@ public class DiscoveryConstants {
* If omitted, the default value is false.
*/
public static final String TLS_CLIENT_CERTIFICATE_BOUND_ACCESS_TOKEN = "tls_client_certificate_bound_access_tokens";

/**
* mtls_endpoint_aliases
* OPTIONAL. JSON Object containing a list of the aliases of the mTLS endpoints supported by the
* Authorization Server.
*/
public static final String MTLS_ENDPOINT_ALIASES = "mtls_endpoint_aliases";
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,5 @@ public static boolean isUseEntityIdAsIssuerInOidcDiscovery() {
}
return Boolean.parseBoolean(useEntityIdAsIssuerInDiscovery);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
package org.wso2.carbon.identity.discovery;


import org.wso2.carbon.identity.core.util.IdentityUtil;

import java.util.HashMap;
import java.util.Map;

Expand Down Expand Up @@ -81,6 +83,10 @@ public class OIDProviderConfigResponse {
private String deviceAuthorizationEndpoint;
private String webFingerEndpoint;
private Boolean tlsClientCertificateBoundAccessTokens;
private String mtlsTokenEndpoint;
private String mtlsPushedAuthorizationRequestEndpoint;

private static final String MUTUAL_TLS_ALIASES_ENABLED = "OAuth.MutualTLSAliases.Enabled";
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we need a configuration to enable /disable MTLS? For SaaS deployment can't ee depend on the existing config which we use to control other SaaS specific properties?

Copy link
Contributor Author

@RivinduM RivinduM Apr 30, 2024

Choose a reason for hiding this comment

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

There's no backend config to identify a SaaS deployment. Hence added this config to enable MTLS aliases in the well known response


public String getIssuer() {
return issuer;
Expand Down Expand Up @@ -514,6 +520,16 @@ public void setTlsClientCertificateBoundAccessTokens(Boolean tlsClientCertificat
this.tlsClientCertificateBoundAccessTokens = tlsClientCertificateBoundAccessTokens;
}

public void setMtlsTokenEndpoint(String mtlsTokenEndpoint) {

this.mtlsTokenEndpoint = mtlsTokenEndpoint;
}

public void setMtlsPushedAuthorizationRequestEndpoint(String mtlsPushedAuthorizationRequestEndpoint) {

this.mtlsPushedAuthorizationRequestEndpoint = mtlsPushedAuthorizationRequestEndpoint;
}

public Map<String, Object> getConfigMap() {
Map<String, Object> configMap = new HashMap<String, Object>();
configMap.put(DiscoveryConstants.ISSUER.toLowerCase(), this.issuer);
Expand Down Expand Up @@ -581,6 +597,13 @@ public Map<String, Object> getConfigMap() {
configMap.put(DiscoveryConstants.WEBFINGER_ENDPOINT.toLowerCase(), this.webFingerEndpoint);
configMap.put(DiscoveryConstants.TLS_CLIENT_CERTIFICATE_BOUND_ACCESS_TOKEN.toLowerCase(),
this.tlsClientCertificateBoundAccessTokens);
if (Boolean.parseBoolean(IdentityUtil.getProperty(MUTUAL_TLS_ALIASES_ENABLED))) {
Map<String, String> mtlsAliases = new HashMap<String, String>();
mtlsAliases.put(DiscoveryConstants.TOKEN_ENDPOINT.toLowerCase(), this.mtlsTokenEndpoint);
mtlsAliases.put(DiscoveryConstants.PUSHED_AUTHORIZATION_REQUEST_ENDPOINT.toLowerCase(),
this.mtlsPushedAuthorizationRequestEndpoint);
configMap.put(DiscoveryConstants.MTLS_ENDPOINT_ALIASES, mtlsAliases);
}
return configMap;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,8 @@ public OIDProviderConfigResponse buildOIDProviderConfig(OIDProviderRequest reque
providerConfig.setWebFingerEndpoint(OAuth2Util.OAuthURL.getOidcWebFingerEPUrl());
providerConfig.setTlsClientCertificateBoundAccessTokens(OAuth2Util.getSupportedTokenBindingTypes()
.contains(OAuth2Constants.TokenBinderType.CERTIFICATE_BASED_TOKEN_BINDER));
providerConfig.setMtlsTokenEndpoint(OAuth2Util.OAuthURL.getOAuth2MTLSTokenEPUrl());
providerConfig.setMtlsPushedAuthorizationRequestEndpoint(OAuth2Util.OAuthURL.getOAuth2MTLSParEPUrl());
return providerConfig;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,7 @@ public static SubjectType fromValue(String text) {
public static final String RENEW_TOKEN_WITHOUT_REVOKING_EXISTING_ENABLE_CONFIG =
"OAuth.JWT.RenewTokenWithoutRevokingExisting.Enable";
public static final String OAUTH_BUILD_ISSUER_WITH_HOSTNAME = "OAuth.BuildIssuerWithHostname";
public static final String MTLS_HOSTNAME = "OAuth.MutualTLSAliases.Hostname";

public static final String REQUEST_BINDING_TYPE = "request";
public static final String ORG_ID = "org_id";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1466,6 +1466,18 @@ public static String getOAuth2TokenEPUrl() {
return buildUrl(OAUTH2_TOKEN_EP_URL, OAuthServerConfiguration.getInstance()::getOAuth2TokenEPUrl);
}

public static String getOAuth2MTLSParEPUrl() {

return buildUrlWithHostname(OAUTH2_PAR_EP_URL, OAuthServerConfiguration.getInstance()::getOAuth2ParEPUrl,
IdentityUtil.getProperty(OAuthConstants.MTLS_HOSTNAME));
}

public static String getOAuth2MTLSTokenEPUrl() {

return buildUrlWithHostname(OAUTH2_TOKEN_EP_URL, OAuthServerConfiguration.getInstance()::
getOAuth2TokenEPUrl, IdentityUtil.getProperty(OAuthConstants.MTLS_HOSTNAME));
}

/**
* This method is used to get the resolved URL for the OAuth2 Registration Endpoint.
*
Expand Down Expand Up @@ -1642,6 +1654,28 @@ private static String buildUrl(String defaultContext, Supplier<String> getValueF
return buildServiceUrl(defaultContext, oauth2EndpointURLInFile);
}

/**
* Builds a URL with a given context in both the tenant-qualified url supported mode and the legacy mode.
* Returns the absolute URL build from the default context in the tenant-qualified url supported mode. Gives
* precedence to the file configurations in the legacy mode and returns the absolute url build from file
* configuration context.
*
* @param defaultContext Default URL context.
* @param getValueFromFileBasedConfig File-based Configuration.
* @param hostname hostname of the service
* @return Absolute URL.
*/
private static String buildUrlWithHostname(String defaultContext, Supplier<String> getValueFromFileBasedConfig,
String hostname) {

String oauth2EndpointURLInFile = null;
if (getValueFromFileBasedConfig != null) {
oauth2EndpointURLInFile = getValueFromFileBasedConfig.get();
}
return hostname != null ? buildServiceUrlWithHostname(defaultContext, oauth2EndpointURLInFile, hostname) :
buildServiceUrl(defaultContext, oauth2EndpointURLInFile);
}

/**
* Returns the public service url given the default context and the url picked from the configuration based on
* the 'tenant_context.enable_tenant_qualified_urls' mode set in deployment.toml.
Expand Down Expand Up @@ -1673,6 +1707,39 @@ public static String buildServiceUrl(String defaultContext, String oauth2Endpoin
}
}

/**
* Returns the public service url given the default context and the url picked from the configuration based on
* the 'tenant_context.enable_tenant_qualified_urls' mode set in deployment.toml.
*
* @param defaultContext default url context path
* @param oauth2EndpointURLInFile url picked from the file configuration
* @param hostname hostname of the service
* @return absolute public url of the service if 'enable_tenant_qualified_urls' is 'true', else returns the url
* from the file config
*/
public static String buildServiceUrlWithHostname(String defaultContext, String oauth2EndpointURLInFile,
String hostname) {

if (IdentityTenantUtil.isTenantQualifiedUrlsEnabled()) {
try {
String organizationId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getOrganizationId();
return ServiceURLBuilder.create().addPath(defaultContext).setOrganization(organizationId)
.build(hostname).getAbsolutePublicURL();
} catch (URLBuilderException e) {
throw new OAuthRuntimeException("Error while building url for context: " + defaultContext, e);
}
} else if (StringUtils.isNotBlank(oauth2EndpointURLInFile)) {
// Use the value configured in the file.
return oauth2EndpointURLInFile;
}
// Use the default context.
try {
return ServiceURLBuilder.create().addPath(defaultContext).build(hostname).getAbsolutePublicURL();
} catch (URLBuilderException e) {
throw new OAuthRuntimeException("Error while building url for context: " + defaultContext, e);
}
}

private static boolean isNotSuperTenant(String tenantDomain) {

return (StringUtils.isNotBlank(tenantDomain) &&
Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -901,7 +901,7 @@
<carbon.kernel.registry.imp.pkg.version.range>[1.0.1, 2.0.0)</carbon.kernel.registry.imp.pkg.version.range>

<!-- Carbon Identity Framework version -->
<carbon.identity.framework.version>7.1.42</carbon.identity.framework.version>
<carbon.identity.framework.version>7.1.45</carbon.identity.framework.version>
<carbon.identity.framework.imp.pkg.version.range>[5.25.234, 8.0.0)
</carbon.identity.framework.imp.pkg.version.range>

Expand Down
Loading