我正在尝试将多个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的新手,所以我甚至不确定这种方法是否正确。