【问题标题】:How does UseWindowsAzureActiveDirectoryBearerAuthentication work in validating the token?UseWindowsAzureActiveDirectoryBearerAuthentication 在验证令牌时如何工作?
【发布时间】:2015-12-05 02:28:06
【问题描述】:

我正在关注下面的 GitHub 示例,用于跨 WebApp 和 WebApi 实现身份验证机制。

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

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

几个问题: 1. 什么触发以下处理程序为租户和观众验证令牌?它是 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,
                  }
              });

请指教。提前致谢!

【问题讨论】:

    标签: c# authentication asp.net-web-api


    【解决方案1】:

    什么触发以下处理程序为租户和观众验证令牌?

    中间件默认以Active 模式运行,因此它会尝试在每个请求中查找令牌。如果它找到一个,它将尝试验证它。如果它发现它是有效的,则会创建一个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));
    

    【讨论】:

      【解决方案2】:

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

      【讨论】:

      • 是否每次都连接到azure来验证token?
      • 我和 Jaanus 有同样的问题
      • @Jaanus 令牌包含验证它所需的信息。
      • 这个答案不正确。身份验证中间件在每个请求上运行。中间件组件至少在启动时从 Azure AD 下载公钥,并使用该信息来验证传入的令牌。如果它在请求中找到一个有效的令牌,它会从中构造一个 ClaimsPrincipal 来识别用户。 AuthorizeAttribute 只是检查用户的身份,如果身份验证成功,它将在那里。
      • 投反对票,因为这是不正确的。请参阅 juunas 的答案。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-08-19
      • 2022-01-24
      • 2019-12-01
      • 1970-01-01
      • 2018-10-16
      • 2011-04-25
      • 2021-10-11
      相关资源
      最近更新 更多