WebAPI 2中非常基本的承载令牌认证和授权

时间:2018-07-17 15:38:44

标签: c# asp.net-web-api2 bearer-token

我有一个Intranet站点,在我的组织内部本地托管。同一站点还通过各种Web服务公开了一些数据。它是使用ASP.NET MVC 5和WebAPI 2编写的,它是.NET 4.5,而不是Core。

目前,用户可以使用Windows身份验证登录网站,并且在通过身份验证后,便可以访问API。但是,我还需要允许使用令牌访问API,以便可以由自动化过程来查询它们,因此,我创建了一个页面,经过身份验证的用户可以访问该页面并请求令牌。

我打算将此令牌用作承载令牌,包括在对Web API的HTTP请求的标头中,以允许访问这些API。据我了解,无记名令牌在本质上代表了用户访问数据的权利,并且不需要任何其他信息(甚至用户名)。

但是,我一直在努力寻找一个完整的,端到端的教程来认证和授权请求。这个站点和Microsoft的aritcle上有一些问题,可以提供一些很好的指示,但是我觉得它们可能暗示着某些事情对于我的要求来说太复杂了。我不需要返回任何带有声明的身份或类似的身份,而且我完全不关心OAuth。

我使用的是Microsoft的Web API框架,因此可以合理地假设做提取和检查请求标头中的令牌之类的基本操作应该相当简单!

有人可以概述应用程序中需要放置的组件和过程,以使其能够从HTTP请求中提取Bearer令牌,使用我自己的代码检查其有效性,然后支持{{ 1}} Web API方法上的属性,如果令牌有效?

2 个答案:

答案 0 :(得分:3)

看起来我们有相同的需求,我也只需要快速进行承载令牌验证就不会使API完全开放。

我从此处复制了大部分内容,并对其进行了调整,以便它仅检查Bearer令牌https://docs.microsoft.com/en-us/aspnet/web-api/overview/security/authentication-filters

在WebApiConfig.cs中添加过滤器

public class WebApiConfig    
{    
    public static void Register(HttpConfiguration config)    
    {    
        // Add authentication    
        config.Filters.Add(new SimpleAuthenticationFilter()):  
        foo
    }  
}

SimpleAuthenticationFilter.cs

public class SimpleAuthenticationFilter : IAuthenticationFilter
{
    private readonly string _bearerToken = ConfigurationManager.AppSettings["simpleToken"];
    public bool AllowMultiple { get; }

    public async Task AuthenticateAsync(HttpAuthenticationContext context, CancellationToken cancellationToken)
    {
        // 1. Look for credentials in the request.
        var request = context.Request;
        var authorization = request.Headers.Authorization;

        // 2. If there are no credentials, do nothing.
        if (authorization == null)
        {
            context.ErrorResult = new AuthenticationFailureResult("Authorization header is 'null''", request);
            return;
        }

        // 3. If there are credentials but the filter does not recognize the 
        //    authentication scheme, do nothing.
        if (!authorization.Scheme.Equals("Bearer"))
        {
            context.ErrorResult = new AuthenticationFailureResult("Authentication type must be 'Bearer'", request);
            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("Bearer token is null or empty", request);
            return;
        }

        if (!authorization.Parameter.Equals(_bearerToken))
        {
            context.ErrorResult = new AuthenticationFailureResult("Bearer token invalid", request);
        }
    }

    public Task ChallengeAsync(HttpAuthenticationChallengeContext context, CancellationToken cancellationToken)
    {
        return Task.FromResult(0);
    }
}

AuthenticationFailureResponse.cs

  public class AuthenticationFailureResult : IHttpActionResult
  {
    public AuthenticationFailureResult(string reasonPhrase, HttpRequestMessage request)
    {
        ReasonPhrase = reasonPhrase;
        Request = request;
    }

    private string ReasonPhrase { get; }

    private HttpRequestMessage Request { get; }

    public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
    {
        return Task.FromResult(Execute());
    }

    private HttpResponseMessage Execute()
    {
        var response = new HttpResponseMessage(HttpStatusCode.Unauthorized)
        {
            RequestMessage = Request, ReasonPhrase = ReasonPhrase
        };
        return response;
    }
}

答案 1 :(得分:0)

扩大以上闵的答案:

string token = Request.Headers.Authorization.ToString().Split(' ')[1];