IdentityServer4 Делегирование с Windows Аутентификация User.Identity.Name является пустым - PullRequest
0 голосов
/ 29 января 2020

У меня есть следующий поток Asp. Net Базовое приложение (приложение), которое вызывает Asp. Net Базовое веб-API (API1), которое inturn вызывает другой Asp. Net Веб-API (API2). )

Я использую IdentityServer4 с Windows Аутентификация для аутентификации моих пользователей, вот мой код:

Определение ApiResources:

new ApiResource("api1", "api1", new List<string> {  JwtClaimTypes.Name, JwtClaimTypes.Email}),
new ApiResource("api2", "api2", new List<string> {  JwtClaimTypes.Name, JwtClaimTypes.Email})

Определение клиента

new Client
{
    ClientId = "app1",
    ClientName = "app1",
    ClientSecrets = { new Secret("app1".Sha256())},
    AllowedGrantTypes = GrantTypes.HybridAndClientCredentials,
    AllowedScopes =
    {
        IdentityServerConstants.StandardScopes.OpenId,
        IdentityServerConstants.StandardScopes.Profile,
        IdentityServerConstants.StandardScopes.OfflineAccess,
        IdentityServerConstants.StandardScopes.Email,
        "api1"
    },
    RedirectUris = { "https://localhost:44375/signin-oidc" },
    FrontChannelLogoutUri = "https://localhost:44375/signout-oidc",
    PostLogoutRedirectUris = { "https://localhost:44375/signout-callback-oidc" },

    AllowOfflineAccess = true,
    RequireConsent = false,
    AccessTokenLifetime = 5
},
new Client
{
    ClientId = "api1",
    ClientSecrets = { new Secret("api1".Sha256())},
    AllowedGrantTypes = {"delegation" },
    AllowedScopes = {
        IdentityServerConstants.StandardScopes.OpenId,
        IdentityServerConstants.StandardScopes.Profile,
        IdentityServerConstants.StandardScopes.Email,
        "api2"}
}

Код делегирования в API1

public async Task<string> DelegateAsync(string userToken)
{
    var client = new HttpClient();
    var disco = await client.GetDiscoveryDocumentAsync("https://localhost:44382/");
    if (disco.IsError) throw new Exception(disco.Error);

    var tokenResponse = await client.RequestTokenAsync(new TokenRequest()
    {
        Address = disco.TokenEndpoint,
        GrantType = "delegation",
        ClientId = "api1",
        ClientSecret = "api1",
        Parameters =
        {
            {"scope" , "api2 email profile openid" },
            {"token", userToken }
        }
    });

    if (tokenResponse.IsError)
    {
        throw new Exception(tokenResponse.Error);
    }


    _logger.LogInformation($"new: {tokenResponse.AccessToken}");

    return tokenResponse.AccessToken;
}

IdentityServer4 DelegationGrantValidator:

public class DelegationGrantValidator : IExtensionGrantValidator
{
    private readonly ITokenValidator _validator;

    public DelegationGrantValidator(ITokenValidator validator)
    {
        _validator = validator;
    }

    public string GrantType => "delegation";

    public async Task ValidateAsync(ExtensionGrantValidationContext context)
    {
        var userToken = context.Request.Raw.Get("token");

        if (string.IsNullOrEmpty(userToken))
        {
            context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant);
            return;
        }

        var result = await _validator.ValidateAccessTokenAsync(userToken);
        if (result.IsError)
        {
            context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant);
            return;
        }

        // get user's identity
        var sub = result.Claims.FirstOrDefault(c => c.Type == "sub").Value;

        context.Result = new GrantValidationResult(sub, GrantType);
        return;
    }
}

в API1 User.Identity.Name = "Domain\UserName", но в API2 User.Identity.Name = null

есть что-нибудь не хватает, что я должен решить эту проблему?

PS: если я вызову конечную точку UserInfo IdentityServer из API2, я получу ожидаемое имя пользователя

1 Ответ

0 голосов
/ 09 февраля 2020

После долгих поисков я наконец нашел ответ.

Я следовал тому, что Рори Брэйбрук описал в этой статье , и теперь все работает

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...