UseWindowsAzureActiveDirectoryBearerAuthentication如何在validation令牌时起作用?

我遵循以下GitHub示例,以实现跨WebApp和WebApi的身份validation机制。

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

我正在为WebApp和WebApi使用单个App注册,获取“ https://abc.onmicrosoft.com/App ”的访问令牌并将其传递给WebApi。 我将令牌附加到名为“Bearer”的HTTPS标头。 我在WebApi Owin Startup类中有以下内容来validationAudience和Tenant的令牌,但实际上并未按预期validation令牌。

几个问题:1。什么触发下面的处理程序来validation租户和受众的令牌? 它是Controller类的[Authorize]属性吗? 2.如何找到执行处理程序的令牌? 3.将SaveSigninToken设置为true可保存令牌。 如何检索令牌并从此令牌获取Graph API的访问令牌?

app.UseWindowsAzureActiveDirectoryBearerAuthentication( new WindowsAzureActiveDirectoryBearerAuthenticationOptions { Tenant = "abc.onmicrosoft.com", TokenValidationParameters = new TokenValidationParameters { ValidAudience = "https://abc.onmicrosoft.com/App", SaveSigninToken = true, } }); 

请指教。 提前致谢!

是什么触发了下面的处理程序来validation租户和受众的令牌?

默认情况下,中间件以Active模式运行,因此它将尝试在每个请求中查找令牌。 如果找到一个,它将尝试validation它。 如果它发现它是有效的,则创建一个ClaimsPrincipal ,可以在其他OWIN中间件和Web API组件中访问它。

它还会下载公钥,用于从Azure AD检查应用程序启动时的令牌签名。 如果你使用像Fiddler这样的工具,你可以看到这个。

如何找到执行处理程序的令牌?

我不确定我是否理解这个问题,我希望我的答案能够澄清这一过程。

将SaveSigninToken设置为true可保存令牌。 如何检索令牌并从此令牌获取Graph 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)); 

控制器中的[Authorize]装饰或我们指定的任何方法触发Owin安全处理程序以validation令牌并生成声明。