如何使用 id_token 从 Azure Function 应用程序获取 Azure access_token?

Posted

技术标签:

【中文标题】如何使用 id_token 从 Azure Function 应用程序获取 Azure access_token?【英文标题】:How get in Azure access_token from Azure Function app with id_token? 【发布时间】:2020-06-27 20:33:23 【问题描述】:

当用户访问匿名函数应用程序时,我正在尝试获取授权和访问和刷新令牌。

我已经按照这个tutorial使用了Function App的B2C租户授权。

我可以在函数应用程序中使用这个获取 id_token。要获取令牌,我将函数应用程序的地址粘贴到浏览器中:

public static async Task<IActionResult> Run([HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req, ILogger log)
        
            string code = null;
            foreach (var h in req.Headers)
            
                if(h.Key.Equals("X-MS-TOKEN-AAD-ID-TOKEN"))
                    code += (h.Value);//authorisation id_token to get access_token
            

我已经尝试了几个教程来获取访问/刷新令牌,这个one 我可以遵循/理解:我在 Fiddler 中看到我在https://tenantName.azurewebsites.net/.auth/login/aad/callback 获得了 id_token;但是下一行https://functionAppName.azurewebsites.net/api/functionName GET 请求,响应是 Server Error, 404 - File or directory not found.":

public static async Task<IActionResult> Run([HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req, ILogger log)
        
            string code = null;
            foreach (var h in req.Headers)
            
                if(h.Key.Equals("X-MS-TOKEN-AAD-ID-TOKEN"))
                    code += (h.Value);
            
var content = new StringContent(
                "grant_type=refresh_token" +
                "&client_id=" + B2CApplication-ApiID+
                "&redirect_uri="+"https://functionapp.azurewebsites.net/.auth/login/aad/callback"+
                "&client_secret="+"XXX"+
                "&code" + code +
                "&scope=user.read"+
                "&resource="+"https://graph.microsoft.com",//also tried https://graph.microsoft.com/.default
                Encoding.UTF8,
                "application/x-www-form-urlencoded");

    BaseURL="https://tenantName.b2clogin.com/tenantName.onmicrosoft.com/oauth2/v2.0/token";
    var response = await httpClient.PostAsync(BaseURL, content);
    var result = await response.Content.ReadAsStringAsync();

    dynamic json = JsonConvert.DeserializeObject(result);
    var access_token = json.access_token;
    var refresh_token = json.refresh_token;
    string token_value = access_token.value; 
    string refresh_value = refresh_token.value;
    return (ActionResult)new OkObjectResult($"Complete " ,token_value);

这是设置:

    Azure AD B2C Tenant
    Domain Name: tenantName.onmicrosoft.com
    Applications: B2CApplication-Api
        WebApp/API : Yes
        Allow Implicit Flow : Yes
        Reply Url : https://functionapp.azurewebsites.net/.auth/login/aad/callback
        App ID : https://tenantName.onmicrosoft.com/B2CApplication-Api
        Add URI (optional): identityauth
        Include Native client: No
        Secret key: XXX
        Reply URL: https://tenantName.azurewebsites.net/.auth/login/aad/callback
        API Access to Microsoft Graph: Read User Profile with granted admin consent
        Published Scope read: https://tenantName.onmicrosoft.com/identityauth/read
        Published Scope user_impersonation: https://tenantName.onmicrosoft.com/identityauth/user_impersonation
    User Flows
        SignupSignIn, Password reset, profile editing
        Application : B2CApplication-Api
        Reply Url : https://tenantName.azurewebsites.net/.auth/login/aad/callback


    Azure Function: Anonymous
    App Service Authentication : On
    Action to take when not authenticated : Login with Azure AD
    Authentication provider:Azure AAD
        Management Mode : Advanced
        client id : B2C-Application-ApplicationID
        issuer url : https://tenantName.b2clogin.com/tenantName.onmicrosoft.com/v2.0/.well-known/openid-configuration?p=B2C_1_signinsignoutpolicy
        Allowed Token Audiences: B2C-Application-Application_ID

【问题讨论】:

您只显示了上面的 refresh_token 授权调用;当您尝试授权代码授权时会发生什么? 嗨@sellotape 我得到相同的响应服务器错误,404 - 找不到文件或目录。但我知道我有 id_token (authorization_code) 并且我发送的请求是针对 acces_code 和刷新 docs.microsoft.com/en-us/azure/active-directory/azuread-dev/… 比较混乱,access_token是什么?此链接中的图表显示用户获取的第一个代码是授权代码,稍后获取 access_code docs.microsoft.com/en-us/azure/active-directory/azuread-dev/…,但其他文档指向 grant_type=authorization_code 以获取 access_token(第 3 节)docs.microsoft.com/en-us/graph/auth-v2-user ID 令牌一般对授权请求没有任何价值;只有访问令牌可以。您需要获取该 刷新令牌(如有必要)以刷新现有访问令牌。你确定你的网址都正确吗?例如将您的实际租户名称/ID 代入其中? 首先,我将消除围绕刷新令牌的混淆,并尝试在此时使用授权码授权获取访问令牌。那么,您的 b2c 租户实际上是否称为“tenantName”,或者您只是将其替换为不显示真实的租户?你可以(最初,无论如何)尝试使用“login.microsoftonline.com”而不是“tenantName.b2clogin.com”(它是valid until Dec 2020),看看这是否能让你走得更远。 【参考方案1】:

Azure AD B2C 访问令牌只能用于访问您自己的受保护资源。

我们不能使用 Azure AD B2C 颁发的访问令牌来调用 Microsoft Graph API。您必须让用户调用您的 API,并且您的 API 需要使用 client_credentials 来获取 Graph API 的令牌。

而且,https://graph.microsoft.com 用于资源(v1.0),https://graph.microsoft.com/.default 用于范围(v2.0)。详情可参考this article。

参考:

B2C calling a Web API you own

AAD calling MS Graph API

【讨论】:

以上是关于如何使用 id_token 从 Azure Function 应用程序获取 Azure access_token?的主要内容,如果未能解决你的问题,请参考以下文章

如何强制Azure Active Directory身份验证服务重新发出带有更新声明的id_token?

由于错误的 KID,passport-azure-ad 无法验证“id_token”

使用 id_token 对受广告保护的应用进行身份验证

在 keycloak id_token 中获取 Azure 组信息

Azure AD Daemon应用程序的应用程序权限和id_token

从 Azure AD 中获取用户的令牌主题标识符(子)