Conditional .NET Core Authentication Attributes for Development and Production

In short, is it possible to place an authorization attribute based on the environment for my API so that privilege restriction is disabled during the development process and re-enabled in Production?

I have a separate Angular 2 project that I want to call the .NET Core API. We created a separate project so that we can open the Angular 2 project in vscode and debug typescript. Upon completion, we will build the project and place it in the .NET Core project for security reasons.

Our problem is that at the debugging stages we cannot connect to the API, because these are two separate projects, and our Angular 2 project does not have Active Directory. The .NET Core project currently has authentication attributes and does not allow (401) access to the API. It would be nice if we could disable this during development and return during production.

I am also open to any other suggestions on how we can best solve this problem.

[Authorize: (Only in Production)] <-- // something like this??? [Route("api/[controller]")] public class TestController : Controller { ... 
+11
source share
4 answers

ASP.NET Core authorization is policy based. As you can see, AuthorizeAttribute can accept the name of the policy so that it knows what criteria must be met in order for the request to be resolved. I suggest you read the excellent documentation on this.

Returning to your problem, it looks like you are not using a specific policy, so it uses a default value that requires user authentication by default.

You can change this behavior in Startup.cs . If you are in development mode, you can override the default policy so that it does not have any requirements:

 public void ConfigureServices(IServiceCollection services) { services.AddAuthorization(x => { // _env is of type IHostingEnvironment, which you can inject in // the ctor of Startup if (_env.IsDevelopment()) { x.DefaultPolicy = new AuthorizationPolicyBuilder().Build(); } }); } 

Update

im1dermike mentioned in a comment that an AuthorizationPolicy needs at least one requirement, as we can see here . This code has not been recently introduced, so that means the solution above was broken all the time.

To get around this, we can use the RequireAssertion method of the AuthorizationPolicyBuilder and add a dummy requirement. It will look like this:

 public void ConfigureServices(IServiceCollection services) { services.AddAuthorization(x => { // _env is of type IHostingEnvironment, which you can inject in // the ctor of Startup if (_env.IsDevelopment()) { x.DefaultPolicy = new AuthorizationPolicyBuilder() .RequireAssertion(_ => true) .Build(); } }); } 

This ensures that we have at least one requirement in the authorization policy, and we know that it will always pass.

+18
source

Personally, I would set my dev environment as close to prd as possible. Anytime when I start doing something only in Dev, I hate myself for it later.

Do you use Windows Authentication? When Api starts using Windows authentication, it will pick up the user api user authentication through the angular2 application. Therefore, an angular2 application does not require Active Directory.

But if you want to create your own attribute AuthorizeAttribute, as suggested. You can do something like this.

 public class CustomAuthorize : AuthorizationFilterAttribute, IAuthorizationFilter { public override void OnAuthorization(HttpActionContext actionContext) { bool devEnvironment = GetEnvironment(); if (devEnvironment) return; else base.OnAuthorization(actionContext); } public override Task OnAuthorizationAsync(HttpActionContext actionContext, CancellationToken cancellationToken) { bool devEnvironment = GetEnvironment(); if (devEnvironment) return; else base.OnAuthorization(actionContext); } private bool GetEnvironment(HttpActionContext actionContext, bool access) { // code that will tell you if you are in your dev environment or not } } 

Then in your controller, you simply use the [CustomAuthorize] attribute.

+2
source

In the end, I can help:

  public class OnlyDebugModeAttribute : ActionFilterAttribute { public override void OnActionExecuted(ActionExecutedContext context) { base.OnActionExecuted(context); } public override void OnActionExecuting(ActionExecutingContext context) { #if DEBUG //Ok #else context.Result = new ForbidResult(); return; #endif } } 

and then apply it on the controller

 [OnlyDebugMode] [Route("api/[controller]")] [ApiController] public class DebugController : ControllerBase { 
+1
source

Here is my solution:

New attribute for your controllers:

[AzureADAuthorize]

AzureADAuthorize.cs:

 public class AzureADAuthorize : AuthorizeAttribute { public AzureADAuthorize() : base(AzureADPolicies.Name) { } } 

AzureADPolicies.cs:

 public static class AzureADPolicies { public static string Name => "AzureADAuthorizationRequired"; public static void Build(AuthorizationPolicyBuilder builder) { if (StaticRepo.Configuration.GetValue<bool>("EnableAuthorization") == true) { var section = StaticRepo.Configuration.GetSection($"AzureAd:AuthorizedAdGroups"); var groups = section.Get<string[]>(); builder.RequireClaim("groups", groups); } else if (StaticRepo.Configuration.GetValue<bool>("EnableAuthentication") == true) { builder.RequireAuthenticatedUser(); }else { builder .RequireAssertion(_ => true) .Build(); } } } 

Startup.cs:

 //Authentication & Authorization #region AUTHENTICATION / AUTHORICATION StaticRepo.Configuration = Configuration; services.AddAuthorization(options => { options.AddPolicy( AzureADPolicies.Name, AzureADPolicies.Build); }); services.AddAuthentication(AzureADDefaults.AuthenticationScheme) .AddAzureAD(options => Configuration.Bind("AzureAd", options)); #endregion 

Appsettings.json:

  "EnableAuditLogging": false, "EnableAuthentication": true, "EnableAuthorization": false, "AzureAd": { "Instance": "https://login.microsoftonline.com/", "Domain": "https://MyDomain.onmicrosoft.com/", "TenantId": "b6909603-e5a8-497d-8fdb-7f10240fdd10", "ClientId": "6d09a1bf-4678-4aee-b67c-2d6df68d5324", "CallbackPath": "/signin-oidc", //Your Azure AD Security Group Object IDs that users needs to be member of to gain access "AuthorizedAdGroups": [ "568bd325-283f-4909-9fcc-a493d19f98e8", "eee6d366-0f4d-4fca-9965-b2bc0770506d" ] } 

(These are random guides)

Now you can use conditional control if you want to have anonymous access, Azure authentication, authentication + group authorization. There are still some things in the Azure ad app manifest file that you need to customize, but I think that goes beyond that.

0
source

Source: https://habr.com/ru/post/1262605/


All Articles