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 d7a0ec1c614..674728491f0 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 26166e864a7..af69a320ea1 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 4b596c4ed36..16bf4d695e3 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 1f793bb7990..9735f054e9a 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) {