Skip to content

Commit

Permalink
Update APIs to support custom authentication management.
Browse files Browse the repository at this point in the history
  • Loading branch information
Thisara-Welmilla committed Nov 11, 2024
1 parent a2fb35c commit cfc2832
Show file tree
Hide file tree
Showing 4 changed files with 119 additions and 62 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,18 @@ public enum ErrorMessage {
ERROR_CODE_ERROR_LISTING_TRUSTED_TOKEN_ISSUERS("60021",
"Unable to list existing trusted token issuers.",
"Server encountered an error while listing the trusted token issuers."),
ERROR_CODE_ENDPOINT_PROVIDED_FOR_SYSTEM_AUTH("60039", "Endpoint provided for the system " +
"defined federated authenticator", "No endpoint configuration must be provided for " +
"the system defined federated authenticators %s."),
ERROR_CODE_PROPERTIES_PROVIDED_FOR_USER_AUTH("60040", "Properties provided for the user " +
"defined federated authenticator", "No properties must be provided for the user defined " +
"federated authenticators %s."),
ERROR_CODE_NO_ENDPOINT_PROVIDED("60041", "No endpoint provided.", "Endpoint " +
"configuration must be provided for the user defined federated authenticators %s."),
ERROR_CODE_NON_DECODABLE_AUTH_ID("60042", "Non-decodable authenticator ID.",
"Unable to decode the provided authenticator ID %s."),
ERROR_CODE_NO_SYSTEM_AUTHENTICATOR_FOUND("60043", "No system authenticator found.",
"No system authenticator found for the provided authenticator Id."),

// Server Error starting from 650xx.
ERROR_CODE_ERROR_ADDING_IDP("65002",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,11 @@ public Endpoint uri(String uri) {
return this;
}

@ApiModelProperty(example = "https://abc.com/token", value = "")
@ApiModelProperty(example = "https://abc.com/token", required = true, value = "")
@JsonProperty("uri")
@Valid @Pattern(regexp="^https?://.+")
@Valid
@NotNull(message = "Property uri cannot be null.")
@Pattern(regexp="^https?://.+")
public String getUri() {
return uri;
}
Expand All @@ -62,9 +64,11 @@ public Endpoint authentication(AuthenticationType authentication) {
return this;
}

@ApiModelProperty(value = "")
@ApiModelProperty(required = true, value = "")
@JsonProperty("authentication")
@Valid
@NotNull(message = "Property authentication cannot be null.")

public AuthenticationType getAuthentication() {
return authentication;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,6 @@
import org.apache.cxf.jaxrs.ext.search.PrimitiveStatement;
import org.apache.cxf.jaxrs.ext.search.SearchCondition;
import org.apache.cxf.jaxrs.ext.search.SearchContext;
import org.wso2.carbon.identity.action.management.model.AuthProperty;
import org.wso2.carbon.identity.action.management.model.EndpointConfig;
import org.wso2.carbon.identity.api.server.common.ContextLoader;
import org.wso2.carbon.identity.api.server.common.FileContent;
import org.wso2.carbon.identity.api.server.common.Util;
Expand Down Expand Up @@ -1764,42 +1762,52 @@ private MetaOutboundConnector createMetaOutboundConnector(ProvisioningConnectorC
}

private void updateFederatedAuthenticatorConfig(IdentityProvider idp, FederatedAuthenticatorRequest
federatedAuthenticatorRequest, boolean isNewFederatedAuthenticator) {
federatedAuthenticatorRequest, boolean isNewFederatedAuthenticator)
throws IdentityProviderManagementClientException {

if (federatedAuthenticatorRequest != null) {
List<FederatedAuthenticator> federatedAuthenticators = federatedAuthenticatorRequest.getAuthenticators();
String defaultAuthenticator = federatedAuthenticatorRequest.getDefaultAuthenticatorId();
FederatedAuthenticatorConfig defaultAuthConfig = null;
List<FederatedAuthenticatorConfig> fedAuthConfigs = new ArrayList<>();
for (FederatedAuthenticator authenticator : federatedAuthenticators) {
FederatedAuthenticatorConfig authConfig = new FederatedAuthenticatorConfig();
authConfig.setName(base64URLDecode(authenticator.getAuthenticatorId()));
authConfig.setDisplayName(getDisplayNameOfAuthenticator(authConfig.getName()));
authConfig.setEnabled(authenticator.getIsEnabled());

String authenticatorName = getDecodedAuthName(authenticator.getAuthenticatorId());
FederatedAuthenticatorConfig authConfig;
String definedByType = null;
if (authenticator.getDefinedBy() != null) {
definedByType = authenticator.getDefinedBy().toString();
}
authConfig.setDefinedByType(resolveDefinedByType(authConfig.getName(),
definedByType, isNewFederatedAuthenticator));

List<org.wso2.carbon.identity.api.server.idp.v1.model.Property> authProperties =
authenticator.getProperties();
if (IdentityApplicationConstants.Authenticator.SAML2SSO.FED_AUTH_NAME.equals(authConfig.getName())) {
validateSamlMetadata(authProperties);
}
if (authProperties != null) {
if (!areAllDistinct(authProperties)) {
throw handleException(Response.Status.BAD_REQUEST,
Constants.ErrorMessage.ERROR_CODE_INVALID_INPUT, " Duplicate properties are found in " +
"the request.");
definedByType = resolveDefinedByType(authenticatorName, definedByType, isNewFederatedAuthenticator)
.toString();
if (DefinedByType.SYSTEM.toString().equals(definedByType)) {
authConfig = createSystemDefinedFederatedAuthenticator(authenticatorName,
authenticator.getEndpoint());
List<org.wso2.carbon.identity.api.server.idp.v1.model.Property> authProperties =
authenticator.getProperties();
if (IdentityApplicationConstants.Authenticator.SAML2SSO.FED_AUTH_NAME
.equals(authConfig.getName())) {
validateSamlMetadata(authProperties);
}
List<Property> properties = authProperties.stream()
.map(propertyToInternal)
.collect(Collectors.toList());
authConfig.setProperties(properties.toArray(new Property[0]));
if (authProperties != null) {
if (!areAllDistinct(authProperties)) {
throw handleException(Response.Status.BAD_REQUEST,
Constants.ErrorMessage.ERROR_CODE_INVALID_INPUT, " Duplicate properties are found" +
" in the request.");
}
List<Property> properties = authProperties.stream()
.map(propertyToInternal)
.collect(Collectors.toList());
authConfig.setProperties(properties.toArray(new Property[0]));
}
} else {
authConfig = createUserDefinedFederatedAuthenticator(authenticatorName, authenticator.getEndpoint(),
authenticator.getProperties());
}

authConfig.setName(authenticatorName);
authConfig.setDisplayName(getDisplayNameOfAuthenticator(authConfig.getName()));
authConfig.setEnabled(authenticator.getIsEnabled());
fedAuthConfigs.add(authConfig);

if (StringUtils.equals(defaultAuthenticator, authenticator.getAuthenticatorId())) {
Expand Down Expand Up @@ -2085,7 +2093,8 @@ private void updateGroups(IdentityProvider idp, List<IdPGroup> groups) {
return apiProperty;
};

private IdentityProvider createIDP(IdentityProviderPOSTRequest identityProviderPOSTRequest) {
private IdentityProvider createIDP(IdentityProviderPOSTRequest identityProviderPOSTRequest)
throws IdentityProviderManagementClientException {

String idpJWKSUri = null;
IdentityProvider idp = new IdentityProvider();
Expand Down Expand Up @@ -2845,20 +2854,30 @@ private ProvisioningConnectorConfig createProvisioningConnectorConfig(String out
* @return Federated authenticator config of the specified ID.
*/
private FederatedAuthenticatorConfig updateFederatedAuthenticatorConfig(String federatedAuthenticatorId,
FederatedAuthenticatorPUTRequest
authenticator) {
FederatedAuthenticatorPUTRequest authenticator) throws IdentityProviderManagementClientException {

String authenticatorName = base64URLDecode(federatedAuthenticatorId);
String authenticatorName = getDecodedAuthName(federatedAuthenticatorId);
FederatedAuthenticatorConfig authConfig;
DefinedByType definedByType = null;
String definedByType = null;
if (authenticator.getDefinedBy() != null) {
definedByType = authenticator.getDefinedBy().toString();
}
definedByType = resolveDefinedByType(authenticatorName, definedByType.toString(), false);
if (definedByType == DefinedByType.SYSTEM) {
authConfig = createSystemDefinedFederatedAuthenticator(authenticator, authenticatorName);
definedByType = resolveDefinedByType(authenticatorName, definedByType, false).toString();
if (DefinedByType.SYSTEM.toString().equals(definedByType)) {
authConfig = createSystemDefinedFederatedAuthenticator(authenticatorName, authenticator.getEndpoint());
if (IdentityApplicationConstants.Authenticator.SAML2SSO.FED_AUTH_NAME.equals(authenticatorName)) {
validateSamlMetadata(authenticator.getProperties());
}
if (IdentityApplicationConstants.Authenticator.OIDC.FED_AUTH_NAME.equals(authenticatorName)) {
validateDuplicateOpenIDConnectScopes(authenticator.getProperties());
validateDefaultOpenIDConnectScopes(authenticator.getProperties());
}
List<Property> properties = authenticator.getProperties().stream().map(propertyToInternal)
.collect(Collectors.toList());
authConfig.setProperties(properties.toArray(new Property[0]));
} else {
authConfig = createUserDefinedFederatedAuthenticator(authenticator);
authConfig = createUserDefinedFederatedAuthenticator(authenticatorName, authenticator.getEndpoint(),
authenticator.getProperties());
}
authConfig.setName(authenticatorName);
authConfig.setDisplayName(getDisplayNameOfAuthenticator(authenticatorName));
Expand All @@ -2868,38 +2887,53 @@ private FederatedAuthenticatorConfig updateFederatedAuthenticatorConfig(String f
}

private FederatedAuthenticatorConfig createSystemDefinedFederatedAuthenticator(
FederatedAuthenticatorPUTRequest authenticator, String authenticatorName) {
String authenticatorName, Endpoint endpoint) throws IdentityProviderManagementClientException {

FederatedAuthenticatorConfig authConfig = new FederatedAuthenticatorConfig();
authConfig.setDefinedByType(DefinedByType.SYSTEM);

List<org.wso2.carbon.identity.api.server.idp.v1.model.Property> authProperties = authenticator.getProperties();
if (IdentityApplicationConstants.Authenticator.SAML2SSO.FED_AUTH_NAME.equals(authenticatorName)) {
validateSamlMetadata(authProperties);
if (endpoint != null) {
Constants.ErrorMessage error = Constants.ErrorMessage.ERROR_CODE_ENDPOINT_PROVIDED_FOR_SYSTEM_AUTH;
throw new IdentityProviderManagementClientException(error.getCode(),
String.format(error.getDescription(), authenticatorName));
}
if (IdentityApplicationConstants.Authenticator.OIDC.FED_AUTH_NAME.equals(authenticatorName)) {
validateDuplicateOpenIDConnectScopes(authProperties);
validateDefaultOpenIDConnectScopes(authProperties);

if (ApplicationAuthenticatorService.getInstance()
.getFederatedAuthenticatorByName((authenticatorName)) == null) {
Constants.ErrorMessage error = Constants.ErrorMessage.ERROR_CODE_NO_SYSTEM_AUTHENTICATOR_FOUND;
throw new IdentityProviderManagementClientException(error.getCode(), error.getDescription());
}
List<Property> properties = authProperties.stream().map(propertyToInternal).collect(Collectors.toList());
authConfig.setProperties(properties.toArray(new Property[0]));

FederatedAuthenticatorConfig authConfig = new FederatedAuthenticatorConfig();
authConfig.setDefinedByType(DefinedByType.SYSTEM);

return authConfig;
}

private UserDefinedFederatedAuthenticatorConfig createUserDefinedFederatedAuthenticator(
FederatedAuthenticatorPUTRequest authenticator) {
String authenticatorName, Endpoint endpoint, List<org.wso2.carbon.identity.api.server.idp.v1.model.Property>
properties) throws IdentityProviderManagementClientException {

if (properties == null || !properties.isEmpty()) {
Constants.ErrorMessage error = Constants.ErrorMessage.ERROR_CODE_PROPERTIES_PROVIDED_FOR_USER_AUTH;
throw new IdentityProviderManagementClientException(error.getCode(),
String.format(error.getDescription(), authenticatorName));
}

if (endpoint == null || endpoint.getUri() == null || endpoint.getAuthentication() == null) {
Constants.ErrorMessage error = Constants.ErrorMessage.ERROR_CODE_NO_ENDPOINT_PROVIDED;
throw new IdentityProviderManagementClientException(error.getCode(),
String.format(error.getDescription(), authenticatorName));
}

UserDefinedFederatedAuthenticatorConfig userDefinedAuthConfig = new UserDefinedFederatedAuthenticatorConfig();
userDefinedAuthConfig.setDefinedByType(DefinedByType.USER);

UserDefinedAuthenticatorEndpointConfig.UserDefinedAuthenticatorEndpointConfigBuilder endpointConfigBuilder =
new UserDefinedAuthenticatorEndpointConfig.UserDefinedAuthenticatorEndpointConfigBuilder();
endpointConfigBuilder.uri(authenticator.getEndpoint().getUri());
endpointConfigBuilder.authenticationType(authenticator.getEndpoint().getAuthentication().getType().toString());
endpointConfigBuilder.authenticationProperties(authenticator.getEndpoint().getAuthentication().getProperties()
endpointConfigBuilder.uri(endpoint.getUri());
endpointConfigBuilder.authenticationType(endpoint.getAuthentication().getType().toString());
endpointConfigBuilder.authenticationProperties(endpoint.getAuthentication().getProperties()
.entrySet().stream().collect(Collectors.toMap(
Map.Entry::getKey, entry -> entry.getValue().toString())));
userDefinedAuthConfig.setEndpointConfig(endpointConfigBuilder.build());
return userDefinedAuthConfig;
}

Expand Down Expand Up @@ -3136,20 +3170,14 @@ private void resolveEndpointConfiguration(FederatedAuthenticator authenticator,
try {
UserDefinedFederatedAuthenticatorConfig userDefinedConfig =
(UserDefinedFederatedAuthenticatorConfig) config;
EndpointConfig endpointConfig = userDefinedConfig.getEndpointConfig().getEndpointConfig();
UserDefinedAuthenticatorEndpointConfig endpointConfig = userDefinedConfig.getEndpointConfig();

AuthenticationType authenticationType = new AuthenticationType();
authenticationType.setType(AuthenticationType.TypeEnum.fromValue(endpointConfig
authenticationType.setType(AuthenticationType.TypeEnum.fromValue(endpointConfig.getEndpointConfig()
.getAuthentication().getType().toString()));
Map<String, Object> authenticatorProperties = new HashMap<>();
for (AuthProperty prop: endpointConfig.getAuthentication().getProperties()) {
authenticatorProperties.put(prop.getName(), prop.getValue());
}
authenticationType.setProperties(authenticatorProperties);

Endpoint endpoint = new Endpoint();
endpoint.setAuthentication(authenticationType);
endpoint.setUri(userDefinedConfig.getEndpointConfig().getEndpointConfig().getUri());
endpoint.setUri(endpointConfig.getEndpointConfig().getUri());
authenticator.setEndpoint(endpoint);
} catch (ClassCastException e) {
throw new IdentityProviderManagementServerException("Error occurred while resolving endpoint " +
Expand Down Expand Up @@ -3924,4 +3952,15 @@ private void validateSystemReservedIDP(String idpName) throws IdentityProviderMa
"a system reserved name.", idpName));
}
}

private String getDecodedAuthName(String authId) throws IdentityProviderManagementClientException {

try {
return base64URLDecode(authId);
} catch (IllegalArgumentException e) {
Constants.ErrorMessage error = Constants.ErrorMessage.ERROR_CODE_NON_DECODABLE_AUTH_ID;
throw new IdentityProviderManagementClientException(error.getCode(),
String.format(error.getDescription(), authId));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2825,7 +2825,6 @@ components:
items:
$ref: '#/components/schemas/MetaProperty'
endpoint:
endpoint:
$ref: '#/components/schemas/Endpoint'
FederatedAuthenticatorRequest:
type: object
Expand Down Expand Up @@ -2884,6 +2883,9 @@ components:
$ref: '#/components/schemas/Endpoint'
Endpoint:
type: object
required:
- uri
- authentication
properties:
uri:
type: string
Expand Down

0 comments on commit cfc2832

Please sign in to comment.