【问题标题】:User is authenticated after OpenId Connect (AAD) but Unable to find access token用户在 OpenId Connect (AAD) 之后通过身份验证,但无法找到访问令牌
【发布时间】:2019-07-14 15:31:41
【问题描述】:

在用户从 OpenId Connect 进行身份验证后,我试图从 AAD 中查找访问令牌。 它是与 AAD OpenId Connect 集成的 Web 应用程序。我需要获取访问令牌来调用另一个使用相同 AAD 的 API。这是我尝试过的:

  1. 克隆this示例代码。
  2. 在 Startup.cs 文件中,添加以下代码块:

     public void ConfigureServices(IServiceCollection services) {
        services.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor();
    
        services.AddAuthentication(sharedOptions =>
    {
        sharedOptions.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
        sharedOptions.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
    })
    .AddAzureAd(options => Configuration.Bind("AzureAd", options))
          .AddOpenIdConnect("oidc", options =>
          {
              options.Authority = "http://localhost:5000";
              options.ClientId = "<<client-id>>";
              options.SignInScheme = "cookie";
              options.SaveTokens = true;
              options.GetClaimsFromUserInfoEndpoint = true;
              options.RequireHttpsMetadata = false;
    
          })
    .AddCookie();
    services.AddMvc();}
    
  3. HomeController 类中,我添加了一个名为httpContextAccessor 的私有变量,并将其设置在构造函数中。

        private IHttpContextAccessor _httpContextAccessor;
        public HomeController(IHttpContextAccessor httpContextAccessor)
        {
            _httpContextAccessor = httpContextAccessor;
        }
    
  4. HomeController 类中,我添加了一些代码来访问访问令牌。

     public IActionResult Index()
        {
            if (User.Identity.IsAuthenticated)
            {
                var attempt1 = Request.Headers["Authorization"];
                var attempt2 = HttpContext.GetTokenAsync("access_token");
                var attempt3 = _httpContextAccessor.HttpContext.GetTokenAsync("access_token");
                var attempt4 = _httpContextAccessor.HttpContext.Request.Headers["Authorziation"];
            }
            return View();
        }
    

但它们都返回空或 null。我错过了什么吗?

我查看了以下帖子以供参考: How to refresh access token How to get access token from HttpContext in .Net core 2.0

【问题讨论】:

    标签: authentication asp.net-core azure-active-directory access-token openid-connect


    【解决方案1】:

    您需要在 OpenID Connect 配置中将 SaveTokens 设置为 true:

    1. 克隆该代码示例
    2. 保留 Startup.cs ,您不需要添加 .AddOpenIdConnect 部分,AddAzureAd 扩展方法将有助于将 Azure Active Directory 身份验证添加到您的应用程序。

    3. 修改Extensions文件夹中的AzureAdAuthenticationBuilderExtensions.cs

      public void Configure(string name, OpenIdConnectOptions options)
      {
          options.ClientId = _azureOptions.ClientId;
          options.Authority = $"{_azureOptions.Instance}{_azureOptions.TenantId}";
          options.UseTokenLifetime = true;
          options.CallbackPath = _azureOptions.CallbackPath;
          options.RequireHttpsMetadata = false;
          options.SaveTokens = true;  // set to true 
      }
      
    4. 然后就可以从httpContextAccessor获取ID token了:

      var idToken = _httpContextAccessor.HttpContext.GetTokenAsync("id_token");
      

    但访问令牌仍然是 null 。该示例展示了如何使用 OpenID Connect ASP.NET Core 中间件从单个 Azure AD 租户登录用户,这意味着您可以获得ID Token,它作为 OpenID Connect 流的一部分发送到客户端应用程序,并且客户端使用它来对用户进行身份验证。请参考文档:ID tokens

    Access tokens 使客户端能够安全地调用受 Azure 保护的 API。请参考文档:Azure Active Directory access tokens

    如果你想获取访问受Azure AD保护的资源的访问令牌,你应该使用ADAL(Azure AD V1.0端点)来获取令牌,参见代码示例(尤其是use OnAuthorizationCodeReceived to acquire access token):

    https://github.com/Azure-Samples/active-directory-dotnet-webapp-webapi-openidconnect-aspnetcore

    如果您使用的是 Azure AD V2.0 端点,请使用 MSAL

    【讨论】:

    • 使用您的说明步骤 1 - 4 有效。已经拿到令牌了!!谢谢!!
    猜你喜欢
    • 2018-11-07
    • 2018-04-12
    • 2020-04-20
    • 2015-12-25
    • 2015-11-18
    • 2019-04-15
    • 2022-01-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多