在MVC控制器中应用多个Action Filter属性以实现不同的身份验证方式

时间:2014-11-03 18:26:02

标签: c# asp.net-mvc authentication asp.net-web-api attributes

我正在尝试将多个AuthenticationFilter属性与我的Web API控制器一起使用,以便逐个调用它们,并在最终成功进行一次身份验证(相当于逻辑OR)时停止。

[TokenAuthentication]
[DbAuthentication]
public class FooController : ApiController
{
    // actions
}

这两个属性都来自公共基类。这样我就可以避免重复代码,如果需要,我可以快速添加一些新的身份验证。

public abstract class AuthenticationBase : ActionFilterAttribute, IAuthenticationFilter
{
    public Task AuthenticateAsync(HttpAuthenticationContext context, CancellationToken cancellationToken)
    {
        if (HttpContext.Current.User.Identity.IsAuthenticated) return Task.FromResult(0);

        var isValidRequest = VerifyRequest(context);
        if (!isValidRequest)
        {
            context.ErrorResult = new AuthenticationFailureResult(context.Request);
            return Task.FromResult(context.ErrorResult);
        }

        if (HttpContext.Current != null)
        {
            var identity = GetIdentity();
            var claims = GetClaims();
            identity.AddClaims(claims);

            HttpContext.Current.User = new ClaimsPrincipal(identity);
        }

        return Task.FromResult(0);
    }

    public Task ChallengeAsync(HttpAuthenticationChallengeContext context, CancellationToken cancellationToken)
    {
        return Task.FromResult(0);
    }
}

public class TokenAuthentication : AuthenticationBase
{
    protected override GenericIdentity GetIdentity()
    {
           // auth type dependent impl
    }

    protected override bool VerifyRequest(HttpAuthenticationContext context)
    {
           // auth type dependent impl
    }
}

问题是,它们是在逻辑AND的基础上进行评估的 - 意味着,如果第一次验证失败,则不会调用第二次验证。更准确地说,第二个属性总是直接跳转到ChallengeAsync方法,而不会调用AuthenticateAsync。我试图根据this question的答案解决问题,但由于我使用ApiController我无法覆盖InvokeAuthorizationFilters ...我有点困在这里需要关于如何解决这个问题的一些方向。我仍然是.NET MVC的新手,所以我甚至不确定这种方法是否正确。

0 个答案:

没有答案