【问题标题】:static api key for Web APIWeb API 的静态 api 密钥
【发布时间】:2016-09-12 14:55:01
【问题描述】:

我已经构建了一个 RESTful API(使用 ASP.NET Web API 2),它只打算从单个端点使用。这个端点是一个基本的前端站点,只包含 HTML/CSS/JS。由于种种原因,前端站点和 API 完全互为外部,前端站点在 API 的 CORS 配置中被列入白名单。

我现在正试图锁定 API,使其只能从这个特定端点访问,而不引入新的登录系统,因为此页面所在的上下文确保访问它的任何人都已经是受信任的用户(从技术上讲,它在登录系统之后,但使用 API 的页面几乎不知道此上下文)。

在高层次上,我想引入某种静态定义的 API 密钥,它将被硬编码到 API 和消费页面的 JavaScript 中,以帮助确保它是唯一的端点访问API。我们可以假设前端页面和 API 之间的所有通信都将通过安全的 SSL/TLS 连接。

我的问题:对于这种情况,我想使用静态定义的 API 密钥对来自特定页面的 API 请求进行身份验证,从易于实施的角度来看,我最好的选择是什么?我在 Web API 授权上找到的大多数文章都围绕用户登录系统展开,并且对于我的特定用例来说似乎过度设计了。当涉及到这个主题时,我认为自己是一个新手,所以我真的只是希望有人能指出我正确的方向。

谢谢!

【问题讨论】:

  • 我有一个类似的情况,我有一个基于 SSL 的 API,我想知道添加带有密钥的标头或参数是否会使其更安全或者是一种不好的做法,你怎么办有吗?

标签: c# asp.net ajax api restful-authentication


【解决方案1】:

在这种特定情况下,您似乎正在寻找全局过滤器。

身份验证过滤器是对 HTTP 请求进行身份验证的组件

您基本上会在 Authorization 标头中的每个请求中发送共享/静态 api 密钥,自定义过滤器将处理此并决定请求是否有效。

过滤器的基本实现:

public class ApiKeyAuthenticationAttribute : IAuthenticationFilter
{
    public bool AllowMultiple { get; set; }

    public async Task AuthenticateAsync(HttpAuthenticationContext context, CancellationToken cancellationToken)
    {
        HttpRequestMessage request = context.Request;

        // Get Auth header
        AuthenticationHeaderValue authorization = request.Headers.Authorization;

        // Validate the static token
        if (authorization?.Parameter == "123")
        {
            IPrincipal principal = new ClaimsPrincipal(new ClaimsIdentity(new List<Claim> { new Claim("CLAIMTYPE", "CLAIMVALUE") }));

            context.Principal = principal;
        }
        else
        {
            context.ErrorResult = new AuthenticationFailureResult(request);
        }
    }

    public Task ChallengeAsync(HttpAuthenticationChallengeContext context, CancellationToken cancellationToken)
    {
        var challenge = new AuthenticationHeaderValue("Basic");
        context.Result = new AddChallengeOnUnauthorizedResult(challenge, context.Result);

        return Task.FromResult(0);
    }
}

并为对您的 api 的所有调用启用它,请将其添加到您的 WebApiConfig:

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        // Some more config here
        config.Filters.Add(new IdentityBasicAuthenticationAttribute());
    }
}

AuthenticationFailureResultAddChallengeOnUnauthorizedResult 是 IHttpActionResult 的实现。为了全面起见,我将在此处添加它们。

身份验证失败结果

class AuthenticationFailureResult : IHttpActionResult
{
    private HttpRequestMessage _request;

    public AuthenticationFailureResult(HttpRequestMessage request)
    {
        _request = request;
    }

    public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
    {
        HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.Unauthorized);
        response.RequestMessage = _request;
        response.Content = new StringContent("ACCESS DENIED MESSAGE");

        return Task.FromResult(response);
    }
}

AddChallengeOnUnauthorizedResult

class AddChallengeOnUnauthorizedResult : IHttpActionResult
{
    public AddChallengeOnUnauthorizedResult(AuthenticationHeaderValue challenge, IHttpActionResult innerResult)
    {
        Challenge = challenge;
        InnerResult = innerResult;
    }

    public AuthenticationHeaderValue Challenge { get; private set; }

    public IHttpActionResult InnerResult { get; private set; }

    public async Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
    {
        HttpResponseMessage response = await InnerResult.ExecuteAsync(cancellationToken);

        if (response.StatusCode == HttpStatusCode.Unauthorized)
        {
            // Only add one challenge per authentication scheme.
            if (!response.Headers.WwwAuthenticate.Any((h) => h.Scheme == Challenge.Scheme))
            {
                response.Headers.WwwAuthenticate.Add(Challenge);
            }
        }

        return response;
    }
}

此代码来自或衍生自这篇文章Authentication Filters in ASP.NET Web API 2和这篇文章Authentication Filters in ASP.NET Web API 2

【讨论】:

    猜你喜欢
    • 2012-08-03
    • 1970-01-01
    • 2018-01-29
    • 1970-01-01
    • 2019-04-30
    • 2012-12-16
    • 1970-01-01
    • 2019-12-19
    • 1970-01-01
    相关资源
    最近更新 更多