Commit fa26d674 authored by ZhengJie's avatar ZhengJie
Browse files

[代码完善](v2.5): v2.5 beta 数据权限使升级,现可通过注解[@DataPermission]控制

DataPermission 类中有详细说明和使用示例

SecurityUtils 中加入获取当前用户的数据权限的方法

2.5 Beta 详情:https://www.ydyno.com/archives/1225.html
parent 63f00cd3
...@@ -16,8 +16,10 @@ ...@@ -16,8 +16,10 @@
package me.zhengjie.utils; package me.zhengjie.utils;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.ObjectUtil;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import me.zhengjie.annotation.DataPermission;
import me.zhengjie.annotation.Query; import me.zhengjie.annotation.Query;
import javax.persistence.criteria.*; import javax.persistence.criteria.*;
import java.lang.reflect.Field; import java.lang.reflect.Field;
...@@ -33,10 +35,23 @@ public class QueryHelp { ...@@ -33,10 +35,23 @@ public class QueryHelp {
public static <R, Q> Predicate getPredicate(Root<R> root, Q query, CriteriaBuilder cb) { public static <R, Q> Predicate getPredicate(Root<R> root, Q query, CriteriaBuilder cb) {
List<Predicate> list = new ArrayList<>(); List<Predicate> list = new ArrayList<>();
if(query == null){ if(query == null){
return cb.and(list.toArray(new Predicate[0])); return cb.and(list.toArray(new Predicate[0]));
} }
// 数据权限验证
DataPermission permission = query.getClass().getAnnotation(DataPermission.class);
if(permission != null){
// 获取数据权限
List<Long> dataScopes = SecurityUtils.getCurrentUserDataScope();
if(CollectionUtil.isNotEmpty(dataScopes)){
if(StringUtils.isNotBlank(permission.joinName()) && StringUtils.isNotBlank(permission.fieldName())) {
Join join = root.join(permission.joinName(), JoinType.LEFT);
list.add(getExpression(permission.fieldName(),join, root).in(dataScopes));
} else if (StringUtils.isBlank(permission.joinName()) && StringUtils.isNotBlank(permission.fieldName())) {
list.add(getExpression(permission.fieldName(),null, root).in(dataScopes));
}
}
}
try { try {
List<Field> fields = getAllFields(query.getClass(), new ArrayList<>()); List<Field> fields = getAllFields(query.getClass(), new ArrayList<>());
for (Field field : fields) { for (Field field : fields) {
......
...@@ -15,7 +15,9 @@ ...@@ -15,7 +15,9 @@
*/ */
package me.zhengjie.utils; package me.zhengjie.utils;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject; import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import me.zhengjie.exception.BadRequestException; import me.zhengjie.exception.BadRequestException;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
...@@ -23,6 +25,7 @@ import org.springframework.security.core.Authentication; ...@@ -23,6 +25,7 @@ import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UserDetailsService;
import java.util.List;
/** /**
* 获取当前登录的用户 * 获取当前登录的用户
...@@ -65,11 +68,20 @@ public class SecurityUtils { ...@@ -65,11 +68,20 @@ public class SecurityUtils {
/** /**
* 获取系统用户ID * 获取系统用户ID
*
* @return 系统用户ID * @return 系统用户ID
*/ */
public static Long getCurrentUserId() { public static Long getCurrentUserId() {
UserDetails userDetails = getCurrentUser(); UserDetails userDetails = getCurrentUser();
return new JSONObject(new JSONObject(userDetails).get("user")).get("id", Long.class); return new JSONObject(new JSONObject(userDetails).get("user")).get("id", Long.class);
} }
/**
* 获取当前用户的数据权限
* @return /
*/
public static List<Long> getCurrentUserDataScope(){
UserDetails userDetails = getCurrentUser();
JSONArray array = JSONUtil.parseArray(new JSONObject(userDetails).get("dataScopes"));
return JSONUtil.toList(array,Long.class);
}
} }
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package me.zhengjie.aop.log; package me.zhengjie.annotation;
import java.lang.annotation.ElementType; import java.lang.annotation.ElementType;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
......
...@@ -51,7 +51,7 @@ public class LogAspect { ...@@ -51,7 +51,7 @@ public class LogAspect {
/** /**
* 配置切入点 * 配置切入点
*/ */
@Pointcut("@annotation(me.zhengjie.aop.log.Log)") @Pointcut("@annotation(me.zhengjie.annotation.Log)")
public void logPointcut() { public void logPointcut() {
// 该方法无方法体,主要为了让同类中其他方法使用此切入点 // 该方法无方法体,主要为了让同类中其他方法使用此切入点
} }
......
...@@ -18,7 +18,7 @@ package me.zhengjie.rest; ...@@ -18,7 +18,7 @@ package me.zhengjie.rest;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import me.zhengjie.aop.log.Log; import me.zhengjie.annotation.Log;
import me.zhengjie.service.LogService; import me.zhengjie.service.LogService;
import me.zhengjie.service.dto.LogQueryCriteria; import me.zhengjie.service.dto.LogQueryCriteria;
import me.zhengjie.utils.SecurityUtils; import me.zhengjie.utils.SecurityUtils;
......
...@@ -81,7 +81,7 @@ public class LogServiceImpl implements LogService { ...@@ -81,7 +81,7 @@ public class LogServiceImpl implements LogService {
MethodSignature signature = (MethodSignature) joinPoint.getSignature(); MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod(); Method method = signature.getMethod();
me.zhengjie.aop.log.Log aopLog = method.getAnnotation(me.zhengjie.aop.log.Log.class); me.zhengjie.annotation.Log aopLog = method.getAnnotation(me.zhengjie.annotation.Log.class);
// 方法路径 // 方法路径
String methodName = joinPoint.getTarget().getClass().getName()+"."+signature.getName()+"()"; String methodName = joinPoint.getTarget().getClass().getName()+"."+signature.getName()+"()";
......
/*
* Copyright 2019-2020 Zheng Jie
*
* Licensed 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 me.zhengjie.config;
import me.zhengjie.modules.system.domain.Dept;
import me.zhengjie.modules.system.service.DeptService;
import me.zhengjie.modules.system.service.RoleService;
import me.zhengjie.modules.system.service.UserService;
import me.zhengjie.modules.system.service.dto.RoleSmallDto;
import me.zhengjie.modules.system.service.dto.UserDto;
import me.zhengjie.utils.SecurityUtils;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* 数据权限配置
* @author Zheng Jie
* @date 2019-4-1
*/
@Component
public class DataScope {
private final String[] scopeType = {"全部","本级","自定义"};
private final UserService userService;
private final RoleService roleService;
private final DeptService deptService;
public DataScope(UserService userService, RoleService roleService, DeptService deptService) {
this.userService = userService;
this.roleService = roleService;
this.deptService = deptService;
}
public Set<Long> getDeptIds() {
UserDto user = userService.findByName(SecurityUtils.getCurrentUsername());
// 用于存储部门id
Set<Long> deptIds = new HashSet<>();
// 查询用户角色
List<RoleSmallDto> roleSet = roleService.findByUsersId(user.getId());
for (RoleSmallDto role : roleSet) {
if (scopeType[0].equals(role.getDataScope())) {
return new HashSet<>() ;
}
// 存储本级的数据权限
if (scopeType[1].equals(role.getDataScope())) {
deptIds.add(user.getDept().getId());
}
// 存储自定义的数据权限
if (scopeType[2].equals(role.getDataScope())) {
Set<Dept> depts = deptService.findByRoleIds(role.getId());
for (Dept dept : depts) {
deptIds.add(dept.getId());
List<Dept> deptChildren = deptService.findByPid(dept.getId());
if (deptChildren != null && deptChildren.size() != 0) {
deptIds.addAll(getDeptChildren(deptChildren));
}
}
}
}
return deptIds;
}
public List<Long> getDeptChildren(List<Dept> deptList) {
List<Long> list = new ArrayList<>();
deptList.forEach(dept -> {
if (dept!=null && dept.getEnabled()){
List<Dept> depts = deptService.findByPid(dept.getId());
if(deptList.size() != 0){
list.addAll(getDeptChildren(depts));
}
list.add(dept.getId());
}
}
);
return list;
}
}
...@@ -18,7 +18,7 @@ package me.zhengjie.modules.mnt.rest; ...@@ -18,7 +18,7 @@ package me.zhengjie.modules.mnt.rest;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import me.zhengjie.aop.log.Log; import me.zhengjie.annotation.Log;
import me.zhengjie.modules.mnt.domain.App; import me.zhengjie.modules.mnt.domain.App;
import me.zhengjie.modules.mnt.service.AppService; import me.zhengjie.modules.mnt.service.AppService;
import me.zhengjie.modules.mnt.service.dto.AppQueryCriteria; import me.zhengjie.modules.mnt.service.dto.AppQueryCriteria;
......
...@@ -18,7 +18,7 @@ package me.zhengjie.modules.mnt.rest; ...@@ -18,7 +18,7 @@ package me.zhengjie.modules.mnt.rest;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import me.zhengjie.aop.log.Log; import me.zhengjie.annotation.Log;
import me.zhengjie.exception.BadRequestException; import me.zhengjie.exception.BadRequestException;
import me.zhengjie.modules.mnt.domain.Database; import me.zhengjie.modules.mnt.domain.Database;
import me.zhengjie.modules.mnt.service.DatabaseService; import me.zhengjie.modules.mnt.service.DatabaseService;
......
...@@ -18,7 +18,7 @@ package me.zhengjie.modules.mnt.rest; ...@@ -18,7 +18,7 @@ package me.zhengjie.modules.mnt.rest;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import me.zhengjie.aop.log.Log; import me.zhengjie.annotation.Log;
import me.zhengjie.modules.mnt.domain.Deploy; import me.zhengjie.modules.mnt.domain.Deploy;
import me.zhengjie.modules.mnt.domain.DeployHistory; import me.zhengjie.modules.mnt.domain.DeployHistory;
import me.zhengjie.modules.mnt.service.DeployService; import me.zhengjie.modules.mnt.service.DeployService;
......
...@@ -18,7 +18,7 @@ package me.zhengjie.modules.mnt.rest; ...@@ -18,7 +18,7 @@ package me.zhengjie.modules.mnt.rest;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import me.zhengjie.aop.log.Log; import me.zhengjie.annotation.Log;
import me.zhengjie.modules.mnt.service.DeployHistoryService; import me.zhengjie.modules.mnt.service.DeployHistoryService;
import me.zhengjie.modules.mnt.service.dto.DeployHistoryQueryCriteria; import me.zhengjie.modules.mnt.service.dto.DeployHistoryQueryCriteria;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;
......
...@@ -18,7 +18,7 @@ package me.zhengjie.modules.mnt.rest; ...@@ -18,7 +18,7 @@ package me.zhengjie.modules.mnt.rest;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import me.zhengjie.aop.log.Log; import me.zhengjie.annotation.Log;
import me.zhengjie.modules.mnt.domain.ServerDeploy; import me.zhengjie.modules.mnt.domain.ServerDeploy;
import me.zhengjie.modules.mnt.service.ServerDeployService; import me.zhengjie.modules.mnt.service.ServerDeployService;
import me.zhengjie.modules.mnt.service.dto.ServerDeployQueryCriteria; import me.zhengjie.modules.mnt.service.dto.ServerDeployQueryCriteria;
......
...@@ -19,7 +19,7 @@ import io.swagger.annotations.Api; ...@@ -19,7 +19,7 @@ import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import me.zhengjie.aop.log.Log; import me.zhengjie.annotation.Log;
import me.zhengjie.exception.BadRequestException; import me.zhengjie.exception.BadRequestException;
import me.zhengjie.modules.quartz.domain.QuartzJob; import me.zhengjie.modules.quartz.domain.QuartzJob;
import me.zhengjie.modules.quartz.service.QuartzJobService; import me.zhengjie.modules.quartz.service.QuartzJobService;
......
...@@ -24,7 +24,7 @@ import io.swagger.annotations.ApiOperation; ...@@ -24,7 +24,7 @@ import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import me.zhengjie.annotation.AnonymousAccess; import me.zhengjie.annotation.AnonymousAccess;
import me.zhengjie.aop.log.Log; import me.zhengjie.annotation.Log;
import me.zhengjie.exception.BadRequestException; import me.zhengjie.exception.BadRequestException;
import me.zhengjie.modules.security.config.SecurityProperties; import me.zhengjie.modules.security.config.SecurityProperties;
import me.zhengjie.modules.security.security.TokenProvider; import me.zhengjie.modules.security.security.TokenProvider;
......
...@@ -18,7 +18,7 @@ package me.zhengjie.modules.security.rest; ...@@ -18,7 +18,7 @@ package me.zhengjie.modules.security.rest;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import me.zhengjie.aop.log.Log; import me.zhengjie.annotation.Log;
import me.zhengjie.modules.security.service.OnlineUserService; import me.zhengjie.modules.security.service.OnlineUserService;
import me.zhengjie.utils.EncryptUtils; import me.zhengjie.utils.EncryptUtils;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;
......
...@@ -19,6 +19,7 @@ import lombok.RequiredArgsConstructor; ...@@ -19,6 +19,7 @@ import lombok.RequiredArgsConstructor;
import me.zhengjie.exception.BadRequestException; import me.zhengjie.exception.BadRequestException;
import me.zhengjie.exception.EntityNotFoundException; import me.zhengjie.exception.EntityNotFoundException;
import me.zhengjie.modules.security.service.dto.JwtUserDto; import me.zhengjie.modules.security.service.dto.JwtUserDto;
import me.zhengjie.modules.system.service.DataService;
import me.zhengjie.modules.system.service.RoleService; import me.zhengjie.modules.system.service.RoleService;
import me.zhengjie.modules.system.service.UserService; import me.zhengjie.modules.system.service.UserService;
import me.zhengjie.modules.system.service.dto.UserDto; import me.zhengjie.modules.system.service.dto.UserDto;
...@@ -39,6 +40,7 @@ public class UserDetailsServiceImpl implements UserDetailsService { ...@@ -39,6 +40,7 @@ public class UserDetailsServiceImpl implements UserDetailsService {
private final UserService userService; private final UserService userService;
private final RoleService roleService; private final RoleService roleService;
private final DataService dataService;
@Override @Override
public JwtUserDto loadUserByUsername(String username) { public JwtUserDto loadUserByUsername(String username) {
...@@ -57,6 +59,7 @@ public class UserDetailsServiceImpl implements UserDetailsService { ...@@ -57,6 +59,7 @@ public class UserDetailsServiceImpl implements UserDetailsService {
} }
return new JwtUserDto( return new JwtUserDto(
user, user,
dataService.getDeptIds(user),
roleService.mapToGrantedAuthorities(user) roleService.mapToGrantedAuthorities(user)
); );
} }
......
...@@ -33,10 +33,12 @@ import java.util.stream.Collectors; ...@@ -33,10 +33,12 @@ import java.util.stream.Collectors;
@AllArgsConstructor @AllArgsConstructor
public class JwtUserDto implements UserDetails { public class JwtUserDto implements UserDetails {
private UserDto user; private final UserDto user;
private final List<Long> dataScopes;
@JsonIgnore @JsonIgnore
private List<GrantedAuthority> authorities; private final List<GrantedAuthority> authorities;
public Set<String> getRoles() { public Set<String> getRoles() {
return authorities.stream().map(GrantedAuthority::getAuthority).collect(Collectors.toSet()); return authorities.stream().map(GrantedAuthority::getAuthority).collect(Collectors.toSet());
......
...@@ -20,6 +20,7 @@ import io.swagger.annotations.ApiModelProperty; ...@@ -20,6 +20,7 @@ import io.swagger.annotations.ApiModelProperty;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import me.zhengjie.base.BaseEntity; import me.zhengjie.base.BaseEntity;
import me.zhengjie.utils.enums.DataScopeEnum;
import org.hibernate.annotations.CreationTimestamp; import org.hibernate.annotations.CreationTimestamp;
import javax.persistence.*; import javax.persistence.*;
import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotBlank;
...@@ -71,7 +72,7 @@ public class Role extends BaseEntity implements Serializable { ...@@ -71,7 +72,7 @@ public class Role extends BaseEntity implements Serializable {
private String name; private String name;
@ApiModelProperty(value = "数据权限,全部 、 本级 、 自定义") @ApiModelProperty(value = "数据权限,全部 、 本级 、 自定义")
private String dataScope = "本级"; private String dataScope = DataScopeEnum.THIS_LEVEL.getValue();
@Column(name = "level") @Column(name = "level")
@ApiModelProperty(value = "级别,数值越小,级别越大") @ApiModelProperty(value = "级别,数值越小,级别越大")
......
...@@ -19,8 +19,7 @@ import cn.hutool.core.collection.CollectionUtil; ...@@ -19,8 +19,7 @@ import cn.hutool.core.collection.CollectionUtil;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import me.zhengjie.aop.log.Log; import me.zhengjie.annotation.Log;
import me.zhengjie.config.DataScope;
import me.zhengjie.exception.BadRequestException; import me.zhengjie.exception.BadRequestException;
import me.zhengjie.modules.system.domain.Dept; import me.zhengjie.modules.system.domain.Dept;
import me.zhengjie.modules.system.service.DeptService; import me.zhengjie.modules.system.service.DeptService;
...@@ -49,7 +48,6 @@ import java.util.Set; ...@@ -49,7 +48,6 @@ import java.util.Set;
public class DeptController { public class DeptController {
private final DeptService deptService; private final DeptService deptService;
private final DataScope dataScope;
private static final String ENTITY_NAME = "dept"; private static final String ENTITY_NAME = "dept";
@Log("导出部门数据") @Log("导出部门数据")
...@@ -65,8 +63,6 @@ public class DeptController { ...@@ -65,8 +63,6 @@ public class DeptController {
@GetMapping @GetMapping
@PreAuthorize("@el.check('user:list','dept:list')") @PreAuthorize("@el.check('user:list','dept:list')")
public ResponseEntity<Object> getDepts(DeptQueryCriteria criteria){ public ResponseEntity<Object> getDepts(DeptQueryCriteria criteria){
// 数据权限
criteria.setIds(dataScope.getDeptIds());
List<DeptDto> deptDtos = deptService.queryAll(criteria); List<DeptDto> deptDtos = deptService.queryAll(criteria);
return new ResponseEntity<>(deptService.buildTree(deptDtos),HttpStatus.OK); return new ResponseEntity<>(deptService.buildTree(deptDtos),HttpStatus.OK);
} }
......
...@@ -18,7 +18,7 @@ package me.zhengjie.modules.system.rest; ...@@ -18,7 +18,7 @@ package me.zhengjie.modules.system.rest;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import me.zhengjie.aop.log.Log; import me.zhengjie.annotation.Log;
import me.zhengjie.exception.BadRequestException; import me.zhengjie.exception.BadRequestException;
import me.zhengjie.modules.system.domain.Dict; import me.zhengjie.modules.system.domain.Dict;
import me.zhengjie.modules.system.service.DictService; import me.zhengjie.modules.system.service.DictService;
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment