如何在服务器上验证Web API访问令牌?

时间:2016-05-29 07:23:47

标签: asp.net-mvc asp.net-web-api2 access-token

生成WebAPI访问令牌后,WebAPI如何为下一个请求验证该令牌?我想知道我是否可以使用[Authorize]属性,它必须将客户端发送的令牌与服务器端的令牌进行比较,如果存储在某处。它只是检查令牌是否存在而不是它的值?

3 个答案:

答案 0 :(得分:14)

不记名令牌

首先,颁发授权令牌的身份提供者或令牌提供者需要具有与用于加密/解密的Web Api应用程序相同的机器密钥设置:

  

<的machineKey   decryptionKey = “B7EFF1C5839A624ED0268917EDE82F408D2ECBFAC817”   验证= “SHA1”   的validationKey = “C2B8DF31AB9624D8066DFDA1A479542825F3B48865C4E47AF6A026F22D853DEC2B3248DF268599BF89EF78B9E86CA05AC73577E0D5A14C45E0267588850B”   /> < /system.web>

因为引擎盖Bearertoken使用MachineKey加密。 换句话说,如果您没有相同的设置,您的web api将无法解密令牌(验证它)。 这是通过以下方式自动完成的:

  

Microsoft.Owin.Security.OAuth.dll

使用中间件。

如果您希望使用以下用户名或角色进行简单授权,则可以在Web api控制器/操作上使用授权属性

[Authorize(Roles="Administrators,Managers",Users ="Mike,Laura")] 

如果您需要自定义授权,则必须实现自定义授权属性,该属性将处理您的Web API中的自定义授权。如果不允许用户通过,则返回401 UnAuthorized Response:

actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.Unauthorized);
actionContext.Response.Headers.Add("WWW-Authenticate","Bearer location='http://localhost:8323/account/login'");

例如:

[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class)]
public class CustomAuthorizeAttribute : System.Web.Http.Filters.AuthorizationFilterAttribute
{
    public RulesExampleEnum[] Rules { get; set; }
    public string Id { get; set; }
    .....
// Summary:
//     Calls when a process requests authorization.
//
// Parameters:
//   actionContext:
//     The action context, which encapsulates information for using System.Web.Http.Filters.AuthorizationFilterAttribute.
public virtual void OnAuthorization(HttpActionContext actionContext);
public virtual Task OnAuthorizationAsync(HttpActionContext actionContext, CancellationToken cancellationToken);

并在webApiConfig.cs中注册

config.Filters.Add(new CustomAuthorizeAttribute());

并将其应用于Web Api控制器或操作:

[CustomAuthorize(Id = "AnyId", Rules = new RulesExampleEnum[] { RulesExampleEnum.Rule1, RulesExampleEnum.Rule3 })]
public IEnumerable<object> Get()
{...

答案 1 :(得分:4)

生成访问令牌后,客户端必须在每个请求的Header中包含访问令牌。

客户端可以在Authorization HTTP标头内设置访问令牌。

在服务器端,你应该创建一个类来处理Authorization,这是一个来自System.Web.Http.AuthorizeAttribute的派生类,如下所示:

public class AuthorizationHandlerAttribute : AuthorizeAttribute
{
    string AccessTokenFromRequest = "";
    if (actionContext.Request.Headers.Authorization != null)
    {
        // get the access token
        AccessTokenFromRequest = actionContext.Request.Headers.Authorization.Parameter;
    }

    string AccessTokenStored = ""; 
    // write some code to get stored access token, probably from database 
    // then assign the value to a variable for later use

    // compare access token
    if (AccessTokenFromRequest != AccessTokenStored)
    {
        // if the token is not valid then return 401 Http Stasus
        // or simply call base method 
        base.HandleUnauthorizedRequest(actionContext);
    }
}

然后,您使用新创建的类并将其附加到您希望防止未经授权访问的controlleraction上。

public class UsersController : ApiController
{
    [AuthorizationHandler]
    public User Get(int id)
    {
        // only request with valid access token will reach this 
    }
}

答案 2 :(得分:3)

密钥在请求的标头中从客户端传输到服务器,并且在每次使用[Authorize]属性的请求时,在服务器上验证内容。

您可以使用Telerik的Fiddler(免费)等工具查看正在传输的数据,但不能查看内容(自加密后)。在使用MVC / WebAPI时检查原始Web流量是非常宝贵的,所以我强烈推荐它。这是Fiddler的链接,虽然也存在其他类似的工具。

http://www.telerik.com/fiddler

要回答问题的第二部分,服务器会在允许请求继续进行授权之前绝对检查密钥的内容。