Gabriel Lopez
Gabriel Lopez

Reputation: 159

Design Pattern to check user access permissions .net

I apologize if this has been asked before but looking around in StackOverflow I couldn't find something that would answer my question.

I have a system composed of Accounts. Each account can have several users and each user can interact with each other as long as they belong to the same account. Users from different accounts can't perform actions on each other. In addition, I have Roles such as Admin, RegularUser, etc but these roles are limited to each account. That is thse roles don't allow users from different accounts to perform actions on other accounts.

I am looking for a good way to implement permissions. Before performing an action, let say "Add New User" I want to check if the user performing the action, has the necessary access level (based on different rules such as Role, Action Type, if they belong to the same account, etc).

I put together a quick example of how the current code sort of looks.

public interface IUserService
{
    void Add(User newUser);
    void Method1();
    void Method2();
    etc
}

public interface IAccountService
{
    void Create(Account newAccount);
    void Method1();
    void Method2();
    etc
}

public interface IUserAccessService
{
    bool CanPerformAction(int requesterId, otherparameters);
}

public class UserService
{
    private readonly IUserAccessService _userAccessService;

    public UserService(IUserAccessService userAccessService)
    {
        _userAccessService = userAccessService;
    }

    public void Add(User newUser)
    {
        if (!_userAccessService.CanPerformAction(xxx))
            throw;
        AddUser...
    }

    public void Method1()
    {
        if (!_userAccessService.CanPerformAction(xxx))
            throw;
        DoSomething...
    }

    public void Method2()
    {
        // do not check if user can perform action
        DoSomething...
    }
}

I am looking for a way to make sure, whoever implements the interface, that doesn't forget to check for permissions. As you can see in the code above, Add and Method1 do require this check but Method2 doesn't.

I was thinking of using the template design pattern in order to accomplish this (see below), however, it doesn't look like this is the best approach.

public abstract class UserServiceBase
{
    public abstract void Add(User newUser);
    public abstract void Method1();
    public abstract void Method2();
    public abstract bool CanPerformAction(int requesterId, otherparameters);
    etc

    public void AddTemplateMethod(User newUser)
    {
        if (!CanPerformAction(newUser.Id, otherparamters)   
            throw;
        Add(newUser);
    }

    public void Method1TemplateMethod()
    {
        if (!CanPerformAction(someparameters)   
            throw;
        Method1();
    }

}

public abstract class UserService : UserServiceBase
{
    public override void Add(User newUser)
    {
        Add User...
    }

    public override void Method1()
    {
        Do something...
    }

    public override void Method2()
    {
        Do something...
    }
}

With the code above, at least we would check if the user can perform the action or not, but like I say, it doesn't seem to me like the best way to do it.

In case it helps, I am using autofac as my IoC and I am using C# .net 4.5.

Any advice would be greatly appreciate it.

Thank you in advance.

PS. I am not sure I explained myself very well, please let me know if you need further information or clarification.

Upvotes: 3

Views: 3525

Answers (1)

George Howarth
George Howarth

Reputation: 2903

You could use the Decorator pattern like in this question, but as the question implies, it works best in conjunction with the Command / Query pattern. Another alternative is to use Interception.

Whichever method you choose though, don't put cross-cutting concerns in a base class as that can lead to a God object.

Upvotes: 2

Related Questions