From 9964157fce718b50bd6890c7a111a85c75d8998f Mon Sep 17 00:00:00 2001 From: kangkaisen Date: Fri, 21 Apr 2017 17:10:19 +0800 Subject: [PATCH] KYLIN-2563 Fix bug in checkCubeAuthorization --- .../kylin/rest/controller/ProjectController.java | 59 ++--------- .../apache/kylin/rest/service/QueryService.java | 9 +- .../java/org/apache/kylin/rest/util/AclUtil.java | 116 +++++++++++++++++++++ 3 files changed, 134 insertions(+), 50 deletions(-) create mode 100644 server-base/src/main/java/org/apache/kylin/rest/util/AclUtil.java diff --git a/server-base/src/main/java/org/apache/kylin/rest/controller/ProjectController.java b/server-base/src/main/java/org/apache/kylin/rest/controller/ProjectController.java index a6edece56..40e798a65 100644 --- a/server-base/src/main/java/org/apache/kylin/rest/controller/ProjectController.java +++ b/server-base/src/main/java/org/apache/kylin/rest/controller/ProjectController.java @@ -34,6 +34,7 @@ import org.apache.kylin.rest.request.ProjectRequest; import org.apache.kylin.rest.service.AccessService; import org.apache.kylin.rest.service.CubeService; import org.apache.kylin.rest.service.ProjectService; +import org.apache.kylin.rest.util.AclUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -41,9 +42,6 @@ import org.springframework.security.acls.domain.GrantedAuthoritySid; import org.springframework.security.acls.domain.PrincipalSid; import org.springframework.security.acls.model.AccessControlEntry; import org.springframework.security.acls.model.Acl; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.GrantedAuthority; -import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.PathVariable; @@ -69,6 +67,8 @@ public class ProjectController extends BasicController { private AccessService accessService; @Autowired private CubeService cubeService; + @Autowired + private AclUtil aclUtil; /** * Get available project list @@ -90,29 +90,16 @@ public class ProjectController extends BasicController { List projectInstances = projectService.listAllProjects(limit, offset); //get user infomation - Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); - UserDetails userDetails = null; - if (authentication == null) { - logger.debug("authentication is null."); - throw new InternalErrorException("Can not find authentication infomation."); - } - if (authentication.getPrincipal() instanceof UserDetails) { - logger.debug("authentication.getPrincipal() is " + authentication.getPrincipal()); - userDetails = (UserDetails) authentication.getPrincipal(); - } - if (authentication.getDetails() instanceof UserDetails) { - logger.debug("authentication.getDetails() is " + authentication.getDetails()); - userDetails = (UserDetails) authentication.getDetails(); - } + UserDetails userDetails = aclUtil.getCurrentUser(); + String userName = userDetails.getUsername(); //check if ROLE_ADMIN return all,also get user role list - List userAuthority = new ArrayList<>(); - for (GrantedAuthority auth : authentication.getAuthorities()) { - userAuthority.add(auth.getAuthority()); - if (auth.getAuthority().equals(Constant.ROLE_ADMIN)) + List userAuthority = aclUtil.getAuthorityList(); + for (String auth : userAuthority) { + if (auth.equals(Constant.ROLE_ADMIN)) return projectInstances; } - String userName = userDetails.getUsername(); + for (ProjectInstance projectInstance : projectInstances) { if (projectInstance == null) { continue; @@ -157,32 +144,8 @@ public class ProjectController extends BasicController { if (cubeInstance == null) { continue; } - boolean hasCubePermission = false; - AclEntity cubeAe = accessService.getAclEntity("CubeInstance", cubeInstance.getId()); - Acl cubeAcl = accessService.getAcl(cubeAe); - //cube no Acl info will not be used to filter project - if (cubeAcl != null) { - //cube owner will have permission to read project - if (((PrincipalSid) cubeAcl.getOwner()).getPrincipal().equals(userName)) { - hasProjectPermission = true; - break; - } - for (AccessControlEntry cubeAce : cubeAcl.getEntries()) { - - if (cubeAce.getSid() instanceof PrincipalSid && ((PrincipalSid) cubeAce.getSid()).getPrincipal().equals(userName)) { - hasCubePermission = true; - break; - } else if (cubeAce.getSid() instanceof GrantedAuthoritySid) { - String cubeAuthority = ((GrantedAuthoritySid) cubeAce.getSid()).getGrantedAuthority(); - if (userAuthority.contains(cubeAuthority)) { - hasCubePermission = true; - break; - } - - } - } - } - if (hasCubePermission) { + + if (aclUtil.isHasCubePermission(cubeInstance)) { hasProjectPermission = true; break; } diff --git a/server-base/src/main/java/org/apache/kylin/rest/service/QueryService.java b/server-base/src/main/java/org/apache/kylin/rest/service/QueryService.java index 6a38638ed..b526f96cb 100644 --- a/server-base/src/main/java/org/apache/kylin/rest/service/QueryService.java +++ b/server-base/src/main/java/org/apache/kylin/rest/service/QueryService.java @@ -76,6 +76,7 @@ import org.apache.kylin.rest.model.TableMeta; import org.apache.kylin.rest.request.PrepareSqlRequest; import org.apache.kylin.rest.request.SQLRequest; import org.apache.kylin.rest.response.SQLResponse; +import org.apache.kylin.rest.util.AclUtil; import org.apache.kylin.rest.util.QueryUtil; import org.apache.kylin.rest.util.Serializer; import org.apache.kylin.rest.util.TableauInterceptor; @@ -85,7 +86,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.access.AccessDeniedException; -import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.stereotype.Component; @@ -124,6 +124,9 @@ public class QueryService extends BasicService { @Autowired private CacheService cacheService; + @Autowired + private AclUtil aclUtil; + @PostConstruct public void init() throws IOException { Preconditions.checkNotNull(cacheManager, "cacheManager is not injected yet"); @@ -298,8 +301,10 @@ public class QueryService extends BasicService { checkCubeAuthorization(cubeInstance); } - @PreAuthorize(Constant.ACCESS_HAS_ROLE_ADMIN + " or hasPermission(#cube, 'ADMINISTRATION') or hasPermission(#cube, 'MANAGEMENT')" + " or hasPermission(#cube, 'OPERATION') or hasPermission(#cube, 'READ')") private void checkCubeAuthorization(CubeInstance cube) throws AccessDeniedException { + if (!aclUtil.isHasCubePermission(cube)) { + throw new AccessDeniedException("Access denied"); + } } private void checkHybridAuthorization(HybridInstance hybridInstance) throws AccessDeniedException { diff --git a/server-base/src/main/java/org/apache/kylin/rest/util/AclUtil.java b/server-base/src/main/java/org/apache/kylin/rest/util/AclUtil.java new file mode 100644 index 000000000..440b2f98c --- /dev/null +++ b/server-base/src/main/java/org/apache/kylin/rest/util/AclUtil.java @@ -0,0 +1,116 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + +package org.apache.kylin.rest.util; + +import org.apache.kylin.common.persistence.AclEntity; +import org.apache.kylin.cube.CubeInstance; +import org.apache.kylin.rest.constant.Constant; +import org.apache.kylin.rest.exception.InternalErrorException; +import org.apache.kylin.rest.service.AccessService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.acls.domain.GrantedAuthoritySid; +import org.springframework.security.acls.domain.PrincipalSid; +import org.springframework.security.acls.model.AccessControlEntry; +import org.springframework.security.acls.model.Acl; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.List; + +@Component("aclUtil") +public class AclUtil { + private static final Logger logger = LoggerFactory.getLogger(AclUtil.class); + + @Autowired + private AccessService accessService; + + /** + * @return true the current user has permission to query the cube, otherwise + * false + */ + public boolean isHasCubePermission(CubeInstance cube) { + boolean hasCubePermission = false; + String userName = getCurrentUser().getUsername(); + List userAuthority = getAuthorityList(); + + //check if ROLE_ADMIN + for (String auth : userAuthority) { + if (auth.equals(Constant.ROLE_ADMIN)) { + return true; + } + } + + AclEntity cubeAe = accessService.getAclEntity("CubeInstance", cube.getId()); + Acl cubeAcl = accessService.getAcl(cubeAe); + //cube Acl info + if (cubeAcl != null) { + if (((PrincipalSid) cubeAcl.getOwner()).getPrincipal().equals(userName)) { + hasCubePermission = true; + } + + for (AccessControlEntry cubeAce : cubeAcl.getEntries()) { + if (cubeAce.getSid() instanceof PrincipalSid && ((PrincipalSid) cubeAce.getSid()).getPrincipal().equals(userName)) { + hasCubePermission = true; + break; + } else if (cubeAce.getSid() instanceof GrantedAuthoritySid) { + String cubeAuthority = ((GrantedAuthoritySid) cubeAce.getSid()).getGrantedAuthority(); + if (userAuthority.contains(cubeAuthority)) { + hasCubePermission = true; + break; + } + + } + } + } + return hasCubePermission; + } + + public UserDetails getCurrentUser() { + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + UserDetails userDetails = null; + if (authentication == null) { + logger.debug("authentication is null."); + throw new InternalErrorException("Can not find authentication infomation."); + } + if (authentication.getPrincipal() instanceof UserDetails) { + logger.debug("authentication.getPrincipal() is " + authentication.getPrincipal()); + userDetails = (UserDetails) authentication.getPrincipal(); + } + if (authentication.getDetails() instanceof UserDetails) { + logger.debug("authentication.getDetails() is " + authentication.getDetails()); + userDetails = (UserDetails) authentication.getDetails(); + } + return userDetails; + } + + public List getAuthorityList() { + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + List userAuthority = new ArrayList<>(); + for (GrantedAuthority auth : authentication.getAuthorities()) { + userAuthority.add(auth.getAuthority()); + } + return userAuthority; + } +} -- 2.11.0 (Apple Git-81)