Proxied API calls for sub tenant using super tenant details

feature/appm-store/pbac
inoshperera 5 years ago
parent a45d2d7cb0
commit af12d3fe9a

@ -30,6 +30,7 @@ public class AuthenticationInfo {
private String username; private String username;
private String tenantDomain; private String tenantDomain;
private int tenantId = -1; private int tenantId = -1;
private boolean isSuperTenantAdmin;
public WebappAuthenticator.Status getStatus() { public WebappAuthenticator.Status getStatus() {
return status; return status;
@ -71,4 +72,12 @@ public class AuthenticationInfo {
public void setTenantId(int tenantId) { public void setTenantId(int tenantId) {
this.tenantId = tenantId; this.tenantId = tenantId;
} }
public boolean isSuperTenantAdmin() {
return isSuperTenantAdmin;
}
public void setSuperTenantAdmin(boolean superTenantAdmin) {
isSuperTenantAdmin = superTenantAdmin;
}
} }

@ -22,6 +22,7 @@ public final class Constants {
public static final String AUTHORIZATION_HEADER_PREFIX_BEARER = "Bearer"; public static final String AUTHORIZATION_HEADER_PREFIX_BEARER = "Bearer";
public static final String NO_MATCHING_AUTH_SCHEME = "noMatchedAuthScheme"; public static final String NO_MATCHING_AUTH_SCHEME = "noMatchedAuthScheme";
public static final String PROXY_TENANT_ID = "ProxyTenantId";
public static final class HTTPHeaders { public static final class HTTPHeaders {
private HTTPHeaders() { private HTTPHeaders() {

@ -27,6 +27,9 @@ import org.owasp.encoder.Encode;
import org.wso2.carbon.context.PrivilegedCarbonContext; import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.tomcat.ext.valves.CarbonTomcatValve; import org.wso2.carbon.tomcat.ext.valves.CarbonTomcatValve;
import org.wso2.carbon.tomcat.ext.valves.CompositeValve; 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.authenticator.WebappAuthenticator;
import org.wso2.carbon.webapp.authenticator.framework.authorizer.WebappTenantAuthorizer; 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); WebappAuthenticator.Status status = WebappTenantAuthorizer.authorize(request, authenticationInfo);
authenticationInfo.setStatus(status); authenticationInfo.setStatus(status);
} }
Tenant tenant = null;
if (authenticationInfo.getTenantId() != -1) { if (authenticationInfo.getTenantId() != -1) {
try { try {
PrivilegedCarbonContext.startTenantFlow(); PrivilegedCarbonContext.startTenantFlow();
@ -67,10 +72,48 @@ public class WebappAuthenticationValve extends CarbonTomcatValve {
privilegedCarbonContext.setTenantId(authenticationInfo.getTenantId()); privilegedCarbonContext.setTenantId(authenticationInfo.getTenantId());
privilegedCarbonContext.setTenantDomain(authenticationInfo.getTenantDomain()); privilegedCarbonContext.setTenantDomain(authenticationInfo.getTenantDomain());
privilegedCarbonContext.setUsername(authenticationInfo.getUsername()); 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 { } finally {
PrivilegedCarbonContext.endTenantFlow(); 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 { } else {
this.processRequest(request, response, compositeValve, authenticationInfo); this.processRequest(request, response, compositeValve, authenticationInfo);
} }

@ -25,6 +25,7 @@ import org.apache.tomcat.util.buf.ByteChunk;
import org.apache.tomcat.util.buf.MessageBytes; import org.apache.tomcat.util.buf.MessageBytes;
import org.wso2.carbon.webapp.authenticator.framework.AuthenticationException; import org.wso2.carbon.webapp.authenticator.framework.AuthenticationException;
import org.wso2.carbon.webapp.authenticator.framework.AuthenticationInfo; 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.Utils.Utils;
import org.wso2.carbon.webapp.authenticator.framework.authenticator.oauth.OAuth2TokenValidator; import org.wso2.carbon.webapp.authenticator.framework.authenticator.oauth.OAuth2TokenValidator;
import org.wso2.carbon.webapp.authenticator.framework.authenticator.oauth.OAuthTokenValidationException; import org.wso2.carbon.webapp.authenticator.framework.authenticator.oauth.OAuthTokenValidationException;
@ -77,6 +78,11 @@ public class OAuthAuthenticator implements WebappAuthenticator {
String resource = requestUri + ":" + requestMethod; String resource = requestUri + ":" + requestMethod;
OAuthValidationResponse oAuthValidationResponse = this.tokenValidator.validateToken(bearerToken, resource); OAuthValidationResponse oAuthValidationResponse = this.tokenValidator.validateToken(bearerToken, resource);
authenticationInfo = Utils.setAuthenticationInfo(oAuthValidationResponse, authenticationInfo); 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) { } catch (AuthenticationException e) {
log.error("Failed to authenticate the incoming request", e); log.error("Failed to authenticate the incoming request", e);
} catch (OAuthTokenValidationException e) { } catch (OAuthTokenValidationException e) {

Loading…
Cancel
Save