我花了24小时阅读有关如何创建Azure功能的所有内容,并成功将MVC WebApi转换为具有多个功能的新功能应用程序。我的问题是我没有找到任何关于如何使用它们进行最基本的身份验证的明确文档或教程。
我的情景很简单。在我的AAD中配置用户,然后授予这些用户访问特定功能的权限。网站上的用户将点击UI元素,这些元素又会触发调用我的Azure功能的Javascript。在函数中,我需要能够以某种方式验证它们的身份,因为我将把它传递给与SQL实例交互的其他函数。
有人可以指点我的文档,文章,一个例子,一些东西,说明我如何实现这一目标?
对于记录,我在门户网站上找到了我的功能应用程序的“身份验证”配置,并选择了AAD作为我的身份验证提供程序。我已经添加了我的功能应用程序并配置了一些用户。然后我编写了以下测试函数:
[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}!");
}
目前,当我尝试直接点击端点时,我会被重定向到登录页面......所以我猜这个部分正在运行。我如何生成/检索用户令牌,将请求发送到函数或在服务器上处理它们并不清楚。
帮助?
答案 0 :(得分:12)
用户通过Azure AD进行身份验证后,您将看到一个AppServiceAuthSessoin
Cookie。这是一个不透明的cookie,但你可以通过调用
https://yourFunctionApp.azurewebsites.net/.auth/me
并将不透明的cookie作为Cookie
标头传递。此外,您获得的id_token
可以用作Bearer
令牌。
实际上它只是看起来对我,我还没有真正测试它作为持有者,所以在那里有点小心。
这种机制被称为 Easy Auth ,谷歌更容易获得该名称。
有关令牌商店的更多信息 -
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
也像持票人一样好:
$ 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"
}
答案 1 :(得分:0)
我为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
答案 2 :(得分:-2)
azure函数当前不支持AuthorizationLevel.User,请参阅here
截至2017年12月,尚未完全实施。