我已经为客户端凭据和隐式流设置了身份服务器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);
它总是返回错误并总是返回结果吗?主体为空
答案 0 :(得分:0)
ChallengeAsync 在自定义授权验证器中使用时似乎无法正常工作。您可以使用自定义中间件来解决它:
public async Task Invoke(HttpContext httpContext)
{
if (!httpContext.User.Identity.IsAuthenticated)
{
await httpContext.ChallengeAsync("Windows");
}
else
{
await _next(httpContext);
}
}
这将在到达您的验证器之前强制进行身份验证,现在应该设置原则。