0

I have a .Net Core 3.0 Web API that is configured with as such:

services.AddAuthentication(x =>
  {
    x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
    x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
  })
  .AddJwtBearer(x =>
  {
    ...
  });

services.AddAuthorizationCore(options =>
  {
    options.FallbackPolicy = new AuthorizationPolicyBuilder()
      .RequireAuthenticatedUser()
      .Build();
  });

And I enable it in the controller like:

[Authorize(Roles = "Admin,Technician")]
public IActionResult CreateFoo([FromBody] Foo foo)

Some api endpoints are also disabled using the [AllowAnonymous].

This product is supporting multiple environments, and one endpoint needs to be either anonymous or authorized dependent on the runtime variable; currently using custom "ASPNETCORE_ENVIRONMENT" options.

I have seen this comment from .net security person, but if I implement a custom policy, it disallows anonymous access.

What is the easiest way to allow anonymous access if the application is running in a certain environment?

Mike
  • 417
  • 3
  • 12

2 Answers2

0

AuthorizeAttribute is just an implementation of AuthorizationFilterAttribute . You can create your own implementation that will bypass authentication for certain environments:

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = false)]
public class EnvironmentSpecificAutorizeAttribute : AuthorizeAttribute
{
    public string AllowAnonymousEnvironment { get; set; }

    protected override void HandleUnauthorizedRequest(HttpActionContext actionContext)
    {
        // if currentEnv == AllowAnonymousEnvironment 
        //    return 
        // else
        //    base.HandleUnauthorizedRequest(actionContext);
    }
    public override void OnAuthorization(HttpActionContext actionContext)
    {
        // same logic as above
        base.OnAuthorization(actionContext);
    }

    public override Task OnAuthorizationAsync(HttpActionContext actionContext, CancellationToken cancellationToken)
    {
        // same logic as above
        return base.OnAuthorizationAsync(actionContext, cancellationToken);
    }
}

You may find other suggestions in this thread

fenixil
  • 1,984
  • 4
  • 13
  • This doesn't apply to AspNet Core, but thanks for the link. – Mike Oct 11 '19 at 03:52
  • Authorise attribute sources are from webapi, second link is to core docs, why this does not apply? You may need to override different methods in core but the approach is applicable. Feel free to propose an edit if so. – fenixil Oct 11 '19 at 03:59
0

If I understand your question then you could create a custom attribute and always grant the user access when the application is running in a certain env?

   public class CustomEnvRequirement : AuthorizationHandler<CustomEnvRequirement>, IAuthorizationRequirement
    {
        protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, CustomEnvRequirement requirement)
        {
            string currentEnv = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");

            // Allow Anonymous when the current env is development.
            if (currentEnv.ToLowerInvariant().Equals("development"))
            {
                context.Succeed(requirement);
            }
            else if (currentEnv.ToLowerInvariant().Equals("production"))
            {
                // TODO: add more authorization logic.

            }
            return Task.CompletedTask;
        }
    }

And here's the Custom attribute to be added

 [Authorize(Policy = "CustomEnv")]

        public IActionResult Index()
        {
            return this.View();
        }

Also, make sure to configure it in the startup.cs

  services.AddAuthorization(options =>
            {
                options.AddPolicy("CustomEnv",
                    policy => policy.Requirements.Add(new CustomEnvRequirement()));
            });
Jee Mok
  • 4,537
  • 7
  • 35
  • 66
Moe Jallaq
  • 94
  • 5
  • I have already tried that but athentication would still be required. – Mike Oct 10 '19 at 00:17
  • This is essentially the answer, but to make it work fully, a new AuthorizationPolicyBuilder needs to be created for the DefaultPolicy without RequireAuthenticatedUser. – Mike Oct 11 '19 at 03:55