静态API密钥用于Web API

4
我构建了一个RESTful API(使用ASP.NET Web API 2),该API只能从单个终点进行访问。这个终点是一个基本的前端站点,只包含HTML/CSS/JS。由于各种原因,前端站点和API完全独立于彼此,前端站点被列入了API的CORS配置白名单。
现在我想锁定API,使其只能从特定的终点进行访问,而不引入新的登录系统,因为此页面所处的上下文确保任何访问它的人都是受信任的用户(从技术上讲,它在登录系统后面,但消费API的页面几乎没有关于此上下文的知识)。
总的来说,我想引入一种静态定义的API密钥,该密钥将硬编码到API和消费页面的JavaScript中,以确保它是唯一访问API的终点。我们可以假设前端页面和API之间的所有通信都是通过安全的SSL/TLS连接完成的。
我的问题是:对于这种情况,我想从易于实现的角度来验证来自特定页面的API请求,什么是我最好的选择?我找到的大多数Web API授权文章都是围绕用户登录系统展开的,并且对于我的特定用例似乎过于复杂。在这方面我算是一个新手,所以我真的希望有人能指点我正确的方向。谢谢!

我有一个类似的情况,我有一个通过SSL的API,我想知道是否添加一个带有密钥的头或参数会使其更安全,还是这是一种不好的做法?你做了什么? - MikeOx
1个回答

4

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

身份验证过滤器是一种认证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接口的实现。为了全面起见,在此我将它们添加在此处。

AuthenticationFailureResult(身份验证失败结果)

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;
    }
}

这段代码来自于或基于此文章 ASP.NET Web API 2中的身份验证过滤器 和此文章 ASP.NET Web API 2中的身份验证过滤器


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接