如何使用WindowsAzureActiveDirectoryBearerAuthentication来验证令牌
本文关键字:验证 令牌 WindowsAzureActiveDirectoryBearerAuthentication 何使用 | 更新日期: 2023-09-27 18:11:56
我正在遵循以下GitHub示例来跨WebApp和WebApi实现身份验证机制。
https://github.com/AzureADSamples/WebApp-WebAPI-OpenIDConnect-DotNet
我正在对 WebApp 和 WebAPI 使用单个应用注册,获取"https://abc.onmicrosoft.com/App"的访问令牌并将其传递给 WebApi。我正在将令牌附加到名为"持有者"的 HTTPS 标头。我在 WebApi Owin 启动类中有以下内容来验证受众和租户的令牌,但实际上并没有按预期验证这些令牌。
几个问题:1. 什么触发以下处理程序来验证租户和受众的令牌?是控制器类上的 [授权] 属性吗?2. 如何找到执行处理程序的令牌?3. 将"保存登录令牌"设置为 true 将保存令牌。如何从此令牌检索令牌以及获取图形 API 的访问令牌?
app.UseWindowsAzureActiveDirectoryBearerAuthentication(
new WindowsAzureActiveDirectoryBearerAuthenticationOptions
{
Tenant = "abc.onmicrosoft.com",
TokenValidationParameters = new TokenValidationParameters
{
ValidAudience = "https://abc.onmicrosoft.com/App",
SaveSigninToken = true,
}
});
请指教。提前感谢!
什么触发以下处理程序来验证租户和受众的令牌?
默认情况下,中间件以Active
模式运行,因此它将尝试在每个请求中查找令牌。如果找到一个,它将尝试验证它。如果发现它有效,则会创建一个可在其他 OWIN 中间件和 Web API 组件中访问的ClaimsPrincipal
。
它还会下载公钥,用于从 Azure AD 在应用启动时检查令牌签名。如果您使用像 Fiddler 这样的工具,您可以看到这一点。
我如何在哪里找到执行处理程序的令牌?
不确定我是否理解这个问题,我希望我上面的回答澄清了这个过程。
将 SaveSigninToken 设置为 true 将保存令牌。如何从此令牌检索令牌以及获取图形 API 的访问令牌?
您尝试做的是使用 on-behalf-of
流调用 API。您可以在此处找到示例应用:https://github.com/Azure-Samples/active-directory-dotnet-webapi-onbehalfof。更具体地说,您应该对这部分感兴趣:https://github.com/Azure-Samples/active-directory-dotnet-webapi-onbehalfof/blob/master/TodoListService/Controllers/TodoListController.cs#L133。
ClientCredential clientCred = new ClientCredential(clientId, appKey);
var bootstrapContext = ClaimsPrincipal.Current.Identities.First().BootstrapContext as System.IdentityModel.Tokens.BootstrapContext;
string userName = ClaimsPrincipal.Current.FindFirst(ClaimTypes.Upn) != null ? ClaimsPrincipal.Current.FindFirst(ClaimTypes.Upn).Value : ClaimsPrincipal.Current.FindFirst(ClaimTypes.Email).Value;
string userAccessToken = bootstrapContext.Token;
UserAssertion userAssertion = new UserAssertion(bootstrapContext.Token, "urn:ietf:params:oauth:grant-type:jwt-bearer", userName);
string authority = String.Format(CultureInfo.InvariantCulture, aadInstance, tenant);
string userId = ClaimsPrincipal.Current.FindFirst(ClaimTypes.NameIdentifier).Value;
AuthenticationContext authContext = new AuthenticationContext(authority, new DbTokenCache(userId));
// In the case of a transient error, retry once after 1 second, then abandon.
// Retrying is optional. It may be better, for your application, to return an error immediately to the user and have the user initiate the retry.
bool retry = false;
int retryCount = 0;
do
{
retry = false;
try
{
result = await authContext.AcquireTokenAsync(graphResourceId, clientCred, userAssertion);
accessToken = result.AccessToken;
}
catch (AdalException ex)
{
if (ex.ErrorCode == "temporarily_unavailable")
{
// Transient error, OK to retry.
retry = true;
retryCount++;
Thread.Sleep(1000);
}
}
} while ((retry == true) && (retryCount < 1));
控制器中的 [授权] 修饰或我们指定的任何方法都会触发 Owin 安全处理程序来验证令牌并生成声明。