Web API 的静态 api 密钥

Posted

技术标签:

【中文标题】Web API 的静态 api 密钥【英文标题】:static api key for Web 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,我想知道添加带有密钥的标头或参数是否会使其更安全或者是一种不好的做法,你怎么办有吗? 【参考方案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

【讨论】:

以上是关于Web API 的静态 api 密钥的主要内容,如果未能解决你的问题,请参考以下文章

如何在静态网站中安全存储API密钥

将 API 密钥放在哪里?清单中的资源、元数据还是静态变量? [复制]

Azure 静态 Web 应用 API 中的 TypeORM 迁移

如何在 android imageview 上显示静态谷歌地图?

Web APi Vs MVC 和在 ASP.net 核心 Web APi 中提供静态文件

来自静态类的 ASP.NET Core Web API 日志记录