Azure Functions 的身份验证

Posted

技术标签:

【中文标题】Azure Functions 的身份验证【英文标题】:Authentication for Azure Functions 【发布时间】:2018-03-27 05:28:19 【问题描述】:

在过去的 24 小时里,我一直在阅读有关如何创建 Azure Functions 的所有内容,并成功地将 MVC WebApi 转换为具有多个功能的新 Function App。我的问题是我没有找到任何关于如何使用它们进行最基本的身份验证的明确文档或教程。

我的情况非常简单。在我的 AAD 中预配用户,然后授予这些用户对特定功能的访问权限。网站上的用户将单击 UI 元素,这些元素又会触发调用我的 Azure Functions 的 javascript。在函数中,我需要能够以某种方式验证它们的身份,因为我会将其传递给与 SQL 实例交互的其他函数。

有人可以指出我如何实现这一目标的文档、文章、示例等内容吗?

作为记录,我在门户中找到了我的 Function App 的“身份验证”配置,并选择了 AAD 作为我的身份验证提供程序。我已将我的 Function App 添加到其中并配置了一些用户。然后我编写了以下测试函数:

[FunctionName("GetThings")]
public static HttpResponseMessage Run([HttpTrigger(AuthorizationLevel.User, "GET", Route = null)]HttpRequestMessage req, TraceWriter log)

    log.Info("Getting all the things");
    var identity = ClaimsPrincipal.Current.Identity;

    return identity.IsAuthenticated ?
        req.CreateResponse(HttpStatusCode.Unauthorized, "Not authenticated!") :
        req.CreateResponse(HttpStatusCode.OK, $"Hi identity.Name!");

目前,当尝试直接访问端点时,我会被重定向到登录页面......所以我猜这部分正在工作。不过,我如何生成/检索用户令牌、将它们发送到函数的请求或在服务器上处理它们对我来说并不清楚。

帮助?

【问题讨论】:

【参考方案1】:

用户通过 Azure AD 进行身份验证后,您将看到一个 AppServiceAuthSessoin cookie。这是一个不透明的 cookie,但您可以通过调用将其交换为可读的 id 令牌

https://yourFunctionApp.azurewebsites.net/.auth/me

并将不透明的 cookie 作为 Cookie 标头传递。而且,你拿回来的id_token也可以作为Bearer的token使用。

实际上它只是在我看来是正确的,我还没有真正将它作为 Bearer 进行测试,所以要小心一点。

该机制称为Easy Auth,Google 更容易找到这个名称。

更多关于令牌存储的信息——https://cgillum.tech/2016/03/07/app-service-token-store/

...这表示您可以通过读取来自用户浏览器的 HTTP 标头来获取声明:

访问令牌

在您的后端代码中,访问这些令牌就像读取 HTTP 请求标头一样简单。标头命名为X-MS-TOKEN-provider-type。下面列出了可能的令牌头名称:

Azure Active Directory 令牌请求标头:

X-MS-TOKEN-AAD-ID-TOKEN
X-MS-TOKEN-AAD-ACCESS-TOKEN
X-MS-TOKEN-AAD-EXPIRES-ON
X-MS-TOKEN-AAD-REFRESH-TOKEN

其实我现在才发现,所以谢谢你的问题!

更新:

我的预感是正确的,id_token 也可以作为 Bearer:

$ curl -isk https://funcApp.azurewebsites.net/api/someFunc \
       -H "Authorization: Bearer eyJ0eXAiOi....oEU-Q"

HTTP/1.1 200 OK
Cache-Control: no-cache
Server: Microsoft-IIS/8.0
...

两种读取声明的方式(读取标头与使用用户的 Cookie 从后端调用 /.auth/me)之间的主要区别在于您获得的详细信息量。后者还有更多。

这是您从 Easy Auth 为 Twitter 身份验证用户获得的一组 标头


   "cookie": "AppServiceAuthSession=Lx43...xHDTA==",
   ...
   "x-ms-client-principal-name": "evilSnobu",
   "x-ms-client-principal-id": "35....",
   "x-ms-client-principal-idp": "twitter",
   "x-ms-token-twitter-access-token": "35...Dj",
   "x-ms-token-twitter-access-token-secret": "OK3...Jx",

以及致电/.auth/me 获得的索赔:


   "access_token": "35...FDj",
   "access_token_secret": "OK3...sJx",
   "provider_name": "twitter",
   "user_claims": [
      
         "typ": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier",
         "val": "352660979"
      ,
      
         "typ": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn",
         "val": "evilSnobu"
      ,
      
         "typ": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name",
         "val": "Safarihat Hacker"
      ,
      
         "typ": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/webpage",
         "val": "..."
      ,
      
         "typ": "urn:twitter:description",
         "val": "GENIUS. HAVE BRAIN. WILL TRAVEL."
      ,
      
         "typ": "urn:twitter:location",
         "val": ""
      ,
      
         "typ": "urn:twitter:time_zone",
         "val": "London"
      ,
      
         "typ": "urn:twitter:lang",
         "val": "en"
      ,
      
         "typ": "urn:twitter:verified",
         "val": "False"
      ,
      
         "typ": "urn:twitter:profile_image_url_https",
         "val": "https://pbs.twimg.com/profile_images/867473646876545024/1elebfK1_normal.jpg"
      
   ],
   "user_id": "evilSnobu"

【讨论】:

【参考方案2】:

我为 Azure Functions v2 创建了一个小扩展, 与不记名令牌一起使用时可能会对您有所帮助。

例如,要使用 Azure B2C,当您希望允许对应用程序的匿名请求时。

因此,您可以在 Azure 函数中获得您的 ClaimsPrincipal 权利,而无需使用任何样板。

[FunctionName("Example")]
public async Task<IActionResult> Run(
    [HttpTrigger(AuthorizationLevel.Function, "get", Route = null)] HttpRequest req,
    [FunctionToken] FunctionTokenResult token,
    ILogger log)

    log.LogInformation("C# HTTP trigger function processed a request.");
    return (ActionResult) new OkObjectResult($"Hello, token");

代码发布到Github

【讨论】:

【参考方案3】:

Azure 函数当前不支持 AuthorizationLevel.User,请参阅 here

截至 2017 年 12 月,这尚未完全实施。

【讨论】:

以上是关于Azure Functions 的身份验证的主要内容,如果未能解决你的问题,请参考以下文章

身份验证如何在 Azure Functions 上工作

Azure Functions - 配置客户端证书身份验证

如何使用应用服务对 Azure Functions 应用进行身份验证/授权?

Azure Functions App with APIM 使用托管标识 - 身份验证和授权

使用不记名令牌/OAuth2 的 Azure Functions 根 URL 身份验证

使用 swagger ui 的 Azure Functions 广告身份验证说未找到 redirect.html