From d7355cef55d645f6d9c7e5405b66a6dac7e21f22 Mon Sep 17 00:00:00 2001 From: inoshperera Date: Thu, 5 Mar 2020 20:56:19 +0530 Subject: [PATCH 1/2] Proxied API calls for sub tenant using super tenant details --- .../framework/AuthenticationInfo.java | 9 ++++ .../authenticator/framework/Constants.java | 1 + .../framework/WebappAuthenticationValve.java | 45 ++++++++++++++++++- .../authenticator/OAuthAuthenticator.java | 6 +++ 4 files changed, 60 insertions(+), 1 deletion(-) diff --git a/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/AuthenticationInfo.java b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/AuthenticationInfo.java index d7a0ec1c61..674728491f 100644 --- a/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/AuthenticationInfo.java +++ b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/AuthenticationInfo.java @@ -30,6 +30,7 @@ public class AuthenticationInfo { private String username; private String tenantDomain; private int tenantId = -1; + private boolean isSuperTenantAdmin; public WebappAuthenticator.Status getStatus() { return status; @@ -71,4 +72,12 @@ public class AuthenticationInfo { public void setTenantId(int tenantId) { this.tenantId = tenantId; } + + public boolean isSuperTenantAdmin() { + return isSuperTenantAdmin; + } + + public void setSuperTenantAdmin(boolean superTenantAdmin) { + isSuperTenantAdmin = superTenantAdmin; + } } diff --git a/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/Constants.java b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/Constants.java index 26166e864a..af69a320ea 100644 --- a/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/Constants.java +++ b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/Constants.java @@ -22,6 +22,7 @@ public final class Constants { public static final String AUTHORIZATION_HEADER_PREFIX_BEARER = "Bearer"; public static final String NO_MATCHING_AUTH_SCHEME = "noMatchedAuthScheme"; + public static final String PROXY_TENANT_ID = "ProxyTenantId"; public static final class HTTPHeaders { private HTTPHeaders() { diff --git a/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/WebappAuthenticationValve.java b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/WebappAuthenticationValve.java index 4b596c4ed3..16bf4d695e 100644 --- a/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/WebappAuthenticationValve.java +++ b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/WebappAuthenticationValve.java @@ -27,6 +27,9 @@ import org.owasp.encoder.Encode; import org.wso2.carbon.context.PrivilegedCarbonContext; import org.wso2.carbon.tomcat.ext.valves.CarbonTomcatValve; import org.wso2.carbon.tomcat.ext.valves.CompositeValve; +import org.wso2.carbon.user.api.Tenant; +import org.wso2.carbon.user.api.UserStoreException; +import org.wso2.carbon.user.core.service.RealmService; import org.wso2.carbon.webapp.authenticator.framework.authenticator.WebappAuthenticator; import org.wso2.carbon.webapp.authenticator.framework.authorizer.WebappTenantAuthorizer; @@ -60,6 +63,8 @@ public class WebappAuthenticationValve extends CarbonTomcatValve { WebappAuthenticator.Status status = WebappTenantAuthorizer.authorize(request, authenticationInfo); authenticationInfo.setStatus(status); } + + Tenant tenant = null; if (authenticationInfo.getTenantId() != -1) { try { PrivilegedCarbonContext.startTenantFlow(); @@ -67,10 +72,48 @@ public class WebappAuthenticationValve extends CarbonTomcatValve { privilegedCarbonContext.setTenantId(authenticationInfo.getTenantId()); privilegedCarbonContext.setTenantDomain(authenticationInfo.getTenantDomain()); privilegedCarbonContext.setUsername(authenticationInfo.getUsername()); - this.processRequest(request, response, compositeValve, authenticationInfo); + if (authenticationInfo.isSuperTenantAdmin()) { + // If this is a call from super admin to an API and the ProxyTenantId is also + // present, this is a call that is made with super admin credentials to call + // an API on behalf of another tenant. Hence the actual tenants, details are + // resolved instead of calling processRequest. + int tenantId = Integer.valueOf(request.getHeader(Constants.PROXY_TENANT_ID)); + RealmService realmService = (RealmService) PrivilegedCarbonContext + .getThreadLocalCarbonContext().getOSGiService(RealmService.class, null); + if (realmService == null) { + String msg = "RealmService is not initialized"; + log.error(msg); + AuthenticationFrameworkUtil.handleResponse(request, response, + HttpServletResponse.SC_BAD_REQUEST, msg); + return; + } + tenant = realmService.getTenantManager().getTenant(tenantId); + } else { + this.processRequest(request, response, compositeValve, authenticationInfo); + } + } catch (UserStoreException e) { + String msg = "Could not locate the tenant"; + log.error(msg); + AuthenticationFrameworkUtil.handleResponse(request, response, + HttpServletResponse.SC_BAD_REQUEST, msg); } finally { PrivilegedCarbonContext.endTenantFlow(); } + + // A call from super admin to a child tenant. Start a new tenant flow of the target + // tenant and pass to the API. + if (tenant != null) { + try { + PrivilegedCarbonContext.startTenantFlow(); + PrivilegedCarbonContext privilegedCarbonContext = PrivilegedCarbonContext.getThreadLocalCarbonContext(); + privilegedCarbonContext.setTenantId(tenant.getId()); + privilegedCarbonContext.setTenantDomain(tenant.getDomain()); + privilegedCarbonContext.setUsername(tenant.getAdminName()); + this.processRequest(request, response, compositeValve, authenticationInfo); + } finally { + PrivilegedCarbonContext.endTenantFlow(); + } + } } else { this.processRequest(request, response, compositeValve, authenticationInfo); } diff --git a/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/authenticator/OAuthAuthenticator.java b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/authenticator/OAuthAuthenticator.java index 1f793bb799..9735f054e9 100644 --- a/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/authenticator/OAuthAuthenticator.java +++ b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/authenticator/OAuthAuthenticator.java @@ -25,6 +25,7 @@ import org.apache.tomcat.util.buf.ByteChunk; import org.apache.tomcat.util.buf.MessageBytes; import org.wso2.carbon.webapp.authenticator.framework.AuthenticationException; import org.wso2.carbon.webapp.authenticator.framework.AuthenticationInfo; +import org.wso2.carbon.webapp.authenticator.framework.Constants; import org.wso2.carbon.webapp.authenticator.framework.Utils.Utils; import org.wso2.carbon.webapp.authenticator.framework.authenticator.oauth.OAuth2TokenValidator; import org.wso2.carbon.webapp.authenticator.framework.authenticator.oauth.OAuthTokenValidationException; @@ -77,6 +78,11 @@ public class OAuthAuthenticator implements WebappAuthenticator { String resource = requestUri + ":" + requestMethod; OAuthValidationResponse oAuthValidationResponse = this.tokenValidator.validateToken(bearerToken, resource); authenticationInfo = Utils.setAuthenticationInfo(oAuthValidationResponse, authenticationInfo); + if (authenticationInfo.getTenantId() == -1234 && properties.getProperty("Username") + .equals(authenticationInfo.getUsername()) + && request.getHeader(Constants.PROXY_TENANT_ID) != null) { + authenticationInfo.setSuperTenantAdmin(true); + } } catch (AuthenticationException e) { log.error("Failed to authenticate the incoming request", e); } catch (OAuthTokenValidationException e) { From 8df21f8af139e77921aa6be1222765947cef17e6 Mon Sep 17 00:00:00 2001 From: inoshperera Date: Thu, 5 Mar 2020 20:59:00 +0530 Subject: [PATCH 2/2] minor refactoring for getTenantId --- .../details/mgt/impl/DeviceInformationManagerImpl.java | 7 ++++++- .../carbon/device/mgt/core/util/DeviceManagerUtil.java | 5 +++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/device/details/mgt/impl/DeviceInformationManagerImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/device/details/mgt/impl/DeviceInformationManagerImpl.java index f5b7d141dc..4ba774b4c7 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/device/details/mgt/impl/DeviceInformationManagerImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/device/details/mgt/impl/DeviceInformationManagerImpl.java @@ -182,7 +182,7 @@ public class DeviceInformationManagerImpl implements DeviceInformationManager { DeviceDetailsWrapper deviceDetailsWrapper = new DeviceDetailsWrapper(); deviceDetailsWrapper.setDevice(device); deviceDetailsWrapper.setDeviceInfo(deviceInfo); - deviceDetailsWrapper.getJSONString(); + deviceDetailsWrapper.setTenantId(DeviceManagerUtil.getTenantId()); GroupManagementProviderService groupManagementService = DeviceManagementDataHolder .getInstance().getGroupManagementProviderService(); @@ -206,6 +206,11 @@ public class DeviceInformationManagerImpl implements DeviceInformationManager { } catch (UserStoreException e) { log.error("Error occurred while getting role list", e); } + } else { + if(log.isTraceEnabled()) { + log.trace("Event publishing is not enabled for tenant " + + DeviceManagerUtil.getTenantId()); + } } } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/util/DeviceManagerUtil.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/util/DeviceManagerUtil.java index c137432f8e..93fa387d0b 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/util/DeviceManagerUtil.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/util/DeviceManagerUtil.java @@ -350,6 +350,11 @@ public final class DeviceManagerUtil { } } + public static int getTenantId() { + return PrivilegedCarbonContext + .getThreadLocalCarbonContext().getTenantId(); + } + public static int validateActivityListPageSize(int limit) throws OperationManagementException { if (limit == 0) { DeviceManagementConfig deviceManagementConfig = DeviceConfigurationManager.getInstance().