Question
I need implement Windows authentication on Ubuntu (kerberos) with IdentityServer4.
I took IdentityServer host project.
I added handler AddNegotaite to Startup:
services.AddAuthentication(NegotiateDefaults.AuthenticationScheme)
.AddNegotiate();
And created WindowsController with [Authorize] attribute:
[Authorize]
public class WindowsController: Controller
{
[HttpGet]
public async Task<IActionResult> Challenge(string returnUrl)
{
return await ChallengeWindowsAsync(returnUrl);
}
private async Task<IActionResult> ChallengeWindowsAsync(string returnUrl)
{
var wp = HttpContext.User;
var props = new AuthenticationProperties
{
RedirectUri = Url.Action("Callback", "External"),
Items =
{
{ "returnUrl", returnUrl },
{ "scheme", "Negotiate" }
}
};
var id = new ClaimsIdentity("Negotiate");
// the sid is a good sub value
id.AddClaim(new Claim(JwtClaimTypes.Subject, wp.FindFirst(ClaimTypes.PrimarySid).Value));
// the account name is the closest we have to a display name
id.AddClaim(new Claim(JwtClaimTypes.Name, wp.Identity.Name));
// add the groups as claims -- be careful if the number of groups is too large
var wi = wp.Identity as WindowsIdentity;
// translate group SIDs to display names
var groups = wi.Groups.Translate(typeof(NTAccount));
var roles = groups.Select(x => new Claim(JwtClaimTypes.Role, x.Value));
id.AddClaims(roles);
await HttpContext.SignInAsync(
IdentityServerConstants.ExternalCookieAuthenticationScheme,
new ClaimsPrincipal(id),
props);
return Redirect(props.RedirectUri);
}
}
After Windows sign in page redirect to External/Callback. And authentication crash in Callback method on this line:
await HttpContext.SignInAsync(isuser, localSignInProps);
with error:
InvalidOperationException: sub claim is missing IdentityServer4.Extensions.PrincipalExtensions.GetSubjectId(IIdentity identity) in PrincipalExtensions.cs, line 81
It crashes because IdentityServer tries create session and crash when it tries get sub claim from WindowsIdentity. But WindowsIdentity has not this claim.
How to fix it? I did not find any solution IdentityServer4 + AddNegotiate.
My sample project: WinAuth.zip
Need to go: http://localhost:5002/External/Callback
I guess identityserver cannot create session with
services.AddAuthentication(NegotiateDefaults.AuthenticationScheme)
.AddNegotiate();
Solutuion:
In startup:
services.AddAuthentication()
.AddNegotiate();
And I changed [Authorize] attribute to
[Authorize(AuthenticationSchemes = NegotiateDefaults.AuthenticationScheme)]