Transparente Authentifizierung in ASP.Net Core unter Linux


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 :


  1. web-
  2. Kerberos . *Web API* WWW-Authenticate Negotiate
  3. WWW-Authenticate Negotiate ,
  4. , Authorization Negotiate {Kerberos }
  5. 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(” ”);
                    }

    //  ,        -    “Negotiate”. //  

    var ticket = authorizationHeader.Substring(MixedAuthenticationDefaults.AuthorizationHeader.Length);
    //       
    var kerberosAuthTicketValidator = new KerberosAuthTicketValidator();
    var kerberosIdentity = await kerberosAuthTicketValidator.IsValid(new KerberosAuthorizeCredentials(ticket));
    if (kerberosIdentity != null)
        {
            // ClaimsPrincipal
            var principal = new ClaimsPrincipal(kerberosIdentity);
            //  
            var authTicket= new AuthenticationTicket(principal, MixedAuthenticationDefaults.AuthenticationScheme);
                 if (ticket != null)
                    {
                        // ,    ,       cookie 
                        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; //  “Unauthorized”
    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 .


All Articles