如何在Web应用程序中构建良好的安全性体系结构?

时间:2018-08-10 12:43:08

标签: java spring spring-security

我想在应用程序中进行动态安全性(春季启动,春季mvc,春季安全性,百里香叶)。

我想在我的Web应用程序页面中添加用户/管理员可以在其中添加一些新权限(仅名称)的页面。 在另一页中,他将能够添加例如菜单中的新位置(或新字段或新标签)。 并且,当他添加此新项目时,他应该可以选择用户必须具有哪些权限才能看到此新菜单位置(对于字段,将具有一个查看权限,一个用于编辑权限)。

您有解决办法如何做这样的事情吗? 我曾经考虑过在春季安全性中使用ALC,但我现在不是一个好的选择。

也许有一种使用@PreAuthorize("hasRole()")的方法吗? 或在添加用户添加的所有主题时添加“组件”表之类的内容。在此表中,将有“编辑权限”和“查看权限”之类的列,我将在其中放置ID的权限,并在所有获取菜单项,字段..

的方法中检查此表

也许这将是蜜蜂自己实现PermissionEvaluator的好的解决方案?

1 个答案:

答案 0 :(得分:2)

我认为您需要使用数据库中的 权限 表创建 角色枚举

  1. 角色枚举

    public enum Roles {
       Admin,
       Pm,
       TeamLead,
       User,
       ...
    }
    
  2. 权限表

  

| ID | ROLE | WORKSPACE | READ | WRITE | DELETE |
  | 1 | Admin | Dashbord | TRUE | TRUE | TRUE |
  | 2 | Admin | Employee | TRUE | TRUE | TRUE |
  | 3 | Admin | Project | TRUE | TRUE | TRUE |
  | 4 | Admin | Task | TRUE | TRUE | TRUE |
  | 5 | Admin | Team | TRUE | TRUE | TRUE |
  | 6 | Pm | Dashbord | TRUE | FALSE | FALSE |
  | 7 | Pm | Employee | TRUE | FALSE | FALSE |
  | 8 | Pm | Project | TRUE | TRUE | TRUE |
  | 9 | Pm | Task | TRUE | TRUE | TRUE |
  | 10 | Pm | Team | TRUE | FALSE | FALSE |
  | 11 | TeamLead | Dashbord | TRUE | FALSE | FALSE |
  | 12 | TeamLead | Employee | TRUE | TRUE | TRUE |
  | 13 | TeamLead | Project | TRUE | FALSE | FALSE |
  | 14 | TeamLead | Task | TRUE | FALSE | FALSE |
  | 15 | TeamLead | Team | TRUE | TRUE | TRUE |
  | 16 | User | Dashbord | FALSE | FALSE | FALSE |
  | 17 | User | Employee | TRUE | FALSE | FALSE |
  | 18 | User | Project | TRUE | FALSE | FALSE |
  | 19 | User | Task | TRUE | TRUE | FALSE |
  | 20 | User | Team | TRUE | FALSE | FALSE |

  1. 您在数据库中的用户表必须添加 userRole
  

@Basic
  @Enumerated(EnumType.STRING)
  private Roles userRole;

  1. 创建自定义注释界面,以角色权限检查当前用户

      

    @Retention(RetentionPolicy.RUNTIME)   公共@interface权限检查   {

    String[] workspace() default {};
    
    boolean read() default false;
    
    boolean write() default false;
    
    boolean delete() default false; }
    
  

@Aspect @Component公共类PermissionAspect {

@Autowired
private PermissionRepository permissionRepository;

@Around("execution(@com.security.annotation.springbootsecuritypermission
     

.aspect.PermissionCheck   * *(..))&& @annotation(permissionCheck)“)       公共对象doSomething(ProceedingJoinPoint pjp,PermissionCheck> permissionCheck)抛出Throwable {           if(permissionCheck.workspace()。length> 0                   && SecurityUtil.getUser()!= null){              列表PermissionList = PermissionRepository.findByRolesAndWorkspaceIn(                       SecurityUtil.getUser()。getRoles(),permissionCheck.workspace());

       Function<PermissionEntity,Boolean> permissionFunction = new Function<PermissionEntity, Boolean>() {
           @Override
           public Boolean apply(PermissionEntity permissionEntity) {
               if(permissionCheck.read() && permissionEntity.getRead()) {
                   return true;
               }
               if(permissionCheck.write() && permissionEntity.getWrite()) {
                   return true;
               }
               if(permissionCheck.delete() && permissionEntity.getDelete()) {
                   return true;
               }
               return false;
           }
       };

       final boolean[] hasPermission = {false};
       permissionList.forEach(permissionEntity -> {
           hasPermission[0] = permissionFunction.apply(permissionEntity);
           if(hasPermission[0]){
               return;
           }
       });

        if(!hasPermission[0]){
            throw new AccessDeniedException("Do not has permission");
        }

    }
    return pjp.proceed();
} }
  1. 您可以在方法上使用自定义注释

      

    @GetMapping(“ dashboard”)@PermissionCheck(workspace =   {Workspace.DASHBOARD},read = true)公共字符串dashboard(){
      返回“仪表盘”; }

如果不太了解我,则可以打开此链接https://github.com/Dilsh0d/spring-boot-security-permission