Reputation: 3421
I have an attribute to check authentication in controller actions. My attribute like this :
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = true)]
public class AuthenticationRequiredAttribute : ActionFilterAttribute, IAuthenticationFilter
{
private readonly bool checkAuthentication;
public AuthenticationRequiredAttribute(bool checkAuthentication)
{
this.checkAuthentication = checkAuthentication;
}
public void OnAuthentication(AuthenticationContext filterContext)
{
if (checkAuthentication && !UserIdentity.IsAuthenticated)
filterContext.Result = new HttpUnauthorizedResult();
}
public void OnAuthenticationChallenge(AuthenticationChallengeContext filterContext)
{
if (filterContext.Result == null || filterContext.Result is HttpUnauthorizedResult)
{
filterContext.Result = new RedirectToRouteResult(
new System.Web.Routing.RouteValueDictionary{
{"controller", "Account"},
{"action", "Login"}
});
}
}
}
If checkAuthentication = false
no check authentication.
All actions in a controller should be check authentication except one action. I apply [AuthenticationRequired(true)]
on controller and [AuthenticationRequired(false)]
on specific action. but it not work and always check authentication.
When apply [AuthenticationRequired(true)]
on other actions and remove it from controller it work fine.
How I can force use method attribute in this case?
Upvotes: 1
Views: 2011
Reputation: 836
Modify your OnAuthentication
and add validation of AllowAnonymous
attribute.
bool skipAuthorization = filterContext.ActionDescriptor.IsDefined(typeof(AllowAnonymousAttribute), inherit: true)
|| filterContext.ActionDescriptor.ControllerDescriptor.IsDefined(typeof(AllowAnonymousAttribute), inherit: true);
if (skipAuthorization)
{
return;
}
After that just add AllowAnonymous
attribute to methods that should skip authentication\authorization.
Upvotes: 3