Dynamically apply values to the Roles property for the AuthorizedAttribute class

rsford31

New member
Joined
Mar 22, 2016
Messages
3
Programming Experience
1-3
We have an application that have three levels of roles. Depending on which role a user is in determines what they have access to. The users are in activedomain groups. The client has asked that test groups be created for test and the original groups are to be used in production. We're using web.config transforms to distinguish the groups in each environment. Previous to this the AuthorizedAttribute class was set up for a save method as follows:
C#:
[AuthorizeUsers(Roles = "Group A, Administration")]    public SomeInformation Post([FromBody]SomeInformation infodata)
    {
        return _manager.SaveInfo(infodata);
    }
The Group A and Administration are production. In test there is now Group A - Test and Administration - Test.

Here is our AuthorizeUsers class:
C#:
public class AuthorizeUsers : AuthorizeAttribute    {
        protected override bool IsAuthorized(System.Web.Http.Controllers.HttpActionContext actionContext)
        {
            
            var isAuthorized = base.IsAuthorized(actionContext);
            if (!isAuthorized)
                return false;


            return  HttpContext.Current.User.IsInRole(Settings.Default.GroupA)
                || HttpContext.Current.User.IsInRole(Settings.Default.Administration);
        }
    }


Is there a way to pull from the web.config file and assign it to the Roles property?


We tried the following:
C#:
private string Env = Settings.Default.GroupA + ", " + Settings.Default.Administration
 [AuthorizeUsers(Roles = Env)]
But it gacked. The AuthorizeUsers class inherits from AuthorizeAttribute. Any ideas?

Just a note as to why we're looking at doing this is because the testers have lower access in production but need higher access in test to test all the functionality.
 
Last edited:

jmcilhinney

C# Forum Moderator
Staff member
Joined
Apr 23, 2011
Messages
4,249
Location
Sydney, Australia
Programming Experience
10+
You can only use constant values with attributes. The way to solve your issue is with conditional compilation. You can create two different build configurations, one with a compilation constant set and the other without. You can then use that constant to decide which version of the attribute creation to compile, with one build used for testing and the other for production.

Firstly, open the Configuration Manager from the Build menu and create a new build configuration based on your current Release configuration. Select that as the current configuration and go to the Build page of the project properties, there adding a conditional compilation constant, e.g. ALLOW_REDUCED_ACCESS. You can then write your code like this:
#if ALLOW_REDUCED_ACCESS
        [AuthorizeUsers(Roles = "Group A - Test, Administration - Test")]
#else
        [AuthorizeUsers(Roles = "Group A, Administration")]
#endif
        public SomeInformation Post([FromBody]SomeInformation infodata)
        {
            // ...
        }
The first version of the attribute creation will then be included in the compilation if the current configuration defines the ALLOW_REDUCED_ACCESS constant and the second will be included otherwise. You simply change the current build configuration to change how the attribute is created.
 

rsford31

New member
Joined
Mar 22, 2016
Messages
3
Programming Experience
1-3
Thanks for this...we currently have three build configurations: test (which would be for deploying to the test server for the clients to test), debug (used locally) and release (used for production). I'm just trying to understand why we would create a fourth configuration based on release? If test users have less access in production would we put the ALLOW_REDUCED_ACCESS in the release configuration? So the code would be the controllers
C#:
[COLOR=gray][FONT=Consolas]#if ALLOW_REDUCED_ACCESS[/FONT][/COLOR][COLOR=#3E3E3E][FONT=Consolas]        
[AuthorizeUsers(Roles = "Group A, Administration")][/FONT][/COLOR]
[COLOR=#3E3E3E][FONT=Consolas]#else[/FONT][/COLOR]
[COLOR=#3E3E3E][FONT=Consolas]        [AuthorizeUsers(Roles = "Group A - TEST, Administration - TEST")][/FONT][/COLOR]
[COLOR=#3E3E3E][FONT=Consolas]#endif[/FONT][/COLOR]
[COLOR=#3E3E3E][FONT=Consolas]        public SomeInformation Post([FromBody]SomeInformation infodata)[/FONT][/COLOR]
[COLOR=#3E3E3E][FONT=Consolas]        {[/FONT][/COLOR]
[COLOR=#3E3E3E][FONT=Consolas]            // ...[/FONT][/COLOR]
        }

And just so I understand the ALLOW_REDUCED_ACCESS would go in the project > Properties > Build > Conditional compilation symbols?
I really appreciate this help. Thank you so much for your time!
 
Last edited:

jmcilhinney

C# Forum Moderator
Staff member
Joined
Apr 23, 2011
Messages
4,249
Location
Sydney, Australia
Programming Experience
10+
If you already have a test configuration then you don't need to create another one.

I would tend to put the constant in the test configuration because that's the special one from that perspective. You could do it either way but if you add it to release then will you need to add it to debug too? Test is the special case so that's where I would tend to define the constant but what really matters is that you can distinguish one configuration from another.

Yes, that's where the constant would be defined.
 
Top Bottom