MVC5 应用程序使用 Azure Active Directory + REST API -- 为 PowerBI / O365 授权
MVC5 app using Azure Active Directory + REST API -- to auth for PowerBI / O365
我正在尝试调整此处显示的 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 项目)中一切正常。我还在 Startup.Auth.cs
.
中配置了 OWIN app.UseOpenIdConnectAuthentication
东西
似乎问题是我在 'ClaimsPrincipal.Current' 中拥有的唯一声明类型是 'CookieAuthentication' - 它缺少 http://schemas.microsoft.com/identity/claims/objectidentifier 声明。
另外...Microsoft OAuth window 永远不会在浏览器中打开...但是,错误出在与 ActiveDirectory 相关的代码中...该代码首先不需要 OAuth 令牌地方对吧?
推荐的方法是使用 Open ID Connect 中间件自动为您检索的代码。这里有相关示例:
https://github.com/AzureADSamples/WebApp-WebAPI-OpenIDConnect-DotNet
此示例使用 OAuth 获取 AAD 图的令牌 API。我不了解 PowerBI,但我相信这完全类似于为 PowerBI 获取令牌。
特别注意这个文件:
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 用于检索图形的令牌 API。此时,为 Graph API 获取令牌的唯一原因是将短期授权代码交换为寿命更长的刷新令牌,并将其存储在缓存中。这就是从未使用 'result' 的原因。
稍后,在以下文件中,缓存用于检索令牌并使用它来访问图形:
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));
这次真的用到了token
用 PowerBI 替换示例中的 Graph API,我认为你应该可以开始了。
请注意,另一件需要注意的事情是缓存实现。该文件包含一个适当的名称 NaiveSessionCache
.
如果您有多个前端,您将需要实现自己的、不那么天真的会话缓存,以便所有前端可以共享相同的缓存。
至少对我而言,一个潜在的解决方法是在 Azure AD 上使用 "native app" 设置并遵循此工作流程,而不是 Web 应用程序 + oauth 工作流程:
我正在尝试调整此处显示的 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 项目)中一切正常。我还在 Startup.Auth.cs
.
app.UseOpenIdConnectAuthentication
东西
似乎问题是我在 'ClaimsPrincipal.Current' 中拥有的唯一声明类型是 'CookieAuthentication' - 它缺少 http://schemas.microsoft.com/identity/claims/objectidentifier 声明。
另外...Microsoft OAuth window 永远不会在浏览器中打开...但是,错误出在与 ActiveDirectory 相关的代码中...该代码首先不需要 OAuth 令牌地方对吧?
推荐的方法是使用 Open ID Connect 中间件自动为您检索的代码。这里有相关示例:
https://github.com/AzureADSamples/WebApp-WebAPI-OpenIDConnect-DotNet
此示例使用 OAuth 获取 AAD 图的令牌 API。我不了解 PowerBI,但我相信这完全类似于为 PowerBI 获取令牌。
特别注意这个文件:
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 用于检索图形的令牌 API。此时,为 Graph API 获取令牌的唯一原因是将短期授权代码交换为寿命更长的刷新令牌,并将其存储在缓存中。这就是从未使用 'result' 的原因。
稍后,在以下文件中,缓存用于检索令牌并使用它来访问图形:
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));
这次真的用到了token
用 PowerBI 替换示例中的 Graph API,我认为你应该可以开始了。
请注意,另一件需要注意的事情是缓存实现。该文件包含一个适当的名称 NaiveSessionCache
.
如果您有多个前端,您将需要实现自己的、不那么天真的会话缓存,以便所有前端可以共享相同的缓存。
至少对我而言,一个潜在的解决方法是在 Azure AD 上使用 "native app" 设置并遵循此工作流程,而不是 Web 应用程序 + oauth 工作流程: