moozywu
moozywu

Reputation: 229

Check whether the allow anonymous is on or not in ASP.NET Core

I need a way to check if "allow anonymous" is on/off in the controller action. Whether it comes from controller attribute, action attribute

[AllowAnonymous]

or it is set as filter in the MvcOptions

opts.Filters.Add(new AllowAnonymousFilter());

Is it possible?

Upvotes: 16

Views: 15367

Answers (5)

BigJoeNH
BigJoeNH

Reputation: 401

If you need to check if the [AllowAnonymous] attribute is used on a WebAPI2 controller action, when using an ActionFilterAttribute this should work

public class SomeCheckFilter : System.Web.Http.Filters.ActionFilterAttribute
 {
   public override void OnActionExecuting(HttpActionContext actionContext)
    {
      bool hasAllowAnonymous = actionContext.ActionDescriptor.GetCustomAttributes(typeof(AllowAnonymousAttribute)).Any();
      if (hasAllowAnonymous == false)                                             
       {
        // if NOT Anonymous, do the Filtercheck  
        ...    
       }
    }
 } 

Upvotes: 0

mohammadAli
mohammadAli

Reputation: 445

For checking, whether a controller and action has AllowAnonymous attribute, then in your custom authorization filter you can do this as follows:

For method level allow anonymous attribute:

bool hasAllowAnonymous = = filterContext.ActionDescriptor.EndpointMetadata
                             .Any(em => em.GetType() == typeof(AllowAnonymousAttribute));

For controller level allow anonymous attribute:

bool hasAllowAnonymous = = filterContext.ActionDescriptor.ControllerDescriptor.EndpointMetadata
                             .Any(em => em.GetType() == typeof(AllowAnonymousAttribute));

And then

if (hasAllowAnonymous) return;

Upvotes: 2

David Sopko
David Sopko

Reputation: 5623

public class MyController : Controller
{
    protected override void OnAuthorization(AuthorizationContext filterContext)
    {
        var anonActionAttributes = filterContext.ActionDescriptor
            .GetCustomAttributes(typeof(System.Web.Mvc.AllowAnonymousAttribute), true);

        var anonControllerAttributes = filterContext.ActionDescriptor.ControllerDescriptor
            .GetCustomAttributes(typeof(System.Web.Mvc.AllowAnonymousAttribute), true);

        if (anonActionAttributes.Length > 0 || anonControllerAttributes.Length > 0)            
            IsAllowAnonymous = true;

        base.OnAuthorization(filterContext);
    }

    bool IsAllowAnonymous { get; set; } = false;    
}

If you found this answer helpful, kindly upvote it.

Upvotes: 0

TanvirArjel
TanvirArjel

Reputation: 32069

It seems you need to check whether a controller and action does contain AllowAnonymousAttribute from your custom authentication filter during a request. So you can do this as follows:

public class CustomAuthorizationFilter : IAsyncAuthorizationFilter
{
    public async Task OnAuthorizationAsync(AuthorizationFilterContext filterContext)
    {
        if (filterContext == null)
        {
            throw new ArgumentNullException(nameof(filterContext));
        }

        bool hasAllowAnonymous = filterContext.ActionDescriptor.EndpointMetadata
                                 .Any(em => em.GetType() == typeof(AllowAnonymousAttribute)); //< -- Here it is

        if (hasAllowAnonymous) return;

        // Do your authorization check here
    }
}

Upvotes: 36

phuzi
phuzi

Reputation: 13060

Given the extra info in your comment. This appears to work the same way you should do a password reset.

For a password reset you include a one-time password reset token in the request (along with the password/verified password etc.) I would explicitly decorate the action with [AllowAnonymous] and validate the token in the before updating any details and cancelling the token.

In your case, I would do the same thing - explicitly decorate the action with [AllowAnonymous] and validate the one-time token. Your action shouldn't care whether the AllowAnonymous filter has been applied to the Action via the attribute or options.

UPDATE Been thinking a bit more and there's an easy way to disable this based on the build configuration. Wrap the attribute in an #if preprocessor directive and create a build configuration that defines a conditional compliation symbol. See this answer for details

#if DISABLE_ALLOW_ANONYOMOUS
    [AllowAnonymous]
#endif
    public IActionResult GetPicture(string token){
        ...

You can then build a test specific version where AllowAnonymous is disabled.

You could also do the same with MvcOptions:

#if DISABLE_ALLOW_ANONYOMOUS
    opts.Filters.Add(new AllowAnonymousFilter());
#endif

Upvotes: 0

Related Questions