服务器应用程序中授权的体系结构方法:基于活动的访问控制框架

今天,我们将讨论Web(以及(可能不仅是))应用程序中的安全性。在介绍这些方法和框架之前,我会告诉您一些背景知识。



背景



在IT领域多年的工作中,我不得不处理各个领域的项目。每个项目都有自己的安全要求。如果就身份验证而言,所有方面在要求方面或多或少都相同,那么事实证明,实施授权机制的方法因项目而异。每次,几乎都必须从头开始针对项目的特定目标编写授权,开发体系结构解决方案,然后根据不断变化的需求,测试等进行修改。 -所有这是开发中无法避免的通用过程。随着下一个这样的体系结构方法的每次实现,越来越多的人感觉会出现某种通用方法,该方法将涵盖授权的主要目的并且可以在其他应用程序中重用。本文将以开发的示例为例,考虑一种通用的架构授权方法。框架



创建框架的方法



像往常一样,在开发新东西之前,您需要确定要解决的问题,该框架将如何方便和有用,并且也许已经有现成的解决方案(我们将在后面讨论)。



每个人都知道两种编码样式-命令式和声明式。当务之急风格描述如何得到结果,声明式的描述了想要得到的结果。



声明式样式很方便,因为它花费最少的精力和时间来指示所需的结果。例如,对于授权,这可以通过描述用于访问资源,权限等的用户角色的形式来完成。

但是,声明式的样式并不能解决所有问题(至少出于授权目的),实际上并不能解决。命令式样式很方便,因为它为实现提供了必要的灵活性。例如(在授权中)将如何实现为用户分配权限机制-静态或动态地取决于用户。



, , . , , — . : , , — , .





:



  1. — , ..




: ( xml, yaml, properties), java annotations.

, , :



  1. Java annotations java, JVM, runtime, compile time.
  2. , .. .
  3. , .. java.




:



  • , ( , Admin, Viewer, Editor)
  • , (permissions) ( , .. )
  • , ( actions) ( ), .. , ( ) , , ( create, modify, delete). , . action-based , — , , , .




. , . .



, java annotations . — .. . Java Annotation Processing, .



Java Module System, Oracle, JDK 9, .





:



  • , , , , , .. .
  • (actions)
  • , ()
  • ( ) ()
  • () — , ,


Easy-ABAC Framework



.



Spring Boot .

( maven):



<dependency>
  <groupId>com.exadel.security</groupId>
  <artifactId>easy-abac</artifactId>
  <version>1.1</version>
</dependency>


1.1.



, :



@SpringBootApplication
@Import(AbacConfiguration.class)
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}


Project . , .



1.



, :





:





(, , , .. — ).



:



import com.exadel.easyabac.model.core.Action;

public enum ProjectAction implements Action {
    VIEW,
    UPDATE,
    CLOSE,
    DELETE
}


- com.exadel.easyabac.model.core.Action. enum — .

, enum () , — , .



2.



- :



@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.PARAMETER)
public @interface ProjectId {
}


.



:



import com.exadel.easyabac.model.annotation.Access;
import com.exadel.easyabac.model.validation.EntityAccessValidator;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.TYPE})
@Access(identifier = ProjectId.class)
public @interface ProjectAccess {

    ProjectAction[] actions();

    Class<? extends EntityAccessValidator> validator();
}


actions validator , :



Error:(13, 9) java: value() method is missing for @com.example.abac.model.ProjectAccess
Error:(13, 9) java: validator() method is missing for @com.example.abac.model.ProjectAccess


Target:



@Target({ElementType.METHOD, ElementType.TYPE})


, — instance- .



3.



:



import com.exadel.easyabac.model.validation.EntityAccessValidator;
import com.exadel.easyabac.model.validation.ExecutionContext;
import com.example.abac.model.ProjectAction;
import org.springframework.stereotype.Component;

@Component
public class ProjectValidator implements EntityAccessValidator<ProjectAction> {

    @Override
    public void validate(ExecutionContext<ProjectAction> context) {
        // here get current user actions
        // and compare them with context.getRequiredActions()
    }
}


( ):



@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.TYPE})
@Access(identifier = ProjectId.class)
public @interface ProjectAccess {

    ProjectAction[] value();

    Class<? extends EntityAccessValidator> validator() default ProjectValidator.class;
}


:



@ProjectAccess(value = ProjectAction.VIEW, validator = ProjectValidator.class)


4.



, :



import com.exadel.easyabac.model.annotation.ProtectedResource;
import com.example.abac.Project;
import com.example.abac.model.ProjectAccess;
import com.example.abac.model.ProjectAction;
import com.example.abac.model.ProjectId;
import org.springframework.web.bind.annotation.*;

@RestController
@ProtectedResource
@RequestMapping("/project/{projectId}")
public class ProjectController {

    @GetMapping
    @ProjectAccess(ProjectAction.VIEW)
    public Project getProject(@ProjectId @PathVariable("projectId") Long projectId) {
        Project project = ...; // get project here
        return project;
    }

    @PostMapping
    @ProjectAccess({ProjectAction.VIEW, ProjectAction.UPDATE})
    public Project updateProject(@ProjectId @PathVariable("projectId") Long projectId) {
        Project project = ...; // update project here
        return project;
    }

    @PostMapping("/close")
    @ProjectAccess(ProjectAction.CLOSE)
    public Project updateProject(@ProjectId @PathVariable("projectId") Long projectId) {
        Project project = ...; // close project here
        return project;
    }

    @DeleteMapping
    @ProjectAccess(ProjectAction.DELETE)
    public Project updateProject(@ProjectId @PathVariable("projectId") Long projectId) {
        Project project = ...; // delete project here
        return project;
    }
}


@ProtectedResource , — instance- @Access-based , — .



@PublicResource , , , @ProtectedResource



, , . , ( ).



5.



. . , , — -.



, EntityAccessValidator, validate:



public void validate(ExecutionContext<Action> context);


ExecutionContext - : context.getRequiredActions() Action, .



Action — — . Action(s) : , ...



2 Actions — , — Action — . exception, , AccessDeniedException ExceptionHandler HTTP status 403 — .



.









, - , , - . , , :



: Apache Shiro, JAAS, Spring Security.

Apache Shiro JAAS , , JAAS , Apache Shiro — — , ,

Spring Security — ( ), , compile-time. . , .



Easy-ABAC Framework , , — ...





, . " " .

spring-based . Spring.

.



C



  1. Java
  2. Spring-based




本文讨论了Easy-ABAC框架提出的授权体系结构方法。

已开发框架的优点包括:



  1. 声明式授权样式
  2. 在编译时处理配置错误
  3. 简单直接的配置
  4. 灵活性



All Articles