AcquireTokenAsync returns "invalid_grant", "AADSTS65001"
AcquireTokenAsync returns "invalid_grant", "AADSTS65001"
我正在尝试从基于站点的 Web 服务调用 Azure 托管 WebAPI。
基于站点的服务是一个 adal-angluar SPA,它必须调用 Azure 中托管的 rest API。
来自 AAD 的不记名令牌已成功传递到基于站点的 Web API,然后这必须代表用户获取一个新令牌以调用下游 API,如以下示例所示:
https://github.com/Azure-Samples/active-directory-dotnet-webapi-onbehalfof
示例中的下游API是https://graph.windows.net。并将其作为 resourceId 传递到 AcquireTokenAsync 调用中。
就我而言,下游 API 是我正在编写的 Azure 应用程序,因此我可以完全控制它。
我遇到的问题是 'invalid_grant' 从我站点中的 AcquireTokenAsync 调用返回 api,它试图代表登录用户获取新令牌。
基于站点的 web 应用程序在 Azure 中创建了一个 appid,并尝试获取新令牌,如下所示:
var appId = ConfigurationManager.AppSettings["ActiveDirectoryApplicationId"];
var appKey = ConfigurationManager.AppSettings["ActiveDirectoryApplicationKey"];
var aadInstance = ConfigurationManager.AppSettings["ActiveDirectoryInstance"];
var tenant = ConfigurationManager.AppSettings["ActiveDirectoryTenant"];
var onboardingResourceId = ConfigurationManager.AppSettings["OnboardingApplicationResourceId"];
var clientCredential = new ClientCredential(appId, appKey);
var bootstrapContext =
ClaimsPrincipal.Current.Identities.First().BootstrapContext as
System.IdentityModel.Tokens.BootstrapContext;
var userName = ClaimsPrincipal.Current.FindFirst(ClaimTypes.Upn) != null ? ClaimsPrincipal.Current.FindFirst(ClaimTypes.Upn).Value : ClaimsPrincipal.Current.FindFirst(ClaimTypes.Email).Value;
var userAccessToken = bootstrapContext.Token;
var userAssertion = new UserAssertion(bootstrapContext.Token, "urn:ietf:params:oauth:grant-type:jwt-bearer", userName);
var authority = string.Format(System.Globalization.CultureInfo.InvariantCulture, aadInstance, tenant);
var userId = ClaimsPrincipal.Current.FindFirst(ClaimTypes.NameIdentifier).Value;
var authContext = new AuthenticationContext(authority, new TokenCache());
var result = await authContext.AcquireTokenAsync(onboardingResourceId, clientCredential, userAssertion);
var accessToken = result.AccessToken;
return accessToken;
所以我的问题是,需要在 Azure 中实施什么安全措施才能获得令牌?我读到下游 API 的应用程序清单需要更新以将基于站点的应用程序包含为 "knownClientApplication"。对吗?
我的下游网站的 resourceId 应该是什么样子 api?
我可以在不将下游 Web Api 部署到 Azure 的情况下测试所有这些吗?我希望能够在本地调试所有这些,包括安全性。
谢谢。
knownClientApplications
数组包含众所周知的应用程序的客户端 ID。意思是当用户第一次同意你的前端应用时,除了前端应用的要求外,它还会显示API的权限要求。您不需要单独同意 API,这通常是不需要的。这样一来,他们就会得到同意并立即获得许可。
您可以在 Azure 门户中找到的资源 ID。只需找到您 API 的应用程序,转到“属性”,然后找到应用程序 ID URI:
通常,App ID URI(或资源 URI)的格式为 https://your-domain-name.com/AppName。多租户应用程序的重要一点是 URI 中的域必须是 Azure AD 中经过验证的域。
是的,您可以在本地环境中测试所有内容。只要您将回复 URL 指定为 localhost 等,您就可以开始了。
很抱歉,我不太确定您收到无效授权错误的原因。
要授予自定义应用程序代表用户调用另一个应用程序的权限,您需要执行以下步骤:
- 在旧门户中找到自定义应用程序并打开
配置页面。
- 点击底部的添加应用程序
屏幕.
- Select 所有应用 搜索您要提供的应用名称
访问,然后单击勾号添加。
- Select '委托
应用程序权限部分中的权限' 5. 列表项
- 点击保存。
我正在尝试从基于站点的 Web 服务调用 Azure 托管 WebAPI。
基于站点的服务是一个 adal-angluar SPA,它必须调用 Azure 中托管的 rest API。
来自 AAD 的不记名令牌已成功传递到基于站点的 Web API,然后这必须代表用户获取一个新令牌以调用下游 API,如以下示例所示:
https://github.com/Azure-Samples/active-directory-dotnet-webapi-onbehalfof
示例中的下游API是https://graph.windows.net。并将其作为 resourceId 传递到 AcquireTokenAsync 调用中。
就我而言,下游 API 是我正在编写的 Azure 应用程序,因此我可以完全控制它。
我遇到的问题是 'invalid_grant' 从我站点中的 AcquireTokenAsync 调用返回 api,它试图代表登录用户获取新令牌。
基于站点的 web 应用程序在 Azure 中创建了一个 appid,并尝试获取新令牌,如下所示:
var appId = ConfigurationManager.AppSettings["ActiveDirectoryApplicationId"];
var appKey = ConfigurationManager.AppSettings["ActiveDirectoryApplicationKey"];
var aadInstance = ConfigurationManager.AppSettings["ActiveDirectoryInstance"];
var tenant = ConfigurationManager.AppSettings["ActiveDirectoryTenant"];
var onboardingResourceId = ConfigurationManager.AppSettings["OnboardingApplicationResourceId"];
var clientCredential = new ClientCredential(appId, appKey);
var bootstrapContext =
ClaimsPrincipal.Current.Identities.First().BootstrapContext as
System.IdentityModel.Tokens.BootstrapContext;
var userName = ClaimsPrincipal.Current.FindFirst(ClaimTypes.Upn) != null ? ClaimsPrincipal.Current.FindFirst(ClaimTypes.Upn).Value : ClaimsPrincipal.Current.FindFirst(ClaimTypes.Email).Value;
var userAccessToken = bootstrapContext.Token;
var userAssertion = new UserAssertion(bootstrapContext.Token, "urn:ietf:params:oauth:grant-type:jwt-bearer", userName);
var authority = string.Format(System.Globalization.CultureInfo.InvariantCulture, aadInstance, tenant);
var userId = ClaimsPrincipal.Current.FindFirst(ClaimTypes.NameIdentifier).Value;
var authContext = new AuthenticationContext(authority, new TokenCache());
var result = await authContext.AcquireTokenAsync(onboardingResourceId, clientCredential, userAssertion);
var accessToken = result.AccessToken;
return accessToken;
所以我的问题是,需要在 Azure 中实施什么安全措施才能获得令牌?我读到下游 API 的应用程序清单需要更新以将基于站点的应用程序包含为 "knownClientApplication"。对吗?
我的下游网站的 resourceId 应该是什么样子 api?
我可以在不将下游 Web Api 部署到 Azure 的情况下测试所有这些吗?我希望能够在本地调试所有这些,包括安全性。
谢谢。
knownClientApplications
数组包含众所周知的应用程序的客户端 ID。意思是当用户第一次同意你的前端应用时,除了前端应用的要求外,它还会显示API的权限要求。您不需要单独同意 API,这通常是不需要的。这样一来,他们就会得到同意并立即获得许可。
您可以在 Azure 门户中找到的资源 ID。只需找到您 API 的应用程序,转到“属性”,然后找到应用程序 ID URI:
通常,App ID URI(或资源 URI)的格式为 https://your-domain-name.com/AppName。多租户应用程序的重要一点是 URI 中的域必须是 Azure AD 中经过验证的域。
是的,您可以在本地环境中测试所有内容。只要您将回复 URL 指定为 localhost 等,您就可以开始了。
很抱歉,我不太确定您收到无效授权错误的原因。
要授予自定义应用程序代表用户调用另一个应用程序的权限,您需要执行以下步骤:
- 在旧门户中找到自定义应用程序并打开 配置页面。
- 点击底部的添加应用程序 屏幕.
- Select 所有应用 搜索您要提供的应用名称 访问,然后单击勾号添加。
- Select '委托 应用程序权限部分中的权限' 5. 列表项
- 点击保存。