今日は、Web(そしておそらくそれだけではない)アプリケーションのセキュリティについて説明します。アプローチとフレームワークについて説明する前に、少し背景を説明します。
バックグラウンド
ITでの長年の仕事で、私はさまざまな分野のプロジェクトに取り組む必要がありました。各プロジェクトには独自のセキュリティ要件がありました。認証に関してすべてが要件に関してほぼ同じである場合、承認メカニズムを実装する方法はプロジェクトごとにかなり異なることが判明しました。毎回、プロジェクトの特定の目標のために、アーキテクチャソリューションを開発し、要件の変更やテストなどでそれを改良するために、承認をほぼゼロから作成する必要がありました。 -これはすべて、開発で回避できない一般的なプロセスです。次のそのようなアーキテクチャのアプローチを実装するたびに、承認の主な目的をカバーし、他のアプリケーションで再利用できる、ある種の一般的なアプローチが思い浮かぶ可能性があるという感覚がますます高まっていました。この記事では、開発された例を使用して、承認に対する一般化されたアーキテクチャアプローチについて検討します。フレームワーク。
フレームワークを作成するためのアプローチ
いつものように、何か新しいものを開発する前に、どの問題を解決するか、フレームワークがどのように便利で便利になるかを決定する必要があります。おそらく、既成の解決策がすでにあります(これについては後で説明します)。
誰もがコーディングの2つのスタイルを知っています-必須と宣言。必須スタイルは結果を取得する方法を説明し、宣言スタイルは結果を取得する方法を説明します。
, , . , , (permissions) ..
( ) , . , . ( ), — , .
, , . , , — . : , , — , .
:
- — , ..
- —
: ( xml, yaml, properties), java annotations.
, , :
- Java annotations java, JVM, runtime, compile time.
- , .. .
- , .. 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
- Java
- Spring-based
この記事では、Easy-ABACFrameworkによって提示された承認へのアーキテクチャ上のアプローチについて説明します。
開発されたフレームワークの利点には、次のものがあります。
- 宣言的承認スタイル
- コンパイル時の構成エラーの処理
- シンプルでわかりやすい構成
- 柔軟性