我可以在 Azure AD SSO 中将颁发给一个应用程序的令牌与另一个应用程序一起使用吗?

Posted

技术标签:

【中文标题】我可以在 Azure AD SSO 中将颁发给一个应用程序的令牌与另一个应用程序一起使用吗?【英文标题】:Can I use a token issued to one application with another application in Azure AD SSO? 【发布时间】:2016-06-26 17:09:33 【问题描述】:

假设我在 Azure AD 中配置了两个“应用程序”。一种是称为“A”的 Web API,另一种是称为“B”的本机 Windows 应用程序。用户从 Windows 应用商店下载“B”并使用其 Office 365 凭据登录到 Azure AD。效果很好。他们得到一个令牌。

我可以使用该令牌并将其附加到对 API 应用程序“A”的 REST API 调用吗?

编辑:所以我已经取得了一些进展。我能够获取 Web API 的令牌,但我仍然“未经授权”,它目前正在给我一个交互式登录,以便获取 Web API 的令牌。

这里是关于我的配置的更多细节:

Azure AD 租户 'UWP 的 Foo 应用程序' 应用程序类型:本地客户端应用程序 客户 ID:123 重定向 URI:ms-appx-web://Microsoft.AAD.BrokerPlugin/S-1-15-2-999 其他应用程序的权限: “FooAPI”:委托权限:“访问 MyCompany.Foo.Api” 'Foo Web API' 应用程序类型:Web 应用程序 登录网址:https://api.foo.com 客户端 ID:456 应用 ID URI:https://api.foo.com 回复网址:https://api.foo.com/.auth/login/aad/callback Azure API 应用程序 api-foo-us-east.azurewebsites.net 自定义域:api.foo.com 使用 *.foo.com 通配符证书启用 SSL 绑定 应用服务身份验证 开启 使用 Azure Active Directory 登录 高级 客户端 ID:456 颁发者网址:https://sts.windows.net/tenant_id/ api-foo-us-west.azurewebsites.net 自定义域:api.foo.com 使用 *.foo.com 通配符证书启用 SSL 绑定 应用服务身份验证 开启 使用 Azure Active Directory 登录 高级 客户端 ID:456 颁发者网址:https://sts.windows.net/tenant_id/ api-foo-asia-southeast.azurewebsites.net 自定义域:api.foo.com 使用 *.foo.com 通配符证书启用 SSL 绑定 应用服务身份验证 开启 使用 Azure Active Directory 登录 高级 客户端 ID:456 颁发者网址:https://sts.windows.net/tenant_id/

现在是代码。

当我验证我的 UWP 应用时,我正在这样做:

    static string clientId = "123";
    static string authority = "https://login.windows.net/tenant_id";
    static string uri = string.Format("ms-appx-web://Microsoft.AAD.BrokerPlugin/0", WebAuthenticationBroker.GetCurrentApplicationCallbackUri().Host.ToUpper());
    private AuthenticationContext authContext = new AuthenticationContext(authority);

    private async void AttemptLogin()
    
        WebAccountProvider wap = await WebAuthenticationCoreManager.FindAccountProviderAsync("https://login.microsoft.com", authority);
        WebTokenRequest wtr = new WebTokenRequest(wap, string.Empty, clientId);
        wtr.Properties.Add("resource", "https://graph.windows.net");

        // there is no recorded user. let's start a sign in flow without imposing a specific account.
        WebTokenRequestResult wtrr = await WebAuthenticationCoreManager.RequestTokenAsync(wtr);
        if (wtrr.ResponseStatus == WebTokenRequestStatus.Success)
        
            userAccount = wtrr.ResponseData[0].WebAccount;
            token = wtrr.ResponseData[0].Token;
        

        if (userAccount != null)
        
            OnUserSignedIn();
        
        else
        
             // we got bigger fish to fry!
        
    

    private void OnUserSignedIn()
    
        var redirectUri = new Uri(uri);
        AuthenticationResult authResult = await authContext.AcquireTokenAsync("https://api.foo.com", clientId, redirectUri);

        // just some junk code to call the Web API
        var accountId = ApiClientHelper.AccountIdentifier;
        var client = ApiClientHelper.GetClient();
        client.HttpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(authResult.AccessTokenType, authResult.AccessToken);
        try
        
            var allCustomers = await client.Customers.GetAllWithOperationResponseAsync(accountId);
        
        catch (Exception ex)
        
            Debug.WriteLine(ex.ToString());
        
    

所以有趣的是,当我在 AttemptLogin 方法中获得“https://graph.windows.net”的令牌时,当我获得“https://api.foo.com”的令牌时,令牌字符串的值是 IDENTICAL。

我返回的状态码是“未授权”。

【问题讨论】:

【参考方案1】:

我知道为什么它不起作用了。首先,我通过 azure 门户使用身份验证,而不是在我的应用程序中设置 owin。其次,我错过了一个非常关键但不容易知道问题所在的关键 nuget 包。执行 startup.cs 代码需要 Microsoft.owin.host.systemweb。没有它,您只会收到未经授权的消息,没有其他解释。

【讨论】:

【参考方案2】:

如果你是原生应用,就没有“登录”这回事。您执行的操作是始终为某些资源请求令牌。在获取此类令牌的过程中,最终用户可能必须执行登录 - 但从应用程序的角度来看,该操作是获取令牌。 因此:如果在您的令牌获取操作中您为 API 请求令牌,您将让用户通过登录手势,您将获得 API 的令牌。 即使您最初获得了不同 API 的令牌 - 您与第一个访问令牌一起获得的刷新令牌也能够为您的本机客户端注册以请求访问的所有 API 获取访问令牌,因此您可以获得您的 API 的新令牌,无需任何额外的用户交互。

【讨论】:

感谢您的详细解释。由于我能够在我的 UWP 应用程序中获取“本机客户端应用程序”的令牌,我如何使用该令牌来获取我的“Web 应用程序”(Web API)的令牌,以便我可以使用该令牌?我是否使用 ADAL.NET(UWP 版本)?我找到了这个链接blogs.msdn.com/b/richard_dizeregas_blog/archive/2015/08/07/…,它似乎展示了如何使用 Office 365 REST API 来做到这一点。也许这是正确的技术?

以上是关于我可以在 Azure AD SSO 中将颁发给一个应用程序的令牌与另一个应用程序一起使用吗?的主要内容,如果未能解决你的问题,请参考以下文章

Azure AD - 为啥我无法验证 Azure AD 为我的 Web API 颁发的 JWT 令牌?收到“IDX10516:签名验证失败”错误

Android/iOS:如何使用 SAML 协议通过 Azure AD 为移动设备提供 SSO

管理员帐户的 Azure AD SSO 登录问题

Java Spring 应用程序 - 与 Azure AD 集成以实现 SSO

Azure AD 与 AWS IAM 集成实现SSO—上(Azure部分)

使用 Azure Active Directory 或 ADFS 或 AD 的 SSO