【发布时间】:2018-02-01 07:50:45
【问题描述】:
我在从 Azure 中的 Web 应用程序获取 API 应用程序调用工作时遇到问题。以下是事物的结构 -
- 受 Azure AD 身份验证保护的 Asp.Net Core 1.1 Web 应用 - 使用 Kestrel 在本地运行
Web 应用的 StartUp.cs 具有以下代码,用于将令牌获取到 Web api
app.UseCookieAuthentication();
app.UseOpenIdConnectAuthentication(new OpenIdConnectOptions
{
ClientId = ClientId, //Client Id of my current web app
ClientSecret = ClientSecret, //ClientSecret of my current web app
Authority = "https://login.microsoftonline.com/tenantguid", CallbackPath = Configuration[Constants.ApplicationProxyCallbackPath],
ResponseType = OpenIdConnectResponseType.CodeIdToken,
Events = new OpenIdConnectEvents
{
OnAuthorizationCodeReceived = OnAuthorizationCodeReceived,
OnRemoteFailure = OnAuthenticationFailed
}
});
对于 OnAuthorizationCodeReceived 方法,这是我的代码
private async Task OnAuthorizationCodeReceived(AuthorizationCodeReceivedContext context)
{
string userObjectId = (context.Ticket.Principal.FindFirst(Constants.ClaimsSchemaUri))?.Value;
ClientCredential clientCred = new ClientCredential(ClientId, ClientSecret);
AuthenticationContext authContext = new AuthenticationContext(Authority, new NaiveSessionCache(userObjectId, context.HttpContext.Session));
AuthenticationResult authResult = await authContext.AcquireTokenByAuthorizationCodeAsync(
context.ProtocolMessage.Code,
new Uri(context.Properties.Items[OpenIdConnectDefaults.RedirectUriForCodePropertiesKey]),
clientCred,
WebAPIClientId);
}
使用上面的代码我可以成功获得不记名令牌。
-
我调用 WebApi 的控制器类
Task<string> results = null; string resultSet = String.Empty; AuthenticationResult authResult = null; string userObjectID = (currentUser.FindFirst("http://schemas.microsoft.com/identity/claims/objectidentifier"))?.Value; AuthenticationContext authContext = new AuthenticationContext(Startup.Authority, new NaiveSessionCache(userObjectID, current.Session)); ClientCredential credential = new ClientCredential(Startup.ClientId, Startup.ClientSecret); authResult = await authContext.AcquireTokenSilentAsync(Startup.SearchAPIClientId, credential, new UserIdentifier(userObjectID, UserIdentifierType.UniqueId)); //var callerIdentity = currentUser.Identity as WindowsIdentity; HttpClientHandler handler = null; //Setup async action Action action = () => { handler = new HttpClientHandler() { AllowAutoRedirect = true }; //Setup for windows authentication var client = new HttpClient(handler); //Add common http headers client.DefaultRequestHeaders.Add("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8"); client.DefaultRequestHeaders.Add("Accept-Encoding", "gzip, deflate"); client.DefaultRequestHeaders.Add("Accept-Language", "en-US,en;q=0.8"); client.DefaultRequestHeaders.Add("User-Agent", "Mozilla/5.0 (Windows NT 6.2; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36"); client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", authResult.AccessToken); results = client.GetStringAsync("https://myapi.azurewebsites.net/api/search/"); }; action.Invoke(); resultSet = await results as string;
对 API 的调用被重定向到 login.microsftonline.com,这意味着我的令牌未被理解。
- Web API 使用代码中的 OpenIdConnect 包通过 Azure 身份验证进行保护,就像上面的 Web 应用代码一样。
我查看了几个相关的帖子,但没有任何效果。
更新 1 - 更新 Web API 以使用 JWTBearer 身份验证 现在,我在 Web App 中获得的不记名令牌能够成功地通过 Web API 对我进行身份验证。
我的 Web API 应该调用另一个同样受 Azure AD 身份验证保护的自定义 API。我希望获得相同的令牌,但为了启动该问题,我在将获取令牌用于其他自定义 API 时遇到了问题。它抛出内部服务器 500,没有任何消息。有什么想法吗?
更新 2 - 详细错误 在尝试获取第三个 api 的令牌时,我遇到了以下异常- “AADSTS50105:应用程序‘源客户端 id guid’未分配给应用程序‘目标客户端 id guid’的角色。”
【问题讨论】:
-
在提供
AuthorizationHeader 和不记名令牌后,您是否能够从 Postman 访问该 API? -
不,我做不到。使用上面代码中生成的令牌,我无法使用 Postman 拨打电话。
-
您是否收到 401 或任何其他错误消息?如果令牌有效,那么您应该可以从 Postman 拨打电话。
-
我看到 login.microsoftonline.com 发生 302
-
这可能会有所帮助。 leastprivilege.com/2011/05/31/…
标签: azure asp.net-web-api azure-api-apps