Identityserver4 具有Windows身份验证User.Identity.Name的IdentityServer 4委派为null

Identityserver4 具有Windows身份验证User.Identity.Name的IdentityServer 4委派为null,identityserver4,windows-authentication,asp.net-core-3.1,Identityserver4,Windows Authentication,Asp.net Core 3.1,我有以下流程Asp.Net核心应用程序(App),它调用Asp.Net核心Web API(API1),inturn调用另一个Asp.Net Web API(API2) 我正在使用IdentityServer4和Windows身份验证来验证我的用户 这是我的密码: 资源定义: new ApiResource("api1", "api1", new List<string> { JwtClaimTypes.Name, JwtClaimTypes.Email}), new ApiReso

我有以下流程Asp.Net核心应用程序(App),它调用Asp.Net核心Web API(API1),inturn调用另一个Asp.Net Web API(API2)

我正在使用IdentityServer4和Windows身份验证来验证我的用户 这是我的密码:

资源定义:

new ApiResource("api1", "api1", new List<string> {  JwtClaimTypes.Name, JwtClaimTypes.Email}),
new ApiResource("api2", "api2", new List<string> {  JwtClaimTypes.Name, JwtClaimTypes.Email})
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;
}
在API1中
User.Identity.Name=“域\用户名”
但在API2中,User.Identity.Name=null

我应该做些什么来解决这个问题


注意:如果我从API2调用IdentityServer UserInfo端点,经过大量搜索,我最终找到了答案,我将得到预期的用户名

我遵循了Rory Braybrook在中的描述,现在一切正常

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;
}
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;
    }
}