1

我正在尝试调整此处显示的 WebAPI 示例,以在 MVC5 中使用:

https://msdn.microsoft.com/en-US/library/dn931282.aspx#Configure

我有一个基于常规AccountController的登录系统,但我还需要用户通过 OAuth 登录到 PowerBI,因此我可以通过 PowerBI REST API 提取数据集。但是,我ClaimsPrincipal.Current.FindFirst(..)得到了null

    private static async Task<string> getAccessToken()
    {
        // Create auth context (note: token is not cached)
        AuthenticationContext authContext = new AuthenticationContext(Settings.AzureADAuthority);

        // Create client credential
        var clientCredential = new ClientCredential(Settings.ClientId, Settings.Key);

        // Get user object id
        var userObjectId = ClaimsPrincipal.Current.FindFirst(Settings.ClaimTypeObjectIdentifier).Value;

        // Get access token for Power BI
        // Call Power BI APIs from Web API on behalf of a user
        return authContext.AcquireToken(Settings.PowerBIResourceId, clientCredential, new UserAssertion(userObjectId, UserIdentifierType.UniqueId.ToString())).AccessToken;
    }

在示例应用程序(WebAPI 项目)中一切正常。我app.UseOpenIdConnectAuthentication还在Startup.Auth.cs.

看来问题是我在“ClaimsPrincipal.Current”中拥有的唯一声明类型是“CookieAuthentication” - 它缺少http://schemas.microsoft.com/identity/claims/objectidentifier声明。

另外...Microsoft OAuth 窗口永远不会在浏览器中打开...但是,错误出现在 ActiveDirectory 相关代码中...该代码首先不需要 OAuth 令牌,对吗?

4

2 回答 2

3

推荐的方法是使用 Open ID Connect 中间件将为您自动检索的代码。这里有相关示例:

https://github.com/AzureADSamples/WebApp-WebAPI-OpenIDConnect-DotNet

此示例使用 OAuth 获取 AAD Graph API 的令牌。我不知道 PowerBI,但我相信这与获取 PowerBI 令牌完全类似。

特别注意这个文件:

https://github.com/AzureADSamples/WebApp-WebAPI-OpenIDConnect-DotNet/blob/master/TodoListWebApp/App_Start/Startup.Auth.cs

AuthorizationCodeReceived = (context) =>
{
    var code = context.Code;

    ClientCredential credential = new ClientCredential(clientId, appKey);
    string userObjectID = context.AuthenticationTicket.Identity.FindFirst("http://schemas.microsoft.com/identity/claims/objectidentifier").Value;
    AuthenticationContext authContext = new AuthenticationContext(Authority, new NaiveSessionCache(userObjectID));
    AuthenticationResult result = authContext.AcquireTokenByAuthorizationCode(code, new Uri(HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Path)), credential, graphResourceId);

    return Task.FromResult(0);
},

每次成功的身份验证都会调用上面的代码,并且 ADAL 用于检索 Graph API 的令牌。此时,为 Graph API 获取令牌的唯一原因是将短暂的身份验证代码交换为寿命较长的刷新令牌并将其存储在缓存中。这就是为什么从未使用过“结果”的原因。

稍后,在以下文件中,使用缓存来检索令牌并使用它来访问图形:

https://github.com/AzureADSamples/WebApp-WebAPI-OpenIDConnect-DotNet/blob/master/TodoListWebApp/Controllers/UserProfileController.cs

string tenantId = ClaimsPrincipal.Current.FindFirst(TenantIdClaimType).Value;
string userObjectID = ClaimsPrincipal.Current.FindFirst("http://schemas.microsoft.com/identity/claims/objectidentifier").Value;
AuthenticationContext authContext = new AuthenticationContext(Startup.Authority, new NaiveSessionCache(userObjectID));
ClientCredential credential = new ClientCredential(clientId, appKey);
result = authContext.AcquireTokenSilent(graphResourceId, credential, new UserIdentifier(userObjectID, UserIdentifierType.UniqueId));

这次实际使用了令牌。

在示例中将 PowerBI 替换为 Graph API,我认为您应该很高兴。

请注意,要注意的另一件事是缓存实现。该文件包含适当的名称NaiveSessionCache

https://github.com/AzureADSamples/WebApp-WebAPI-OpenIDConnect-DotNet/blob/master/TodoListWebApp/Utils/NaiveSessionCache.cs

如果您有多个前端,您将需要实现自己的、不那么天真的会话缓存,以便所有前端可以共享相同的缓存。

于 2015-04-24T16:06:00.407 回答
0

至少对我而言,一个潜在的解决方法是使用 Azure AD 上的“本机应用程序”设置并遵循此工作流程,而不是 Web 应用程序 + oauth 工作流程:

https://msdn.microsoft.com/en-US/library/dn877545.aspx

于 2015-04-27T08:00:55.047 回答