Reputation: 229
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
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
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
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
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
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