0

I want to assign Active Directory group name dynamically as an attribute to authorize filter.

Currently we have 2 Active Directory groups, one is for DEV and other is for Prod. However if I have access to dev while debugging in local, I need to have access to the action method. If the AD group is prod, I should not have have access to the action method.

I tried using constants in static class classA

public const  string DevActiveDirectoryName = "DevdirectoryName";
public const  string ProdActiveDirectoryName = "ProddirectoryName";

My action method is like this:

[Authorize(Roles = ClassA.DevActiveDirectoryName)]
public async task<Iactionresult>GetMemberID()
{
}

The only problem with above solution is if I want to deploy to prod, I need to change code and deploy it. Instead if I can pass value dynamically to attribute that would solve my problem. I have tried many ways. Please suggest the best solution for this case. Is there any workaround for this kind of problem? I appreciate your help.

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
user1989
  • 47
  • 2
  • 7

2 Answers2

0

You can add an entry in your <appSettings> of your web.Config file and use ConfigurationManager to look up the value that should be assigned to a variable ActiveDirectoryName.

<appSettings>
  <add key="ActiveDirectoryName" value="DevdirectoryName" />
  ... // other keys
</appSettings>

and in your code, you could look up what you have in your web.Config file (Dev for development and Prod for production servers (you dont need to deploy new web.config when deploying new code unless you make changes to it.

public const string ActiveDirectoryName = ConfigurationManager.AppSettings["ActiveDirectoryName"];

If you are using Visual Studio, web.config have two different configs (web.debug.config / web.release.config). You can use debug for development and Release that works on production.

This will stay constant and only your config files are changed,

[Authorize(Roles = ClassA.ActiveDirectoryName)]
public async task<Iactionresult>GetMemberID()
{
}
Jawad
  • 11,028
  • 3
  • 24
  • 37
  • Hi Jawad - I appreciate your response but this is implementation in .Net core 2.1 . I dont think web.config can be used. Any other ideas ? – user1989 Jun 29 '20 at 03:37
  • [See documentation](https://learn.microsoft.com/en-us/aspnet/core/fundamentals/configuration/?view=aspnetcore-3.1) on appsettings.json for .net core. Same idea of using a config file for value. [Another SO link](https://stackoverflow.com/a/46940811/1390548) for .net 2.1 – Jawad Jun 29 '20 at 03:46
0

In order to be able to change the group name for different environments, you need to use configuration settings instead of constants. There are many options on how to provide configuration settings to an ASP.NET Core application. This link gives an overview.

If your application uses the default host builder, it will read configuration settings from a variety of sources, e.g. appsettings.json. You can add a setting to this file (if it does not exist yet, add it to the project), e.g.:

{
  "ADGroupName": "ProddirectoryName"
}

For your dev-environment there is a dedicated file appsettings.dev.json that you can use to hold your dev settings:

{
  "ADGroupName": "DevdirectoryName"
}

When protecting the controller with an Authorize attribute, you need to provide a constant value to the constructor. As the configuration setting can be changed later, it is (obviously) not constant.

Therefore, you have to set up a policy with a constant name in the ConfigureServices method in Startup.cs:

var adGroupName = Configuration.GetValue<string>("ADGroupName");

services.AddAuthorization(options =>
{
    options.AddPolicy("ADGroupPolicy", policy =>
    {
        // This requirement checks for the group
        policy.RequireRole(adGroupName);
    });
});

For the controller, you need to add the policy name to the Authorize attribute:

[Authorize("ADGroupPolicy")]
public async task<Iactionresult>GetMemberID()
{
}
Markus
  • 20,838
  • 4
  • 31
  • 55