我一直在查看Web Api2中的基本身份验证,似乎找不到我对某些事情感到困惑的解释。
我在Visual Studio 2017中创建了一个具有单独身份验证的Web api应用程序项目。
我有默认代码
public class ValuesController : ApiController
{
public IEnumerable<string> Get()
{
return new string[] { "value1", "value2" };
}
public string Get(int id)
{
return "value";
}
}
我通过邮递员、浏览器等称这些行为都很好。
如果我将 [Authorize] 属性添加到其中一个方法中,我会按预期收到 401 未经授权的响应。
目前为止,一切都好。
然后,我通过创建从 AuthorizationFilterAttribute 派生的类来添加基本身份验证
public class BasicAuthenticationAttribute : AuthorizationFilterAttribute
{
public override void OnAuthorization(HttpActionContext actionContext)
{
var authHeader = actionContext.Request.Headers.Authorization;
if (authHeader != null)
{
var authenticationToken = actionContext.Request.Headers.Authorization.Parameter;
var decodedAuthenticationToken = Encoding.UTF8.GetString(Convert.FromBase64String(authenticationToken));
var usernamePasswordArray = decodedAuthenticationToken.Split(':');
var userName = usernamePasswordArray[0];
var password = usernamePasswordArray[1];
var isValid = userName == "ade" && password == "password";
if (isValid)
{
var principal = new GenericPrincipal(new GenericIdentity(userName), null);
HttpContext.Current.User = principal;
return;
}
}
}
HandleUnathorized(actionContext);
}
private static void HandleUnathorized(HttpActionContext actionContext)
{
actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.Unauthorized);
actionContext.Response.Headers.Add("WWW-Authenticate", "Basic Scheme='Data' location = 'http://localhost:");
}
我在 WebApiConfig 中注册过滤器.cs
config.Filters.Add(new BasicAuthenticationAttribute());
我使用邮递员调用标有[授权]的操作并使用标题发送授权:基本YWRlOnBhc3N3b3Jk
请求已获得授权,我收到了操作响应。都很好。
现在,我调用未标记为 [授权] 的操作,而没有来自邮递员的授权标头,希望得到响应,但调用 OnAuthorization 并显然返回 HandleUnathorized(actionContext(;我只希望调用 OnAuthorization 方法,其中操作标记为 [授权]
所以现在我在想 [授权] 属性的意义何在,因为无论调用 OnAuthorization 如何,那么标记操作 [授权] 属性的意义何在?
其次,我在类中添加了以下方法
private static bool SkipAuthorization(HttpActionContext actionContext)
{
Contract.Assert(actionContext != null);
return actionContext.ActionDescriptor.GetCustomAttributes<AllowAnonymousAttribute>().Any()
|| actionContext.ControllerContext.ControllerDescriptor.GetCustomAttributes<AllowAnonymousAttribute>().Any();
}
我在OnAuthorization开始时调用此方法
if (SkipAuthorization(actionContext)) return;
如果我用[允许匿名]标记我的操作,它可以工作。
如果控制器上没有 [授权] 属性或特定操作,那么肯定也应该跳过 OnAuthorization?
我只是看不出使用 [授权] 的意义,我在这里显然遗漏了一些东西,我做错了什么还是我需要用 [AllowAnonymous] 标记操作以排除它们。
如果你使用的是 [Authorize] 属性和 windows 身份验证,那么授权将自动完成,你不需要做任何特殊配置,但任何特殊情况如果你需要覆盖[Authorize]类,那么你的类就像下面这样,
-
而不是继承AuthorizationFilterAttribute,你可以 继承授权属性
public class BasicAuthenticationAttribute : AuthorizeAttribute { //your override methods }
-
不要使用[Authorize]属性,而是使用派生类名。在您的情况下,请使用[BasicAuthenticationAttribute],而不是[Authorize]
谢谢弗兰,你让我走上了正确的道路。
我注释掉了以下行
config.Filters.Add(new BasicAuthenticationAttribute());
我在控制器中使用以下属性
public class ValuesController : ApiController
{
public IEnumerable<string> Get()
{
return new string[] { "value1", "value2" };
}
[Authorize]
[BasicAuthentication]
public string Get(int id)
{
return "value";
}
}
如果我调用操作get((,我得到一个响应,没有调用OnAuthorisation。 如果我调用get(int id(,我会得到401未经授权的,并且没有调用OnAuthoration。
我从 get(int id( 操作中删除了 [授权]
[BasicAuthentication]
public string Get(int id)
{
return "value";
}
这一切都奏效了,按预期调用了授权。