Question

For authorization in an Entity Framework application, I've written this class which check's whether the current user is in the specified role.

public class AuthorizeDesignatedRoles : AuthorizeAttribute {

        public const string DELETE = System.Configuration.ConfigurationManager.AppSettings["GroupAuthorizedForDeleteAction"].ToString();
        public string DesignatedRoles { get; set; }

        protected override bool IsAuthorized(System.Web.Http.Controllers.HttpActionContext actionContext) {
            bool isAuthorizedBase = base.IsAuthorized(actionContext);
            if (!isAuthorizedBase)
                return false;


            string[] roles = DesignatedRoles.Split(';');  // Multiple roles can be seperated by a semicolon ;
            foreach (string role in roles) {
                if (System.Web.Security.Roles.IsUserInRole(role))
                    return true;
            }
            return false;
        }

    }

Now I can allow controller actions only to be carried out by users who are in a designated role.

[AuthorizeDesignatedRoles(DesignatedRoles = AuthorizeDesignatedRoles.DELETE)]
public HttpResponseMessage DeleteThisAndThat(long id) { ... }

The problem is that I do not want to put the name of the designated DELETE group in the code but in the web.config file. By doing so, Visual Studio complains that it is not a constant string any more.

How can I make it a constant string again?

Edit: When I leave out the const keyword and make DELETE static readonly instead, the compiler says An attribute argument must be a constant expression, typeof expression or array creation expression of an attribute parameter type.

Was it helpful?

Solution

What about storing the AppSettings key in the constant and fetch its value in the IsAuthorized method:

public class AuthorizeDesignatedRoles : AuthorizeAttribute
{
    public const string DELETE = "GroupAuthorizedForDeleteAction";

    public string DesignatedRoles { get; set; }

    protected override bool IsAuthorized(System.Web.Http.Controllers.HttpActionContext actionContext) {
    {
        // ...

        string[] roles = DesignatedRoles.Split(';')
                                        .Select(s => ConfigurationManager.AppSettings[s].ToString())
                                        .ToArray();

        foreach (string role in roles)
        {
            // ...
        }
    }
}

OTHER TIPS

TL;DR: Use readonly rather than const.

Constants need to be set at compile time, and not change in compatible updates. The compiler can and does copy the values of constants from referenced assemblies into their output assembly.

Read-only values can be set in code before references to the type (static readonly) or in the constructor (member readonly) but no further changes is then enforced.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top