0

Is there any way to change parameters of attribute at run time? I have a service in which I am assigning roles who can access the service. I want to assign these roles at run time.

  [HttpGet]
   [Authorize(Roles="admin")]
    public DataTable GetAllProducts()
    {
        FormToken auth = new FormToken();
        DataTable dt = new DataTable();
        if (!auth.isAuthenticated())
        {
            dt.Columns.Add("Error");
            DataRow dr = dt.NewRow();
            dr["Error"] = "Login to get the Service";
            dt.Rows.Add(dr);
            return dt;
        }
        var rec = from log in db.Products select log;
        return rec.ToDataTable();
tereško
  • 58,060
  • 25
  • 98
  • 150
vivek
  • 79
  • 2
  • 11
  • I know same type of question was asked before but I did not found any satisfactory answer on it. – vivek Sep 19 '13 at 13:07

3 Answers3

2

Vivek,

The authorize attribute can be inherited from and you can override the OnAuthorize method. Something like below.

public sealed class AuthorizationAttribute : AuthorizeAttribute
{
    public override void OnAuthorization(AuthorizationContext filterContext)
    {
        //do custom authorization here
        base.OnAuthorization(filterContext);
    }
}

At this point you can do anything you wish for authorization. You can add custom constructors to set your own variables. For example I currently use this override to detect if the user is authorized and they have access to a specific location.

Cheers

Nico
  • 12,493
  • 5
  • 42
  • 62
1

The method proposed by @Nico will work.

An alternative, that arguably provides better encapsulation and flexibility is to use the ClaimsPrincipalPermissionAttribute instead of the AuthorizeAttribute. This is part of WIF, which is in theory the preferred framework for identity and authorization in .Net.

In this model, the ClaimsPrincipalPermissionAttribute specifies the authorization context of the request, in terms of an Resource and Operation - that is it describes the request, not who can access it.

The actual authorization logic is then encapsulated in a custom ClaimAuthorizationManager that is given the current user principal and the authorization context. It's job is purely to do the authorization check. The ClaimAuthorizationManager can be controlled by configuration in the application web.config file.

This is all described here

http://msdn.microsoft.com/en-us/library/system.identitymodel.services.claimsprincipalpermissionattribute.aspx

Although I prefer this method I don't think there are very strong reasons to prefer one over the other. I think the advantage of this approach are:

  • It provides better encapsulation
  • It is more flexible
  • It is called by the CLR rather than the MVC framework, meaning it will get called by unit tests or anywhere the decorated method is called
  • It can be used imperatively as well as declaratively (ClaimsPrincipalPermission.CheckAccess("Customer","Add"))
  • It seems to be more aligned with the direction Microsoft are going

A disadvantage is

  • It is .Net 4.5 only. If you are on .Net 3.5 or 4, then you would have to use the earlier version of WIF. It is very similar to the .Net 4.5 version (but not identical). The namespaces are Microsoft.IdentityModel instead of System.IdentityModel

As I say though, it is a mostly a matter of preference in my opinion.

Mike Goodwin
  • 8,810
  • 2
  • 35
  • 50
0

For non-declarative user permission verification, you may want to consider using System.Security.Permissions.PrincipalPermission instead of AuthorizeAttribute. This would allow you to specify the target role at runtime. Depending on how you are doing authentication, you may need to ensure that the authenticated user principal is assigned to Thread.CurrentPrincipal, which is what PrincipalPermission uses, as opposed to just HttpContext.Current.User (which is what the MVC AuthorizeAttribute uses).

Nicole Calinoiu
  • 20,843
  • 2
  • 44
  • 49