fix: 修复权限相关问题

This commit is contained in:
CaptainB 2022-06-15 20:23:38 +08:00 committed by 刘瑞斌
parent f735cb972d
commit ed375c333e
5 changed files with 132 additions and 18 deletions

View File

@ -24,6 +24,9 @@ import static io.metersphere.commons.constants.SessionConstants.ATTR_USER;
public class SessionUtils {
private static final ThreadLocal<String> projectId = new ThreadLocal<>();
private static final ThreadLocal<String> workspaceId = new ThreadLocal<>();
public static String getUserId() {
SessionUser user = getUser();
return user == null ? null : user.getId();
@ -90,7 +93,24 @@ public class SessionUtils {
SecurityUtils.getSubject().getSession().setAttribute(FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME, sessionUser.getId());
}
/**
* 权限验证时从 controller 参数列表中找到 workspaceId 传入
*/
public static void setCurrentWorkspaceId(String workspaceId) {
SessionUtils.workspaceId.set(workspaceId);
}
/**
* 权限验证时从 controller 参数列表中找到 projectId 传入
*/
public static void setCurrentProjectId(String projectId) {
SessionUtils.projectId.set(projectId);
}
public static String getCurrentWorkspaceId() {
if (StringUtils.isNotEmpty(workspaceId.get())) {
return workspaceId.get();
}
try {
HttpServletRequest request = ((ServletRequestAttributes) (RequestContextHolder.currentRequestAttributes())).getRequest();
LogUtil.info("WORKSPACE: {}", request.getHeader("WORKSPACE"));
@ -104,6 +124,9 @@ public class SessionUtils {
}
public static String getCurrentProjectId() {
if (StringUtils.isNotEmpty(projectId.get())) {
return projectId.get();
}
try {
HttpServletRequest request = ((ServletRequestAttributes) (RequestContextHolder.currentRequestAttributes())).getRequest();
LogUtil.info("PROJECT: {}", request.getHeader("PROJECT"));
@ -168,4 +191,12 @@ public class SessionUtils {
.map(UserGroupPermission::getPermissionId)
.collect(Collectors.toSet());
}
public static void clearCurrentWorkspaceId() {
workspaceId.remove();
}
public static void clearCurrentProjectId() {
projectId.remove();
}
}

View File

@ -4,17 +4,22 @@ package io.metersphere.config;
import io.metersphere.commons.utils.ShiroUtils;
import io.metersphere.security.ApiKeyFilter;
import io.metersphere.security.CsrfFilter;
import io.metersphere.security.MsPermissionAnnotationMethodInterceptor;
import io.metersphere.security.UserModularRealmAuthenticator;
import io.metersphere.security.realm.LdapRealm;
import io.metersphere.security.realm.LocalRealm;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.aop.AnnotationResolver;
import org.apache.shiro.authc.pam.FirstSuccessfulStrategy;
import org.apache.shiro.authc.pam.ModularRealmAuthenticator;
import org.apache.shiro.authz.aop.*;
import org.apache.shiro.cache.CacheManager;
import org.apache.shiro.cache.MemoryConstrainedCacheManager;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.session.mgt.SessionManager;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.aop.SpringAnnotationResolver;
import org.apache.shiro.spring.security.interceptor.AopAllianceAnnotationsAuthorizingMethodInterceptor;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
@ -133,6 +138,17 @@ public class ShiroConfig implements EnvironmentAware {
public AuthorizationAttributeSourceAdvisor getAuthorizationAttributeSourceAdvisor(DefaultWebSecurityManager sessionManager) {
AuthorizationAttributeSourceAdvisor aasa = new AuthorizationAttributeSourceAdvisor();
aasa.setSecurityManager(sessionManager);
AopAllianceAnnotationsAuthorizingMethodInterceptor advice = new AopAllianceAnnotationsAuthorizingMethodInterceptor();
List<AuthorizingAnnotationMethodInterceptor> interceptors = new ArrayList<>(5);
AnnotationResolver resolver = new SpringAnnotationResolver();
interceptors.add(new RoleAnnotationMethodInterceptor(resolver));
interceptors.add(new MsPermissionAnnotationMethodInterceptor(resolver));
interceptors.add(new AuthenticatedAnnotationMethodInterceptor(resolver));
interceptors.add(new UserAnnotationMethodInterceptor(resolver));
interceptors.add(new GuestAnnotationMethodInterceptor(resolver));
advice.setMethodInterceptors(interceptors);
aasa.setAdvice(advice);
return aasa;
}

View File

@ -15,11 +15,9 @@ import io.metersphere.controller.request.AddProjectRequest;
import io.metersphere.controller.request.ProjectRequest;
import io.metersphere.dto.ProjectDTO;
import io.metersphere.dto.WorkspaceMemberDTO;
import io.metersphere.i18n.Translator;
import io.metersphere.log.annotation.MsAuditLog;
import io.metersphere.service.CheckPermissionService;
import io.metersphere.service.ProjectService;
import org.apache.shiro.authz.UnauthorizedException;
import org.apache.shiro.authz.annotation.Logical;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.web.bind.annotation.*;
@ -50,10 +48,8 @@ public class ProjectController {
/*jenkins项目列表*/
@GetMapping("/listAll/{workspaceId}")
@RequiresPermissions(PermissionConstants.WORKSPACE_PROJECT_MANAGER_READ)
public List<ProjectDTO> listAll(@PathVariable String workspaceId) {
if (!SessionUtils.hasPermission(workspaceId, null, PermissionConstants.WORKSPACE_PROJECT_MANAGER_READ)) {
throw new UnauthorizedException(Translator.get("check_owner_workspace"));
}
ProjectRequest request = new ProjectRequest();
request.setWorkspaceId(workspaceId);
return projectService.getProjectList(request);
@ -73,7 +69,6 @@ public class ProjectController {
public Project getProject(@PathVariable String id) {
return projectService.getProjectById(id);
}
@GetMapping("/member/size/{id}")
public long getProjectMemberSize(@PathVariable String id) {
return projectService.getProjectMemberSize(id);
@ -90,10 +85,8 @@ public class ProjectController {
}
@PostMapping("/list/{goPage}/{pageSize}")
@RequiresPermissions(PermissionConstants.WORKSPACE_PROJECT_MANAGER_READ)
public Pager<List<ProjectDTO>> getProjectList(@PathVariable int goPage, @PathVariable int pageSize, @RequestBody ProjectRequest request) {
if (!SessionUtils.hasPermission(request.getWorkspaceId(), null, PermissionConstants.WORKSPACE_PROJECT_MANAGER_READ)) {
throw new UnauthorizedException(Translator.get("check_owner_workspace"));
}
Page<Object> page = PageHelper.startPage(goPage, pageSize, true);
return PageUtils.setPageInfo(page, projectService.getProjectList(request));
}
@ -154,12 +147,12 @@ public class ProjectController {
}
@GetMapping("/getOwnerProjects")
public List<ProjectDTO> getOwnerProjects() {
public List<ProjectDTO> getOwnerProjects() {
return checkPermissionService.getOwnerProjects();
}
@GetMapping("/genTcpMockPort/{id}")
public String genTcpMockPort(@PathVariable String id) {
public String genTcpMockPort(@PathVariable String id){
return projectService.genTcpMockPort(id);
}

View File

@ -19,7 +19,6 @@ import io.metersphere.i18n.Translator;
import io.metersphere.log.annotation.MsAuditLog;
import io.metersphere.service.UserService;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authz.UnauthorizedException;
import org.apache.shiro.authz.annotation.Logical;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.web.bind.annotation.*;
@ -148,10 +147,8 @@ public class UserController {
* 获取工作空间成员用户
*/
@PostMapping("/ws/member/list/{goPage}/{pageSize}")
@RequiresPermissions(PermissionConstants.WORKSPACE_USER_READ)
public Pager<List<User>> getMemberList(@PathVariable int goPage, @PathVariable int pageSize, @RequestBody QueryMemberRequest request) {
if (!SessionUtils.hasPermission(request.getWorkspaceId(), null, PermissionConstants.WORKSPACE_USER_READ)) {
throw new UnauthorizedException(Translator.get("check_owner_workspace"));
}
Page<Object> page = PageHelper.startPage(goPage, pageSize, true);
return PageUtils.setPageInfo(page, userService.getMemberList(request));
}
@ -179,10 +176,8 @@ public class UserController {
* 获取工作空间成员用户 不分页
*/
@PostMapping("/ws/member/list/all")
@RequiresPermissions(PermissionConstants.WORKSPACE_PROJECT_MANAGER_READ)
public List<User> getMemberList(@RequestBody QueryMemberRequest request) {
if (!SessionUtils.hasPermission(request.getWorkspaceId(), null, PermissionConstants.WORKSPACE_USER_READ)) {
throw new UnauthorizedException(Translator.get("check_owner_workspace"));
}
return userService.getMemberList(request);
}

View File

@ -0,0 +1,79 @@
package io.metersphere.security;
import io.metersphere.commons.utils.SessionUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.reflect.MethodUtils;
import org.apache.shiro.aop.AnnotationResolver;
import org.apache.shiro.aop.MethodInvocation;
import org.apache.shiro.authz.AuthorizationException;
import org.apache.shiro.authz.aop.PermissionAnnotationMethodInterceptor;
import java.lang.reflect.Field;
import java.lang.reflect.Parameter;
public class MsPermissionAnnotationMethodInterceptor extends PermissionAnnotationMethodInterceptor {
public MsPermissionAnnotationMethodInterceptor(AnnotationResolver resolver) {
super(resolver);
}
@Override
public void assertAuthorized(MethodInvocation mi) throws AuthorizationException {
String projectId = null;
String workspaceId = null;
Object[] arguments = mi.getArguments();
if (ArrayUtils.isNotEmpty(arguments)) {
Parameter[] parameters = mi.getMethod().getParameters();
for (int i = 0; i < arguments.length; i++) {
Object argument = arguments[i];
if (argument instanceof String) {
if (StringUtils.equals(parameters[i].getName(), "projectId")) {
projectId = (String) argument;
}
if (StringUtils.equals(parameters[i].getName(), "workspaceId")) {
workspaceId = (String) argument;
}
} else {
try {
if (isExistField(argument, "projectId")) {
projectId = (String) MethodUtils.invokeMethod(argument, "getProjectId");
}
if (isExistField(argument, "workspaceId")) {
workspaceId = (String) MethodUtils.invokeMethod(argument, "getWorkspaceId");
}
} catch (Exception e) {
}
}
}
}
try {
SessionUtils.setCurrentWorkspaceId(workspaceId);
SessionUtils.setCurrentProjectId(projectId);
super.assertAuthorized(mi);
} finally {
SessionUtils.clearCurrentWorkspaceId();
SessionUtils.clearCurrentProjectId();
}
}
public static boolean isExistField(Object obj, String fieldName) {
if (obj == null || StringUtils.isEmpty(fieldName)) {
return false;
}
//获取这个类的所有属性
Field[] fields = obj.getClass().getDeclaredFields();
boolean flag = false;
//循环遍历所有的fields
for (Field field : fields) {
if (field.getName().equals(fieldName)) {
flag = true;
break;
}
}
return flag;
}
}