【问题标题】:IdentityServer4: get access token from Azure ADIdentityServer4:从 Azure AD 获取访问令牌
【发布时间】:2019-05-15 09:22:45
【问题描述】:

我使用 Azure AD 作为 IdentityServer4 的外部 IdP。要调用受 AzureAd 保护的 API,我需要从 Azure Ad 获取访问令牌。是否可以在登录过程中获取访问令牌并将其保存到声明中?

我正在使用 IdentityServer4 快速入门 UI。我试图在外部令牌的回调方法中捕获访问令牌,但在 HttpContext 或声明中或在 ProcessLoginCallbackForOidc 方法中没有找到。

IdentityServer4 Azure 广告配置:

services.AddIdentityServer()
    .AddDeveloperSigningCredential()
    .AddInMemoryIdentityResources(Config.GetIdentityResources())
    .AddInMemoryApiResources(Config.GetApiResources())
    .AddInMemoryClients(Config.GetClients())
    .AddTestUsers(Config.GetUsers());

services.AddAuthentication()
    .AddOpenIdConnect("oidc", "Azure AD", options =>
    {
        options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;
        options.SignOutScheme = IdentityServerConstants.SignoutScheme;

        options.Authority = "https://login.microsoftonline.com/fredhutch.onmicrosoft.com/";
        options.ClientId = "<client id>";
        options.Resource = "app_id from azure ad";
        options.ClientSecret = "secret from azure ad";
        options.ResponseType = "code id_token";
        options.TokenValidationParameters = new TokenValidationParameters
        {
            NameClaimType = "sub",
            RoleClaimType = "role"
        };

    });

IdentityServer4 中的客户端配置:

new Client
{
    ClientId = "mvc",
    ClientName = "MVC Client",
    ClientSecrets =
    {
        new Secret("secret".Sha256())
    },
    AllowedGrantTypes = GrantTypes.HybridAndClientCredentials,

    RedirectUris = { "http://localhost:49341/signin-oidc" },
    PostLogoutRedirectUris = { "http://localhost:49341/signout-callback-oidc" },

    AllowedScopes = new List<string>
    {
        IdentityServerConstants.StandardScopes.OpenId,
        IdentityServerConstants.StandardScopes.Profile,
        "b03d4318-278d-40fc-b6b3-3cf47a0e6f4d"
    },
    AllowOfflineAccess=true
}

客户端(ASP.Net Core MVC):

services.AddAuthentication(options =>
{
    options.DefaultScheme = "Cookies";
    options.DefaultChallengeScheme = "oidc";
})
.AddCookie("Cookies")
.AddOpenIdConnect("oidc", options =>
{
    options.SignInScheme = "Cookies";

    options.Authority = "idsrv4url";
    options.ClientId = "mvc";
    options.ClientSecret = "secret";

    options.SaveTokens = true;
    options.ResponseType = "code id_token";

    options.Scope.Clear();
    options.Scope.Add("openid");
    options.Scope.Add("profile");
    options.Scope.Add("b03d4318-278d-40fc-b6b3-3cf47a0e6f4d");
    options.Scope.Add("offline_access");

    options.GetClaimsFromUserInfoEndpoint = true;
    options.SaveTokens = true;

});

【问题讨论】:

    标签: asp.net-core azure-active-directory identityserver4


    【解决方案1】:

    您针对 Azure AD 的设置是一个隐式流程,这意味着您只会获得授权代码和 id 令牌(基于您的 responsetype = "code id_token")。

    您需要做的是订阅OnAuthorizationCodeReceived 事件并在此处请求访问令牌。

    options.Events.OnAuthorizationCodeReceived= contex => {
        var authCode = contex.ProtocolMessage.Code;
        ...
        // Get token
        ...
    };
    

    你可以在这里找到更多信息https://docs.microsoft.com/en-us/azure/active-directory/develop/v1-protocols-oauth-code#use-the-authorization-code-to-request-an-access-token

    【讨论】:

      【解决方案2】:

      通过将 SaveTokens 标志添加到 IdentityServer OIDC 设置:

      services.AddIdentityServer()
          .AddDeveloperSigningCredential()
          .AddInMemoryIdentityResources(Config.GetIdentityResources())
          .AddInMemoryApiResources(Config.GetApiResources())
          .AddInMemoryClients(Config.GetClients())
          .AddTestUsers(Config.GetUsers());
      
      services.AddAuthentication()
          .AddOpenIdConnect("oidc", "Azure AD", options =>
          {
              options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;
              options.SignOutScheme = IdentityServerConstants.SignoutScheme;
      
              options.Authority = "https://login.microsoftonline.com/fredhutch.onmicrosoft.com/";
              options.ClientId = "<client id>";
              options.Resource = "app_id from azure ad";
              options.ClientSecret = "secret from azure ad";
              options.ResponseType = "code id_token";
              options.TokenValidationParameters = new TokenValidationParameters
              {
                  NameClaimType = "sub",
                  RoleClaimType = "role"
              };
              options.SaveTokens = true;
          });
      

      设置该标志后,以下代码现在将成功检索 AAD id_token:

      //External OpenId Connect callback
      public async Task<IActionResult> Callback()
      {
          var result = await HttpContext.AuthenticateAsync(IdentityConstants.ExternalScheme);
          var id_token = result.Properties.GetTokenValue("id_token");
          ...
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-11-13
        • 2022-01-05
        • 1970-01-01
        • 2019-08-31
        • 2020-12-21
        • 1970-01-01
        相关资源
        最近更新 更多