IdentityServer4:从Azure AD获取访问令牌

时间:2018-12-14 05:43:23

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

我将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;

});

2 个答案:

答案 0 :(得分: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

找到更多信息

答案 1 :(得分:0)

通过将id_token标志添加到QuickStart UI模板的ExternalController.Callback()(因此ProcessLoginCallbackForOidc())中,我能够获得Azure AD 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");
    ...
}