From bff52518a92847921713d8e12691ce0b5cd0e81d Mon Sep 17 00:00:00 2001 From: piraveena Date: Thu, 22 Jun 2023 17:02:00 +0530 Subject: [PATCH 1/2] Add audit logs improvements --- .../org.wso2.carbon.identity.sso.saml/pom.xml | 5 + .../identity/sso/saml/SAMLSSOConstants.java | 9 ++ .../sso/saml/admin/SAMLSSOConfigAdmin.java | 128 +++++++++++++++++- pom.xml | 10 +- 4 files changed, 145 insertions(+), 7 deletions(-) diff --git a/components/org.wso2.carbon.identity.sso.saml/pom.xml b/components/org.wso2.carbon.identity.sso.saml/pom.xml index 2be37fc79..23affc870 100644 --- a/components/org.wso2.carbon.identity.sso.saml/pom.xml +++ b/components/org.wso2.carbon.identity.sso.saml/pom.xml @@ -293,6 +293,11 @@ slf4j-api test + + com.fasterxml.jackson.core + jackson-databind + provided + org.apache.felix org.apache.felix.scr.ds-annotations diff --git a/components/org.wso2.carbon.identity.sso.saml/src/main/java/org/wso2/carbon/identity/sso/saml/SAMLSSOConstants.java b/components/org.wso2.carbon.identity.sso.saml/src/main/java/org/wso2/carbon/identity/sso/saml/SAMLSSOConstants.java index 48bdedd58..0152444d1 100644 --- a/components/org.wso2.carbon.identity.sso.saml/src/main/java/org/wso2/carbon/identity/sso/saml/SAMLSSOConstants.java +++ b/components/org.wso2.carbon.identity.sso.saml/src/main/java/org/wso2/carbon/identity/sso/saml/SAMLSSOConstants.java @@ -200,6 +200,15 @@ private StatusCodes() { } } + /** + * Group the constants related to logs. + */ + public static class LogConstants { + + public static final String CREATE_SAML_APPLICATION = "CREATE SAML APPLICATION"; + public static final String DELETE_SAML_APPLICATION = "DELETE SAML APPLICATION"; + } + public static class SingleLogoutCodes { public static final String LOGOUT_USER = "urn:oasis:names:tc:SAML:2.0:logout:user"; public static final String LOGOUT_ADMIN = "urn:oasis:names:tc:SAML:2.0:logout:admin"; diff --git a/components/org.wso2.carbon.identity.sso.saml/src/main/java/org/wso2/carbon/identity/sso/saml/admin/SAMLSSOConfigAdmin.java b/components/org.wso2.carbon.identity.sso.saml/src/main/java/org/wso2/carbon/identity/sso/saml/admin/SAMLSSOConfigAdmin.java index 81548aa71..3eba89918 100644 --- a/components/org.wso2.carbon.identity.sso.saml/src/main/java/org/wso2/carbon/identity/sso/saml/admin/SAMLSSOConfigAdmin.java +++ b/components/org.wso2.carbon.identity.sso.saml/src/main/java/org/wso2/carbon/identity/sso/saml/admin/SAMLSSOConfigAdmin.java @@ -18,6 +18,8 @@ package org.wso2.carbon.identity.sso.saml.admin; +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -25,6 +27,8 @@ import org.wso2.carbon.base.MultitenantConstants; import org.wso2.carbon.context.CarbonContext; import org.wso2.carbon.core.util.KeyStoreManager; +import org.wso2.carbon.identity.application.authentication.framework.model.AuthenticatedUser; +import org.wso2.carbon.identity.application.mgt.ApplicationMgtUtil; import org.wso2.carbon.identity.base.IdentityException; import org.wso2.carbon.identity.core.model.SAMLSSOServiceProviderDO; import org.wso2.carbon.identity.core.util.IdentityTenantUtil; @@ -32,6 +36,7 @@ import org.wso2.carbon.identity.sp.metadata.saml2.exception.InvalidMetadataException; import org.wso2.carbon.identity.sp.metadata.saml2.util.Parser; import org.wso2.carbon.identity.sso.saml.Error; +import org.wso2.carbon.identity.sso.saml.SAMLSSOConstants; import org.wso2.carbon.identity.sso.saml.SSOServiceProviderConfigManager; import org.wso2.carbon.identity.sso.saml.dto.SAMLSSOServiceProviderDTO; import org.wso2.carbon.identity.sso.saml.dto.SAMLSSOServiceProviderInfoDTO; @@ -41,10 +46,18 @@ import org.wso2.carbon.identity.sso.saml.util.SAMLSSOUtil; import org.wso2.carbon.registry.core.Registry; import org.wso2.carbon.registry.core.session.UserRegistry; +import org.wso2.carbon.user.core.util.UserCoreUtil; +import org.wso2.carbon.utils.AuditLog; import java.security.KeyStore; import java.security.cert.CertificateException; +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; +import static org.wso2.carbon.identity.application.authentication.framework.util.FrameworkConstants.LogConstants.USER; +import static org.wso2.carbon.identity.application.mgt.ApplicationConstants.LogConstants.TARGET_APPLICATION; +import static org.wso2.carbon.identity.central.log.mgt.utils.LoggerUtils.triggerAuditLogEvent; import static org.wso2.carbon.identity.sso.saml.Error.CONFLICTING_SAML_ISSUER; import static org.wso2.carbon.identity.sso.saml.Error.INVALID_REQUEST; @@ -86,8 +99,22 @@ public boolean addRelyingPartyServiceProvider(SAMLSSOServiceProviderDTO serviceP log.error(message); return false; } - return IdentitySAMLSSOServiceComponentHolder.getInstance().getSAMLSSOServiceProviderManager() + boolean isSuccess = IdentitySAMLSSOServiceComponentHolder.getInstance().getSAMLSSOServiceProviderManager() .addServiceProvider(serviceProviderDO, tenantId); + if (isSuccess && ApplicationMgtUtil.isLegacyAuditLogsDisabledInAppMgt()) { + Optional initiatorId = getInitiatorId(); + if (initiatorId.isPresent()) { + AuditLog.AuditLogBuilder auditLogBuilder = new AuditLog.AuditLogBuilder( + initiatorId.get(), USER, + issuer, TARGET_APPLICATION, + SAMLSSOConstants.LogConstants.CREATE_SAML_APPLICATION) + .data(buildSPData(serviceProviderDO)); + triggerAuditLogEvent(auditLogBuilder, true); + } else { + log.error("Error getting the logged in userId"); + } + } + return isSuccess; } catch (IdentityException e) { String message = "Error obtaining a registry for adding a new service provider"; throw new IdentityException(message, e); @@ -140,7 +167,21 @@ public SAMLSSOServiceProviderDTO addSAMLServiceProvider(SAMLSSOServiceProviderDT String message = "A Service Provider with the name: " + issuer + " is already loaded from the file system."; throw buildClientException(CONFLICTING_SAML_ISSUER, message); } - return persistSAMLServiceProvider(serviceProviderDO); + SAMLSSOServiceProviderDTO samlssoServiceProviderDTO = persistSAMLServiceProvider(serviceProviderDO); + if (ApplicationMgtUtil.isLegacyAuditLogsDisabledInAppMgt()) { + Optional initiatorId = getInitiatorId(); + if (initiatorId.isPresent()) { + AuditLog.AuditLogBuilder auditLogBuilder = new AuditLog.AuditLogBuilder( + initiatorId.get(), USER, + issuer, TARGET_APPLICATION, + SAMLSSOConstants.LogConstants.CREATE_SAML_APPLICATION) + .data(buildSPData(serviceProviderDO)); + triggerAuditLogEvent(auditLogBuilder, true); + } else { + log.error("Error getting the logged in userId"); + } + } + return samlssoServiceProviderDTO; } catch (IdentitySAML2ClientException e){ throw e; } catch (IdentityException e) { @@ -149,6 +190,47 @@ public SAMLSSOServiceProviderDTO addSAMLServiceProvider(SAMLSSOServiceProviderDT } } + private static Map buildSPData(SAMLSSOServiceProviderDO app) { + + if (app == null) { + return new HashMap<>(); + } + + Gson gson = new Gson(); + String json = gson.toJson(app); + return gson.fromJson(json, new TypeToken>() { + }.getType()); + } + + /** + * This method is used to retrieve logged in tenant domain. + * @return logged in tenant domain. + */ + private String getLoggedInTenantDomain() { + + if (!IdentityTenantUtil.isTenantedSessionsEnabled()) { + return getTenantDomain(); + } + return IdentityTenantUtil.getTenantDomainFromContext(); + } + + private Optional getLoggedInUser(String tenantDomain) { + + String tenantAwareLoggedInUsername = CarbonContext.getThreadLocalCarbonContext().getUsername(); + return Optional.ofNullable(tenantAwareLoggedInUsername) + .filter(StringUtils::isNotEmpty) + .map(username -> buildAuthenticatedUser(username, tenantDomain)); + } + + private AuthenticatedUser buildAuthenticatedUser(String tenantAwareUser, String tenantDomain) { + + AuthenticatedUser user = new AuthenticatedUser(); + user.setUserName(UserCoreUtil.removeDomainFromName(tenantAwareUser)); + user.setTenantDomain(tenantDomain); + user.setUserStoreDomain(IdentityUtil.extractDomainFromName(tenantAwareUser)); + return user; + } + /** * Update a service provider if it exists. * @@ -283,8 +365,21 @@ public SAMLSSOServiceProviderDTO uploadRelyingPartyServiceProvider(String metada throw new IdentityException("Error occurred while setting certificate and alias", e); } } - - return persistSAMLServiceProvider(samlssoServiceProviderDO); + SAMLSSOServiceProviderDTO samlssoServiceProviderDTO = persistSAMLServiceProvider(samlssoServiceProviderDO); + if (ApplicationMgtUtil.isLegacyAuditLogsDisabledInAppMgt()) { + Optional initiatorId = getInitiatorId(); + if (initiatorId.isPresent()) { + AuditLog.AuditLogBuilder auditLogBuilder = new AuditLog.AuditLogBuilder( + initiatorId.get(), USER, + samlssoServiceProviderDO.getIssuer(), TARGET_APPLICATION, + SAMLSSOConstants.LogConstants.CREATE_SAML_APPLICATION) + .data(buildSPData(samlssoServiceProviderDO)); + triggerAuditLogEvent(auditLogBuilder, true); + } else { + log.error("Error getting the logged in userId"); + } + } + return samlssoServiceProviderDTO; } /** @@ -599,13 +694,36 @@ public SAMLSSOServiceProviderInfoDTO getServiceProviders() throws IdentityExcept */ public boolean removeServiceProvider(String issuer) throws IdentityException { try { - return IdentitySAMLSSOServiceComponentHolder.getInstance() + boolean isSuccess = IdentitySAMLSSOServiceComponentHolder.getInstance() .getSAMLSSOServiceProviderManager().removeServiceProvider(issuer, tenantId); + if (isSuccess) { + if (ApplicationMgtUtil.isLegacyAuditLogsDisabledInAppMgt()) { + Optional initiatorId = getInitiatorId(); + if (initiatorId.isPresent()) { + AuditLog.AuditLogBuilder auditLogBuilder = new AuditLog.AuditLogBuilder(initiatorId.get(), + USER, issuer, TARGET_APPLICATION, + SAMLSSOConstants.LogConstants.DELETE_SAML_APPLICATION); + triggerAuditLogEvent(auditLogBuilder, true); + } else { + log.error("Error getting the logged in userId"); + } + } + } + return isSuccess; } catch (IdentityException e) { throw new IdentityException("Error removing a Service Provider with issuer: " + issuer, e); } } + private Optional getInitiatorId(){ + + return Optional.ofNullable(CarbonContext.getThreadLocalCarbonContext().getUserId()) + .filter(StringUtils::isNotBlank) + .or(() -> getLoggedInUser(getLoggedInTenantDomain()) + .map(loggedInUser -> IdentityUtil.getInitiatorId(loggedInUser.getUserName(), + getLoggedInTenantDomain()))); + } + protected String getTenantDomain() { return CarbonContext.getThreadLocalCarbonContext().getTenantDomain(); diff --git a/pom.xml b/pom.xml index 805745413..26d95e509 100644 --- a/pom.xml +++ b/pom.xml @@ -261,6 +261,11 @@ axis2-client ${axis2.wso2.version} + + com.fasterxml.jackson.core + jackson-databind + ${com.fasterxml.jackson.version} + org.wso2.carbon.identity.inbound.auth.saml2 org.wso2.carbon.identity.sso.saml.common @@ -450,9 +455,9 @@ - 4.9.0 + 4.9.10 4.9.0 - 5.25.247 + 5.25.258 [5.25.234, 7.0.0) 1.0.0 @@ -470,6 +475,7 @@ 1.2.0.wso2v1 1.6.1.wso2v12 2.9.4.wso2v1 + 2.13.2 3.2.0 2.3.1 From c8a27509a9dfdc8b0906e5a745dc6dfc6f887a12 Mon Sep 17 00:00:00 2001 From: Chamath Samarawickrama Date: Wed, 26 Jul 2023 15:37:50 +0530 Subject: [PATCH 2/2] fix formatting --- .../wso2/carbon/identity/sso/saml/admin/SAMLSSOConfigAdmin.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/org.wso2.carbon.identity.sso.saml/src/main/java/org/wso2/carbon/identity/sso/saml/admin/SAMLSSOConfigAdmin.java b/components/org.wso2.carbon.identity.sso.saml/src/main/java/org/wso2/carbon/identity/sso/saml/admin/SAMLSSOConfigAdmin.java index 3eba89918..5d7ea32bc 100644 --- a/components/org.wso2.carbon.identity.sso.saml/src/main/java/org/wso2/carbon/identity/sso/saml/admin/SAMLSSOConfigAdmin.java +++ b/components/org.wso2.carbon.identity.sso.saml/src/main/java/org/wso2/carbon/identity/sso/saml/admin/SAMLSSOConfigAdmin.java @@ -715,7 +715,7 @@ public boolean removeServiceProvider(String issuer) throws IdentityException { } } - private Optional getInitiatorId(){ + private Optional getInitiatorId() { return Optional.ofNullable(CarbonContext.getThreadLocalCarbonContext().getUserId()) .filter(StringUtils::isNotBlank)