Web API 2 基本身份验证和允许操作未标记为 [授权]



我一直在查看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]类,那么你的类就像下面这样,

  1. 而不是继承AuthorizationFilterAttribute,你可以 继承授权属性

    public class BasicAuthenticationAttribute : AuthorizeAttribute
    {
    //your override methods
    }
    
  2. 不要使用[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";
}

这一切都奏效了,按预期调用了授权。

最新更新