Authorization in class Ibraries

Asked

Viewed 134 times

6

Doubt

I’m with a project in which all business rule is encapsulated in a set of DLL’s with 3-layer architecture.

I would like to know, what is the best approach to authorization control in these dll’s. Is it possible to use Identity? Is there any Pattern design or other more appropriate approach to solve this problem?

Taking into account that a user may 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, a Attribute above methods or classes indicates which functionality can access the code.

To verify that the user can access the code, it is verified that 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 layer Service encapsulates the entire system business rule and has access to the Domain and to Repositories.

The Web project (MVC) and Web Api have access to DLL Services, and access control enters at this time. 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;
    }

Method of use

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

Another problem

Another problem I’m facing is knowing which user is authenticated in the applications, since the web project can implement Session and others not. Should this authentication be the responsibility of the DLL? The most correct would be to store the authentication in the database?

  • 1

    Vinicius, I will reopen your question as I consider that there is a possibility of getting a good answer. But I also suggest that you edit the question by placing some piece of code that exemplifies your approach. Hug!

  • I will edit the question with the existing code today and the architecture used in the DLL’s!

1 answer

7

I would like to know, what is the best approach to authorization control in these dll’s. It is possible to use Identity?

Possible, but Identity was designed for the MVC architecture initially. It will work well if your service layer flow looks like a Controller.

Is there any Pattern design or other more appropriate approach to solve this problem?

It depends on what you need. Taking advantage of the hook of your implementation by Attribute passing functionalities by parameter, the approximation 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 a feature Enum:

public enum Funcionalidade {
    Foo, Bar
}

Pass them as parameter:

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

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

About Sessions, you will have to write your own session control, since you are not using any known architecture’s ready solution.

About where to store this data, I think it’s an opinionated part of the issue. By load balancing, I prefer to keep in the database or using some key-value cache, such as Redis, for example.

  • I’ll raise the question then with the code I have today

  • @Vinícius I updated the answer.

  • initially was with Enum but this was too big. Enum was enumerating the keys of the functions registered in the database. You think this approach is right?

  • 1

    @Vinícius Safer, I would say. Let it get big. Better so than something prone to error.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.