diff --git a/pom.xml b/pom.xml index ed12aae5d..d3cbeab67 100644 --- a/pom.xml +++ b/pom.xml @@ -79,6 +79,7 @@ default teamproject + https://mygen3.arborist.url.here DisabledSecurity 43200 http://localhost diff --git a/src/main/java/org/ohdsi/webapi/shiro/filters/UpdateAccessTokenFilter.java b/src/main/java/org/ohdsi/webapi/shiro/filters/UpdateAccessTokenFilter.java index faeaa7095..04d0ca32c 100644 --- a/src/main/java/org/ohdsi/webapi/shiro/filters/UpdateAccessTokenFilter.java +++ b/src/main/java/org/ohdsi/webapi/shiro/filters/UpdateAccessTokenFilter.java @@ -5,6 +5,8 @@ import static org.ohdsi.webapi.shiro.management.AtlasSecurity.TOKEN_ATTRIBUTE; import io.buji.pac4j.subject.Pac4jPrincipal; +import org.json.JSONObject; + import java.net.URI; import java.net.URISyntaxException; import java.security.Principal; @@ -36,6 +38,7 @@ import org.pac4j.core.profile.CommonProfile; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.web.client.RestTemplate; /** * @@ -49,18 +52,21 @@ public class UpdateAccessTokenFilter extends AdviceFilter { private final Set defaultRoles; private final String onFailRedirectUrl; private final String authorizationMode; + private final String authorizationUrl; public UpdateAccessTokenFilter( PermissionManager authorizer, Set defaultRoles, int tokenExpirationIntervalInSeconds, String onFailRedirectUrl, - String authorizationMode) { + String authorizationMode, + String authorizationUrl) { this.authorizer = authorizer; this.tokenExpirationIntervalInSeconds = tokenExpirationIntervalInSeconds; this.defaultRoles = defaultRoles; this.onFailRedirectUrl = onFailRedirectUrl; this.authorizationMode = authorizationMode; + this.authorizationUrl = authorizationUrl; logger.debug("AUTHORIZATION_MODE in UpdateAccessTokenFilter constructor == '{}'", this.authorizationMode); } @@ -147,9 +153,13 @@ protected boolean preHandle(ServletRequest request, ServletResponse response) th String teamProjectRole = extractTeamProjectFromRequestParameters(request); // if found, add teamproject as a role in the newUserRoles list: if (teamProjectRole != null) { + // double check if this role has really been granted to the user: + if (checkGen3Authorization(teamProjectRole, login) == false) { + WebUtils.toHttp(response).sendError(HttpServletResponse.SC_FORBIDDEN, + "User is not authorized to access this team project's data"); + return false; + } newUserRoles.add(teamProjectRole); - // double check with Arborist if this role has really been granted to the user.... - // TODO } } this.authorizer.registerUser(login, name, defaultRoles, newUserRoles, resetRoles); @@ -177,6 +187,26 @@ protected boolean preHandle(ServletRequest request, ServletResponse response) th return true; } + private boolean checkGen3Authorization(String teamProjectRole, String login) throws Exception { + logger.debug("Checking Gen3 Authorization for 'team project'={} and user={} using service={}", teamProjectRole, login, this.authorizationUrl); + RestTemplate restTemplate = new RestTemplate(); + String arboristAuthorizationURL = this.authorizationUrl; + String requestBody = String.format("{\"username\": \"%s\"}", login); + String jsonResponseString = restTemplate.postForObject(arboristAuthorizationURL, requestBody, String.class); + + JSONObject jsonObject = new JSONObject(jsonResponseString); + + if (!jsonObject.keySet().contains(teamProjectRole)) { + logger.debug("User is not authorized to access this team project's data"); + return false; + } else { + // TODO add more checks, e.g. whether the expected service / method config are also present... + Object teamProjectAuthorizations = jsonObject.get(teamProjectRole); + logger.debug("Found authorizations={}", teamProjectAuthorizations); + return true; + } + } + private URI getOAuthFailUri() throws URISyntaxException { return getFailUri("oauth_error_email"); } diff --git a/src/main/java/org/ohdsi/webapi/shiro/management/AtlasRegularSecurity.java b/src/main/java/org/ohdsi/webapi/shiro/management/AtlasRegularSecurity.java index 6029cbd16..ac31d3181 100644 --- a/src/main/java/org/ohdsi/webapi/shiro/management/AtlasRegularSecurity.java +++ b/src/main/java/org/ohdsi/webapi/shiro/management/AtlasRegularSecurity.java @@ -258,6 +258,9 @@ public class AtlasRegularSecurity extends AtlasSecurity { @Value("${security.ohdsi.custom.authorization.mode}") private String authorizationMode; + @Value("${security.ohdsi.custom.authorization.url}") + private String authorizationUrl; + private RestTemplate restTemplate = new RestTemplate(); @Autowired @@ -275,8 +278,9 @@ public Map getFilters() { filters.put(LOGOUT, new LogoutFilter(eventPublisher)); logger.debug("Initializing UpdateAccessTokenFilter with AUTHORIZATION_MODE === '{}'", this.authorizationMode); + logger.debug("Initializing UpdateAccessTokenFilter with AUTHORIZATION_URL === '{}'", this.authorizationUrl); filters.put(UPDATE_TOKEN, new UpdateAccessTokenFilter(this.authorizer, this.defaultRoles, this.tokenExpirationIntervalInSeconds, - this.redirectUrl, this.authorizationMode)); + this.redirectUrl, this.authorizationMode, this.authorizationUrl)); filters.put(ACCESS_AUTHC, new GoogleAccessTokenFilter(restTemplate, permissionManager, Collections.emptySet())); filters.put(JWT_AUTHC, new AtlasJwtAuthFilter()); diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 8ded58304..2b7a811ee 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -203,6 +203,7 @@ security.auth.cas.enabled=${security.auth.cas.enabled} #Authorization config security.ohdsi.custom.authorization.mode=${security.ohdsi.custom.authorization.mode} +security.ohdsi.custom.authorization.url=${security.ohdsi.custom.authorization.url} #Execution engine executionengine.updateStatusCallback=${executionengine.updateStatusCallback}