Authorization in class libraries

6

Doubt

I have a project where the entire business rule is encapsulated in a set of DLLs with 3-tier architecture.

I wonder, what is the best approach for authorization control in these dll's. Is it possible to use Identity? Is there a design pattern or some other best approach to solve this problem?

Considering that a user can have a profile with access to certain functionalities (methods or classes).

Initially, I implemented a feature table and a profile table that contains these features. In the application, an Attribute above methods or classes indicates which functionality can access the code.

To verify that the user can access the code, it is checked whether the user's profile has the functionality described in Attribute . However, I'm not sure that this form is the most elegant for the situation.

Architecture

The solution architecture is implemented according to the Onion architecture. The Service layer encapsulates the entire system business rule and has access to Domain and Repositories .

The Web project (MVC) and Web Api have access to DLL Services, and access control is now in place. To prevent these and other external projects that want to access Services from implementing each of their authorization controls, an access control has been created as described below.

Current Code

AttributeUsage(AttributeTargets.Method)]
public class ControleAcessoAttribute : Attribute
{
    private string[] funcionalidades;
    private UsuarioAutenticado usuario;

    public ControleAcessoAttribute(params string[] funcionalidades)
    {
        this.funcionalidades = funcionalidades;
        this.usuario = UsuarioAutenticado.GetInstance();
        VerificarAcesso();
    }

    public void VerificarAcesso()
    {
        var isAutorizado = VerificarFuncionalidades();
        if(!isAutorizado)
        {
            throw new NegocioException("O usuário autenticado não possui permissão para acessar esta funcionalidade.");
        }
    }

    public bool VerificarFuncionalidades()
    {
        foreach (var item in usuario.Perfil.Funcoes)
        {
            for (int i = 0; i < funcionalidades.Length; i++)
            {
                if(item.Descricao.Contains(funcionalidades[i]))
                    return true;
            } 
        }
        return false;
    }

Usage method

public class Foo
{
      [ControleAcesso("Bar","Foo")]
      public void Bar()
      {
           //Some code here
      }
}

Another problem

Another problem I am facing is in knowing which is the authenticated user in the applications, since the web project can implement Session and others do not. Should this authentication be the DLL's responsibility? Is it better to save the authentication to the database?

    
asked by anonymous 06.01.2015 / 17:15

1 answer

7

I wonder, what is the best approach for authorization control in these dll's. Is it possible to use Identity?

It is possible, but Identity was designed for the MVC architecture initially. It will work well if the flow of your services layer is similar to a Controller .

Is there a design pattern or some other approach best suited to solve this problem?

It depends on what you need. Taking the hook from your implementation by Attribute passing features per parameter, the approach is correct, but I have some observations:

Strings are more prone to problems at some point (especially typing problems). Instead of using:

[ControleAcesso("Bar","Foo")]

Create an Enum of functionality:

public enum Funcionalidade {
    Foo, Bar
}

Pass them as a parameter:

[ControleAcesso(Funcionalidade.Bar, Funcionalidade.Foo)]

VerificarFuncionalidades can be simplified and will be more efficient and more secure in terms of code.

On Sessions , you will have to write your own session control, since you are not using ready-made solution of some known architecture.

On where to store these data, I think that is an opinion piece of the question. By load balancing, I prefer to keep in the database or using some key-value cache, such as Redis, for example.

    
07.01.2015 / 08:36