Hoje vamos falar sobre segurança em aplicativos da web (e, provavelmente, não apenas). Antes de descrever as abordagens e estruturas, vou lhe contar um pouco do contexto.
fundo
Por muitos anos de trabalho na área de TI, tive que lidar com projetos em diversas áreas. Cada projeto tinha seus próprios requisitos de segurança. Se em termos de autenticação tudo era mais ou menos igual em termos de requisitos, as formas de implementação do mecanismo de autorização revelaram-se bastante diferentes de projeto para projeto. Cada vez, a autorização tinha que ser escrita quase do zero para os objetivos específicos do projeto, desenvolver uma solução arquitetônica e, em seguida, modificá-la com mudanças de requisitos, teste, etc. - tudo isso é um processo comum que não pode ser evitado no desenvolvimento. Com cada implementação da próxima abordagem arquitetônica, havia mais e mais a sensação de que você poderia chegar a algum tipo de abordagem geral que cobriria os principais objetivos da autorização e que poderia ser reutilizada em outros aplicativos.Este artigo irá considerar uma abordagem arquitetônica generalizada para autorização usando o exemplo doquadro .
Abordagens para a criação de uma estrutura
Como de costume, antes de desenvolver algo novo, você precisa decidir quais problemas serão resolvidos, como o framework será conveniente e útil e, talvez, já haja uma solução pronta (falaremos sobre isso mais tarde).
Todo mundo conhece dois estilos de codificação - imperativo e declarativo. O estilo imperativo descreve como obter o resultado, o estilo declarativo descreve o que você deseja obter como resultado.
, , . , , (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);
}
}
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({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
O artigo discute abordagens arquitetônicas para autorização, apresentadas pelo Easy-ABAC Framework.
Entre as vantagens do framework desenvolvido estão:
- Estilo de autorização declarativa
- Tratamento de erros de configuração em tempo de compilação
- Configuração simples e direta
- Flexibilidade