views:

343

answers:

3

Where is the most fitting place for security and roles authorization to fit into the model view presenter design pattern?

Would it be for all pages that implement security to implement a specific interface, say IAuthorizedView that's along the lines of

public interface IAuthorizedView : IView
{
    IUser user;
    void AuthorizationInitialized();
    void AuthorizationInvoked();
}

Then handled inside the presenter level

public abstract class Presenter<TView> where TView : IView
{
    public TView View { get; set; }

    public virtual void OnViewInitialized()
    {
    }

    public virtual void OnViewLoaded()
    {
    }
}

public abstract class AuthorizationSecuredPresenter<TView> 
                        : Presenter<TView> where TView : IAuthorizedView 
{
    public override void OnViewInitialized()
    {
        View.AuthorizationInitialized();
        base.OnViewInitialized();
    }

    public override void OnViewLoaded()
    {
        View.AuthorizationInvoked();
        base.OnViewLoaded();
    }
}

This would be my first idea on it, the only question this would leave me is if we move from solely web based and added any type of API that required authorization on the service level that there would end up alot of duplication of access checking or is that perfectly acceptable to verify twice and should be designed for up front?

A: 

The View should handles just the UI. It should setup the dialog/form/controls however you need it. When the user tries to authorize hand the data off to the presenter.

The presenter then should take that data and validate it using the API and model exposed from the model.

In my CAD/CAM application the actual API reside in lowest of my application the utility assembly. I wrap and interface around it so that if I chance my security API the upper levels do not see anything different. The Utility tells me if the entered information is valid or not and what level of security to grant the person.

Any more specific depends on the exact security API you are using.

RS Conley
+2  A: 

Here is something that you might want to consider.

I would use the decorator pattern to authorize each call to your object separatly.

Let's say you have the following class:

public class MyService
{
    public virtual void DoSomething()
    {
        //do something on the server
    }
}

You would then proceed to create a base decorator to implement the default constructor like this:

public class MyServiceDecoratorBase : MyService
{
    public MyServiceDecoratorBase(MyService service)
    {
    }
}

Once this is setup, you can actually start to decorate by creating an authorization decorator like this:

public class MyServiceAuthorizationDecorator : MyServiceDecoratorBase
{
    private readonly MyService _service;
    public MyServiceDecoratorBase(MyService service)
    {
        _service = service;
    }

    public override void DoSomething()
    {
        //TODO: Authorize the user here.
        _service.DoSomething();
    }
}

So now that the main classes are done... how are you going to call all this? Easy!

MyService service = new MyServiceAuthorizationDecorator(new MyService());
service.DoSomething();

Now... the advantage of all that is that your authorization logic is completely decoupled from your main service(or object) logic. Why is this important? Testability. You can test your main service independently of your authorization logic. This correspond to the Open/Close Principle.

Now, let's say you want to calculate performance on those pesky methods... add a decorator! Logging? Another decorator! They can all be chained that way. Of course, the more you add and the heavier it gets but I think that it's worth it for the advantage it gives.

Comments?

Maxim
+2  A: 

Your design looks fine; as for your concluding question ...

if we move from solely web based and added any type of API that required authorization on the service level that there would end up alot of duplication of access checking or is that perfectly acceptable to verify twice and should be designed for up front?

The answer is emphatically yes - you may even want to verify permissions more often than that, even when these checks are semi-redundant. I can think of at least three times I'd check security in a typical web application (with role-based security requirements):

  • First, inside your business layer - to ensure security is applied no matter what the execution context.

  • Second, when creating the view itself (or its presenter), it's important to make sure users only see features for which they have permission - both for security reasons and so they don't waste their time.

  • Third, when constructing menus to make sure that users don't see functionality that they don't have permission to use. Again, this is for both security and usability reasons. You don't want to distract users with features they can't use, if you can help it.

Jeff Sternal