Onde aplica regras de autorização para meu aplicativo em camadas?


8

Esta pergunta é sobre a aplicação de regras do meu aplicativo que me confundem.

Meu controlador está usando o serviço e o serviço está usando o repositório.

public class CommentController: ApiController{

    [HttpPost]
    public bool EditComment(Comment comment){
        commentService.Update(comment);
    }
}

public class CommentService{
    ICommentRepository repository;
    ....
    ....
    public void Update(Comment comment){
        repository.Update(comment);
    }
}

Se o usuário estiver autenticado, ele poderá atualizar um comentário.

  • Mas um usuário deve editar seus próprios comentários.

  • Mas um administrador pode editar todos os comentários.

  • Mas o comentário não pode editar após uma data especificada.

  • Editar por um departamento

E eu tenho algo parecido com essas regras.

Se eu aplicar a regra "comentário de edição do usuário" na camada de serviço, alterarei a methot de atualização e passarei o parâmetro do controlador User.Identity.Name,

public class CommentService{
    ICommentRepository repository;
    ....
    ....
    public void Update(string updatedByThisUser, Comment comment){
        // if updatedByThisUser is owner of comment
        repository.Update(comment);
    }
}

Mas, é verdade a alteração das operações de serviço por regra?

Estou um pouco confuso sobre onde posso aplicar as regras. No controlador ou no serviço ou no repositório.

Existe alguma maneira padrão de fazer isso como padrões de design.


Na minha experiência, é sempre bom aplicar a autorização no nível do controlador. Você colocaria um atributo de autorização acima do nome da classe Controller da seguinte maneira: [Authorize(Roles="member, admin")]e agora todos os métodos de ação no Controller seriam acessíveis apenas pelos usuários na função de "membro" ou "administrador".
Alternatex

1
Porém, se eu precisar usar meu serviço no projeto de área de trabalho e no projeto do site MVC, aplique novamente as regras Autorizar todos os projetos.
barteloma

Respostas:


1

Eu gostaria

  • crie um PermissionService separado que implemente métodos como isUserAllowedTo(user, PermissionService.Permissiontype.Update, PermissionService.Topic.COMMENT, additionalContextRelevantParameters)
  • e chame os PermissionServicemétodos no controlador, onde informações de contexto necessárias (por exemplo, da sessão) estão disponíveis.

Você pode projetar sua arquitetura para chamar o serviço de permissão no CommentService. Mas eu não recomendaria isso, porque isso adicionaria dependências adicionais ao serviço (ou seja, sessão), o que tornaria o teste de unidade muito mais difícil.


1

Primeiro, reserve um tempo para considerar pelo que o serviço de comentários é realmente responsável. Isso dependerá de seus requisitos específicos e, possivelmente, até de seu próprio julgamento.

Se a responsabilidade do serviço de comentários se limitar a atualizar qualquer comentário , o que você escreveu está bem. Nesse caso, você precisará considerar alguma outra lógica condicional para verificar se algum comentário pode ser atualizado. Você provavelmente fará isso no controlador ou poderá criar um subsistema separado para verificar se um Usuário pode postar um comentário. Você pode reutilizá-lo exatamente como planeja reutilizar o serviço de comentários.

Se o serviço de comentários for responsável por atualizar os comentários de um usuário , seu serviço se tornará Atualização (Usuário, Comentário de comentário) e você terá flexibilidade para verificar as regras de negócios no próprio serviço.

Agora que você está claro sobre quais são suas intenções de design, terá clareza sobre como implementar sua solução.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.