WEB API - 在控制器或操作级别授权(无身份验证)
WEB API - Authorize at controller or action level (no authentication)
我有一个没有身份验证的现有 API。这是一个 public Web API,多个客户端通过发出简单的请求来使用它。
现在,需要授权访问某个方法
有什么方法可以做到这一点,为已经使用此 Web API 的客户端保留其余的控制器和各自的方法 "open"?
如何确定请求是否有权访问此 "protected" 方法?
您可以在特定的 API 方法以及控制器级别使用 [Authorize]
属性。如果您将 [Authorize]
属性放在控制器级别,那么您可以将 [AllowAnonymous]
属性用于那些您希望无需身份验证即可访问的 API 方法。
您需要做的是向您想要保护的方法添加一个 [Authorize]
属性,可选择使用接受一个或多个调用用户必须在其中的角色名称的重载。
那么您必须实现的是一种确保将调用者的身份验证数据转换为 Principal 对象的方法。设置 Principal 通常不是您自己做的事情,而是让框架为您做。
如果您确实想提供自己的界面,您可以使用实现 System.Web.Http.Filters.IAuthenticationFilter
界面的身份验证过滤器。
那么你会得到的是:
[MyAuthentication]
[Authorize]
public SomeClass MyProtectedMethod() {
return new SomeClass();
}
然后实现MyAuthentication
属性。下面是一个示例,重要的是您使用传入请求的上下文并最终使用新的 Principal
设置 context.Principal
属性
public class MyAuthentication : ActionFilterAttribute, System.Web.Http.Filters.IAuthenticationFilter {
public async Task AuthenticateAsync(HttpAuthenticationContext context, CancellationToken cancellationToken)
{
// 1. Look for credentials in the request.
HttpRequestMessage request = context.Request;
AuthenticationHeaderValue authorization = request.Headers.Authorization;
// 2. If there are no credentials, do nothing.
if (authorization == null)
{
return;
}
// 3. If there are credentials but the filter does not recognize the
// authentication scheme, do nothing.
if (authorization.Scheme != "Basic")
{
return;
}
// 4. If there are credentials that the filter understands, try to validate them.
// 5. If the credentials are bad, set the error result.
if (String.IsNullOrEmpty(authorization.Parameter))
{
context.ErrorResult = new AuthenticationFailureResult("Missing credentials", request);
return;
}
Tuple<string, string> userNameAndPasword = ExtractUserNameAndPassword(authorization.Parameter);
if (userNameAndPasword == null)
{
context.ErrorResult = new AuthenticationFailureResult("Invalid credentials", request);
}
string userName = userNameAndPasword.Item1;
string password = userNameAndPasword.Item2;
IPrincipal principal = await AuthenticateAsync(userName, password, cancellationToken);
if (principal == null)
{
context.ErrorResult = new AuthenticationFailureResult("Invalid username or password", request);
}
// 6. If the credentials are valid, set principal.
else
{
context.Principal = principal;
}
}
... other interface methods here
}
我希望这可以帮助您走上正轨。有关详细信息,请查看此 post:
http://www.asp.net/web-api/overview/security/authentication-filters
默认情况下,应用程序全局禁用授权。您可以通过添加操作过滤器 [Authorize].
强制您的控制器只允许授权请求
[Authorize] // This will enforce all methods inside should be authorized
public class AuthorizeController : ApiController
{
//this method will only be called if user is authorized
public IHttpActionResult GetList()
{
return Ok();
}
}
您也可以强制只授权某些方法:
public class AuthorizeController : ApiController
{
[Authorize] //this method will only be called if user is authorized
public IHttpActionResult GetList()
{
return Ok();
}
// This method can still be called even if user is not authorized
public IHttpActionResult GetListUnauthorized()
{
return Ok();
}
}
或者只是在需要授权的控制器中禁用某些方法的授权:
[Authorize]
public class AuthorizeController : ApiController
{
//this method will only be called if user is authorized
public IHttpActionResult GetList()
{
return Ok();
}
[AllowAnonymous]// This method can be called even if user is not authorized due the AllowAnonymous attribute
public IHttpActionResult GetListUnauthorized()
{
return Ok();
}
}
您还可以使用以下方式设置允许谁访问您的方法:
[Authorize(Users="Joey,Billy")]
或按规则使用:
[Authorize(Roles="Administrator,Manager")]
或者甚至构建一个更复杂的授权属性,就像这个答案(基于声明):Authorization Attribute by Claims
我们在方法上使用 [AllowAnonymous] 解决了这个问题,我们不想对谁进行身份验证但已授权,覆盖了授权。
执行流程将进入方法级别,然后进入控制器级别。因此,如果您提到 "AllowAnonymous" 将在没有授权检查的情况下执行。
我有一个没有身份验证的现有 API。这是一个 public Web API,多个客户端通过发出简单的请求来使用它。
现在,需要授权访问某个方法
有什么方法可以做到这一点,为已经使用此 Web API 的客户端保留其余的控制器和各自的方法 "open"?
如何确定请求是否有权访问此 "protected" 方法?
您可以在特定的 API 方法以及控制器级别使用 [Authorize]
属性。如果您将 [Authorize]
属性放在控制器级别,那么您可以将 [AllowAnonymous]
属性用于那些您希望无需身份验证即可访问的 API 方法。
您需要做的是向您想要保护的方法添加一个 [Authorize]
属性,可选择使用接受一个或多个调用用户必须在其中的角色名称的重载。
那么您必须实现的是一种确保将调用者的身份验证数据转换为 Principal 对象的方法。设置 Principal 通常不是您自己做的事情,而是让框架为您做。
如果您确实想提供自己的界面,您可以使用实现 System.Web.Http.Filters.IAuthenticationFilter
界面的身份验证过滤器。
那么你会得到的是:
[MyAuthentication]
[Authorize]
public SomeClass MyProtectedMethod() {
return new SomeClass();
}
然后实现MyAuthentication
属性。下面是一个示例,重要的是您使用传入请求的上下文并最终使用新的 Principal
context.Principal
属性
public class MyAuthentication : ActionFilterAttribute, System.Web.Http.Filters.IAuthenticationFilter {
public async Task AuthenticateAsync(HttpAuthenticationContext context, CancellationToken cancellationToken)
{
// 1. Look for credentials in the request.
HttpRequestMessage request = context.Request;
AuthenticationHeaderValue authorization = request.Headers.Authorization;
// 2. If there are no credentials, do nothing.
if (authorization == null)
{
return;
}
// 3. If there are credentials but the filter does not recognize the
// authentication scheme, do nothing.
if (authorization.Scheme != "Basic")
{
return;
}
// 4. If there are credentials that the filter understands, try to validate them.
// 5. If the credentials are bad, set the error result.
if (String.IsNullOrEmpty(authorization.Parameter))
{
context.ErrorResult = new AuthenticationFailureResult("Missing credentials", request);
return;
}
Tuple<string, string> userNameAndPasword = ExtractUserNameAndPassword(authorization.Parameter);
if (userNameAndPasword == null)
{
context.ErrorResult = new AuthenticationFailureResult("Invalid credentials", request);
}
string userName = userNameAndPasword.Item1;
string password = userNameAndPasword.Item2;
IPrincipal principal = await AuthenticateAsync(userName, password, cancellationToken);
if (principal == null)
{
context.ErrorResult = new AuthenticationFailureResult("Invalid username or password", request);
}
// 6. If the credentials are valid, set principal.
else
{
context.Principal = principal;
}
}
... other interface methods here
}
我希望这可以帮助您走上正轨。有关详细信息,请查看此 post: http://www.asp.net/web-api/overview/security/authentication-filters
默认情况下,应用程序全局禁用授权。您可以通过添加操作过滤器 [Authorize].
强制您的控制器只允许授权请求[Authorize] // This will enforce all methods inside should be authorized
public class AuthorizeController : ApiController
{
//this method will only be called if user is authorized
public IHttpActionResult GetList()
{
return Ok();
}
}
您也可以强制只授权某些方法:
public class AuthorizeController : ApiController
{
[Authorize] //this method will only be called if user is authorized
public IHttpActionResult GetList()
{
return Ok();
}
// This method can still be called even if user is not authorized
public IHttpActionResult GetListUnauthorized()
{
return Ok();
}
}
或者只是在需要授权的控制器中禁用某些方法的授权:
[Authorize]
public class AuthorizeController : ApiController
{
//this method will only be called if user is authorized
public IHttpActionResult GetList()
{
return Ok();
}
[AllowAnonymous]// This method can be called even if user is not authorized due the AllowAnonymous attribute
public IHttpActionResult GetListUnauthorized()
{
return Ok();
}
}
您还可以使用以下方式设置允许谁访问您的方法:
[Authorize(Users="Joey,Billy")]
或按规则使用:
[Authorize(Roles="Administrator,Manager")]
或者甚至构建一个更复杂的授权属性,就像这个答案(基于声明):Authorization Attribute by Claims
我们在方法上使用 [AllowAnonymous] 解决了这个问题,我们不想对谁进行身份验证但已授权,覆盖了授权。
执行流程将进入方法级别,然后进入控制器级别。因此,如果您提到 "AllowAnonymous" 将在没有授权检查的情况下执行。