ASP.Net (Core) — , , . - — (ntlm, kerberos). , IIS, — , . , .Net Core, Linux Nginx, ? , IIS . , c . .Net Core 2.0-2.2. , 3 1. , .Net Core , , , , , .
Kerberos, , Wiki. Kerberos keytab Linux ( Windows, , ), , windows-.
, kerberos. , . , github , — Kerberos.NET ( nuget ). , . . 
ASP.NET Core, , Kerberos Cookies .
, , : Cookies, , . , , - Microsoft . 
Kerberos :
- web-
- Kerberos . *Web API* WWW-Authenticate Negotiate
- WWW-Authenticate Negotiate ,
- , Authorization Negotiate {Kerberos }
- Profit!
, . 
— . , :
public class MixedAuthenticationDefaults
{
    public const string AuthenticationScheme = "Mixed";
    public const string AuthorizationHeader = "Negotiate";
}
Mixed. WWW-Authenticate. 
— , . 
Web API :
[HttpGet("login")]
public async Task<IActionResult> External()
{
    return Challenge(new AuthenticationProperties(), MixedAuthenticationDefaults.AuthenticationScheme);
}
Challenge. , «» Web API . , - . Kerberos , , , OAuth redirect url. , , , . Kerberos.
, Kerberos.NET. 
public class KerberosAuthTicketValidator
{
    public async Task<ClaimsIdentity> IsValid(string ticket, string keytabPath)
    {
        if (!string.IsNullOrEmpty(keytabPath) || !string.IsNullOrEmpty(ticket))
            {
                var kerberosAuth = new KerberosAuthenticator(new KeyTable(File.ReadAllBytes(_kerberosConfiguration.KeytabPath)));
                var identity = await kerberosAuth.Authenticate(kerberosCredentials.Ticket);
                return identity;  
            }
        return null; 
    }
}
, KerberosAuthenticator.Authenticate() ClaimsIdentity, . - . , , github. 
— ( ) .
, Cookie Authentication. CookieAuthenticationHandler. :
public class MixedAuthenticationHandler : CookieAuthenticationHandler{}
, .. . , . 
:
protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
{
    var authResult = await base.HandleAuthenticateAsync(); 
    if (!authResult.Succeeded) 
        {
            string authorizationHeader = Request.Headers["Authorization"];
                if (string.IsNullOrEmpty(authorizationHeader))
                    {
                        return AuthenticateResult.Fail(” ”);
                    }
    
    var ticket = authorizationHeader.Substring(MixedAuthenticationDefaults.AuthorizationHeader.Length);
    
    var kerberosAuthTicketValidator = new KerberosAuthTicketValidator();
    var kerberosIdentity = await kerberosAuthTicketValidator.IsValid(new KerberosAuthorizeCredentials(ticket));
    if (kerberosIdentity != null)
        {
            
            var principal = new ClaimsPrincipal(kerberosIdentity);
            
            var authTicket= new AuthenticationTicket(principal, MixedAuthenticationDefaults.AuthenticationScheme);
                 if (ticket != null)
                    {
                        
                        await base.HandleSignInAsync(principal, ticket.Properties);
                        
                        return AuthenticateResult.Success(ticket);
                    }
        }
        }  
   return authResult;
}
HandleAuthenticateAsync() — . , . HandleChallengeAsync(). , Challenge(). . , redirect url oauth.
:
protected override Task HandleChallengeAsync(AuthenticationProperties properties)
{
    Response.StatusCode = 401; 
    Response.Headers.Append(HeaderNames.WWWAuthenticate, MixedAuthenticationDefaults.AuthorizationHeader);
    return Task.CompletedTask;
}
. , ,
public void ConfigureServices(IServiceCollection services)
{   
    .....
    
    services.AddAuthentication().AddCookie();
    ....
}
:
public static class MixedAuthenticationExtensions
{
   public static AuthenticationBuilder AddMixed(this AuthenticationBuilder builder)
   {
       builder.Services.TryAddEnumerable(ServiceDescriptor.Singleton<IPostConfigureOptions<CookieAuthenticationOptions>, PostConfigureCookieAuthenticationOptions>());
       return builder.AddScheme<CookieAuthenticationOptions, MixedAuthenticationHandler>(MixedAuthenticationDefaults.AuthenticationScheme, String.Empty, null);
   }
}
:
public void ConfigureServices(IServiceCollection services)
{   
    ...
    
    services.AddAuthentication(MixedAuthenticationDefaults.AuthenticationScheme).AddMixed();
    ...
}
. cookie — , , . , IAuthenticator, DI .