【问题标题】:Identity server 4 windows authentication using extension Grant not working使用扩展授权的身份服务器 4 Windows 身份验证不起作用
【发布时间】:2019-12-22 08:37:16
【问题描述】:

我已经为客户端凭据和隐式流设置了身份服务器 4,并且一切正常。现在我编写了一个扩展授权来支持 Windows 身份验证,但它总是在 ValidateAsync 方法中从 AuthenticateAsync 返回 false。

我的问题与本文IdentityServer4 Resource owner password and Win auth: unauthorized中提到的问题相同

但没有人回复该帖子

public class WinAuthGrantValidator : IExtensionGrantValidator
    {
        private readonly HttpContext _httpContext;
        private readonly IClientSecretValidator _clientValidator;

        public string GrantType => "CustomWindowsAuth";

        public WinAuthGrantValidator(IClientSecretValidator clientValidator,IHttpContextAccessor httpContextAccessor)
        {
            _httpContext = httpContextAccessor.HttpContext;
            _clientValidator = clientValidator;
        }

        public async Task ValidateAsync(ExtensionGrantValidationContext context)
        {
            // validate client
            var clientResult = await _clientValidator.ValidateAsync(_httpContext);
            if (clientResult.Client == null)
            {
               // _httpContext.Response.StatusCode = 401;
                context.Result = new GrantValidationResult(TokenRequestErrors.InvalidClient);
                return;
            }

            var result = await _httpContext.AuthenticateAsync(AccountOptions.WindowsAuthenticationSchemeName);
            if (result?.Principal is WindowsPrincipal wp)
            {
                var roles = wp.Claims.ToList();

                var id = new ClaimsIdentity(AccountOptions.WindowsAuthenticationSchemeName);
                id.AddClaim(new Claim(JwtClaimTypes.Subject, wp.Identity.Name));
                id.AddClaim(new Claim(JwtClaimTypes.Name, wp.Identity.Name));
                if (AccountOptions.IncludeWindowsGroups)
                {
                    var wi = wp.Identity as WindowsIdentity;
                    var groups = wi?.Groups?.Translate(typeof(NTAccount),false);
                    if (groups != null)
                    {
                        roles = groups.Select(x => new Claim(JwtClaimTypes.Role, x.Value)).ToList();
                        id.AddClaims(roles);
                    }
                }
                context.Result = new GrantValidationResult(wp.Identity.Name, GrantType, roles);

            }
            else
            {

                await _httpContext.ChallengeAsync(AccountOptions.WindowsAuthenticationSchemeName);
                context.Result = new GrantValidationResult(TokenRequestErrors.UnauthorizedClient, "Invalid credential");
            }
        }
    }

这是上面的身份服务器注册

services.Configure<IISOptions>(iis =>
            {
                iis.AuthenticationDisplayName = "Windows";
                iis.AutomaticAuthentication = false;
            });

  var builder = services.AddIdentityServer(options =>
                {

                    options.Events.RaiseErrorEvents = true;
                    options.Events.RaiseInformationEvents = true;
                    options.Events.RaiseFailureEvents = true;
                    options.Events.RaiseSuccessEvents = true;
                })
                .AddSigningCredential(Certificate.Certificate.LoadCertificateFromStore(thumbPrint, logger))
                .AddAspNetIdentity<TUserIdentity>()
                .AddIdentityServerStoresWithDbContexts<TConfigurationDbContext, TPersistedGrantDbContext>(configuration)
                 .AddExtensionGrantValidator<WinAuthGrantValidator>()
                .AddProfileService<CustomProfileService>();

这是来自客户端的代码

var client = new HttpClient(new HttpClientHandler
    {
        UseDefaultCredentials = true
    });

    var disco = await client.GetDiscoveryDocumentAsync(new DiscoveryDocumentRequest
    {
        Address = "http://marsdevhv020.identity.marsdev.co.nz",
        Policy =
        {
            RequireHttps = false
        }
    });

    var tokenResponse = await client.RequestTokenAsync(new TokenRequest
    {
        Address = disco.TokenEndpoint,
        GrantType = "CustomWindowsAuth",
        ClientId = "WindowsClient",
        ClientSecret = "WindowsClientSecret",
        Parameters =
        {
            { "scope", "TestApi.Read" }
        }
    });


    if (tokenResponse.IsError)
    {
        Console.WriteLine(tokenResponse.Error);
        Console.WriteLine("Press any key to exit!");
        Console.Read();
    }

    Console.WriteLine(tokenResponse.AccessToken);

它总是像往常一样返回错误结果?.Principal 为 null

【问题讨论】:

  • 错误是什么?这还不足以帮助您。
  • 你好 如前所述,当执行 Httpcontext.AuthenticateAsync 时,result.Principal 始终为空,因为 Windows 凭据从控制台客户端正确传递。如果它正确地对 Windows 进行身份验证,我会期望来自身份验证方法的 Windows 主体.. 这能更好地解释我遇到的问题吗?

标签: c# asp.net-core identityserver4


【解决方案1】:

在自定义授权验证器中使用时,ChallengeAsync 似乎无法正常工作。您可以使用自定义中间件绕过它:

        public async Task Invoke(HttpContext httpContext)
        {
            if (!httpContext.User.Identity.IsAuthenticated)
            {
                await httpContext.ChallengeAsync("Windows");
            }
            else
            {
                 await _next(httpContext);
            }
        }

这将在到达您的验证器之前强制进行身份验证,现在应该设置原则。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-11-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-28
    • 1970-01-01
    • 1970-01-01
    • 2013-08-26
    相关资源
    最近更新 更多