### Start KDC Server Listener Source: https://github.com/dotnet/kerberos.net/blob/develop/README.md Example of setting up and starting a KDC server listener. Requires configuration of listening endpoint, default realm, and realm service locator. ```csharp var port = 88; var options = new ListenerOptions { ListeningOn = new IPEndPoint(IPAddress.Loopback, port), DefaultRealm = "corp.identityintervention.com".ToUpper(), RealmLocator = realmName => new MyRealmService(realmName) }; var listener = new KdcServiceListener(options); await listener.Start(); ``` -------------------------------- ### Install Kerberos.NET Package Source: https://github.com/dotnet/kerberos.net/blob/develop/README.md Use this command to install the Kerberos.NET NuGet package into your project. ```powershell PM> Install-Package Kerberos.NET ``` -------------------------------- ### Generate Keytab File with ktpass Source: https://github.com/dotnet/kerberos.net/blob/develop/README.md Example command for generating a keytab file using the ktpass utility. This is used for storing Kerberos keys. ```bat ktpass /princ HTTP/test.identityintervention.com@IDENTITIYINTERVENTION.COM /mapuser IDENTITYINTER\server01$ /pass P@ssw0rd! /out sample.keytab /crypto all /PTYPE KRB5_NT_SRV_INST /mapop set ``` -------------------------------- ### Host In-Process KDC Server with KdcServiceListener Source: https://context7.com/dotnet/kerberos.net/llms.txt Start a Kerberos KDC server that listens on TCP/UDP port 88 or a custom port. Requires an implementation of IRealmService for principal lookups and key management. Configure logging and realm settings. ```csharp using Kerberos.NET.Server; using Kerberos.NET.Configuration; using Microsoft.Extensions.Logging; // IRealmService implementation provides principals and realm settings. // See FakeRealmService in Tests.Kerberos.NET for a complete in-memory example. var logFactory = LoggerFactory.Create(b => b.AddConsole().SetMinimumLevel(LogLevel.Trace)); var options = new ListenerOptions { Log = logFactory, DefaultRealm = "CORP.CONTOSO.COM", IsDebug = false, // RealmLocator maps incoming realm names to your IRealmService implementation RealmLocator = realm => new MyRealmService(realm) }; // Override the default port (88) for testing options.Configuration.KdcDefaults.KdcTcpListenEndpoints.Clear(); options.Configuration.KdcDefaults.KdcTcpListenEndpoints.Add("127.0.0.1:8888"); options.Configuration.KdcDefaults.ReceiveTimeout = TimeSpan.FromMinutes(10); using var listener = new KdcServiceListener(options); Console.WriteLine("KDC starting on 127.0.0.1:8888 ..."); await listener.Start(); // blocks until listener.Stop() / Dispose() ``` -------------------------------- ### Install Windows Server RSAT Source: https://github.com/dotnet/kerberos.net/blob/develop/README.md Command to install the Remote Server Administration Tools (RSAT) on a Windows server, which includes utilities like ktpass. ```powershell Add-WindowsFeature RSAT ``` -------------------------------- ### KerberosClient.GetServiceTicket with S4U2Self and S4U2Proxy Source: https://context7.com/dotnet/kerberos.net/llms.txt Demonstrates obtaining a service ticket using S4U2Self for constrained delegation, followed by S4U2Proxy to get a delegated service ticket. Requires prior authentication. ```csharp using Kerberos.NET.Client; using Kerberos.NET.Entities; // Authenticate first await client.Authenticate(new KerberosPasswordCredential("svc@CORP.CONTOSO.COM", "P@ssw0rd!")); // S4U2Self: get a ticket on behalf of another user var s4uSelf = await client.GetServiceTicket( "svc@CORP.CONTOSO.COM", ApOptions.MutualRequired, s4u: "alice@CORP.CONTOSO.COM" ); // S4U2Proxy: use the self-ticket to get a delegated service ticket var session = await client.GetServiceTicket( new RequestServiceTicket { ServicePrincipalName = "host/backend.corp.contoso.com", ApOptions = ApOptions.MutualRequired, S4uTicket = s4uSelf.Ticket // evidence ticket from S4U2Self } ); var apReq = session.ApReq; Console.WriteLine($"SPN: {apReq.Ticket.SName.FullyQualifiedName}"); // Output: SPN: host/backend.corp.contoso.com ``` -------------------------------- ### Example Kerberos Ticket Data Source: https://github.com/dotnet/kerberos.net/blob/develop/README.md This JSON structure represents sample data for a Kerberos ticket, including password bytes, principal name, and salt. ```json { "PasswordBytes": "jBBI1KL19X3olbCK/f9p/+cxZi3RnqqQRH4WawB4EzY=", "KeyPrincipalName": { "Realm": "CORP.IDENTITYINTERVENTION.COM", "Names": [ "STEVE-HOME" ], "NameType": "NT_SRV_HST", "FullyQualifiedName": "STEVE-HOME" }, "Salt": null } ] } } ``` -------------------------------- ### KeyTable Loading and Creation Source: https://context7.com/dotnet/kerberos.net/llms.txt Demonstrates loading service keys from a standard .keytab file or programmatically creating a KeyTable from known password and principal details. ```csharp using Kerberos.NET.Crypto; // Load from a keytab file var keytab = new KeyTable(File.ReadAllBytes("service.keytab")); // Or create programmatically from a known password var key = new KerberosKey( "ServiceP@ssw0rd!", principalName: new PrincipalName( PrincipalNameType.NT_SRV_INST, "CORP.CONTOSO.COM", new[] { "http", "myservice.corp.contoso.com" } ), etype: EncryptionType.AES256_CTS_HMAC_SHA1_96, saltType: SaltType.ActiveDirectoryService ); var keytabFromKey = new KeyTable(key); Console.WriteLine($"Entries: {keytabFromKey.Entries.Count}"); // Output: Entries: 1 ``` -------------------------------- ### Authenticate with Kerberos Client Source: https://github.com/dotnet/kerberos.net/blob/develop/README.md Demonstrates how to use the Kerberos client to authenticate credentials and obtain a service ticket. Ensure you have valid credentials and the target service principal name. ```csharp var client = new KerberosClient(); var kerbCred = new KerberosPasswordCredential("user@domain.com", "userP@ssw0rd!"); await client.Authenticate(kerbCred); var ticket = await client.GetServiceTicket("host/appservice.corp.identityintervention.com"); var header = "Negotiate " + Convert.ToBase64String(ticket.EncodeGssApi().ToArray()); ``` -------------------------------- ### Parse and Configure krb5.conf Source: https://context7.com/dotnet/kerberos.net/llms.txt Load Kerberos configuration from a standard krb5.conf string or programmatically modify settings. This is useful for setting default realms, KDC lookups, and encryption types. ```csharp using Kerberos.NET.Configuration; // Parse from a standard krb5.conf string var config = Krb5Config.Parse(@" [libdefaults] default_realm = CORP.CONTOSO.COM dns_lookup_kdc = false forwardable = true default_tkt_enctypes = aes256-cts-hmac-sha1-96 aes128-cts-hmac-sha1-96 [realms] CORP.CONTOSO.COM = { kdc = dc01.corp.contoso.com kdc = dc02.corp.contoso.com } [domain_realm] .corp.contoso.com = CORP.CONTOSO.COM corp.contoso.com = CORP.CONTOSO.COM"); var client = new KerberosClient(config); // Programmatic configuration client.Configuration.Defaults.DnsLookupKdc = false; client.Configuration.Realms["CORP.CONTOSO.COM"].Kdc.Add("dc03.corp.contoso.com"); // Serialize back to krb5.conf format Console.WriteLine(config.Serialize()); ``` -------------------------------- ### Implement Custom Redis-Backed Replay Validator Source: https://context7.com/dotnet/kerberos.net/llms.txt Replace the default in-memory replay cache with a distributed store like Redis for clustered environments. Implement the `ITicketReplayValidator` interface and inject it into `KerberosValidator`. ```csharp using Kerberos.NET; using Kerberos.NET.Crypto; public class RedisReplayValidator : ITicketReplayValidator { private readonly IDatabase _redis; public RedisReplayValidator(IDatabase redis) => _redis = redis; public async ValueTask Contains(TicketCacheEntry entry) { var key = $"krb:replay:{entry.Container}:{entry.Key}"; return await _redis.KeyExistsAsync(key); } public async ValueTask Add(TicketCacheEntry entry) { var key = $"krb:replay:{entry.Container}:{entry.Key}"; var ttl = entry.Expires - DateTimeOffset.UtcNow; return await _redis.StringSetAsync(key, "1", ttl, When.NotExists); } } // Wire it up var keytab = new KeyTable(File.ReadAllBytes("service.keytab")); var replayValidator = new RedisReplayValidator(redisDb); var validator = new KerberosValidator(keytab, replayValidator: replayValidator) { ValidateAfterDecrypt = ValidationActions.All }; var authenticator = new KerberosAuthenticator(validator); ``` -------------------------------- ### KerberosAsymmetricCredential for Certificate-Based (PKINIT) Authentication Source: https://context7.com/dotnet/kerberos.net/llms.txt Authenticates using an X.509 certificate with a private key for PKINIT. The username is optional and can be inferred from the certificate's SAN. ```csharp using System.Security.Cryptography.X509Certificates; using Kerberos.NET.Credentials; // Load certificate from the current user's personal store using var store = new X509Store(StoreName.My, StoreLocation.CurrentUser); store.Open(OpenFlags.ReadOnly); var certs = store.Certificates.Find( X509FindType.FindByThumbprint, "ABCDEF1234567890...", validOnly: false ); var cert = certs[0]; // must have HasPrivateKey == true // username is optionally a hint; if omitted it is pulled from the cert SAN var kerbCred = new KerberosAsymmetricCredential(cert, username: "alice@CORP.CONTOSO.COM"); ``` -------------------------------- ### OWIN/Katana Middleware for Kerberos Authentication Source: https://context7.com/dotnet/kerberos.net/llms.txt Integrate Kerberos.NET into an OWIN pipeline for ASP.NET Web API or MVC. This middleware handles the Authorization header and sets the request user. Requires a service.keytab file. ```csharp // Startup.cs using Owin; using Kerberos.NET; using Kerberos.NET.Crypto; using Microsoft.Owin; using System.Security.Claims; public class Startup { public void Configuration(IAppBuilder app) { app.Use(); app.UseWebApi(new HttpConfiguration()); } } public class KerberosMiddleware : OwinMiddleware { private readonly KerberosAuthenticator _authenticator; public KerberosMiddleware(OwinMiddleware next) : base(next) { var keytab = new KeyTable(File.ReadAllBytes("service.keytab")); _authenticator = new KerberosAuthenticator(keytab); } public override async Task Invoke(IOwinContext context) { if (!context.Request.Headers.ContainsKey("Authorization")) { context.Response.Headers.Add("WWW-Authenticate", new[] { "Negotiate" }); context.Response.StatusCode = 401; return; } try { var header = context.Request.Headers["Authorization"]; var identity = await _authenticator.Authenticate(header); context.Request.User = new ClaimsPrincipal(identity); } catch { context.Response.StatusCode = 403; return; } await Next.Invoke(context); } } ``` -------------------------------- ### Authenticate Kerberos Ticket with Authenticator Source: https://github.com/dotnet/kerberos.net/blob/develop/README.md Shows how to authenticate a Kerberos ticket using the KerberosAuthenticator. This requires a KeyTable file or KerberosKey for decryption and validation. ```csharp var authenticator = new KerberosAuthenticator(new KeyTable(File.ReadAllBytes("sample.keytab"))); var identity = authenticator.Authenticate("YIIHCAYGKwYBBQUCoIIG..."); Assert.IsNotNull(identity); var name = identity.Name; Assert.IsFalse(string.IsNullOrWhitespace(name)); ``` -------------------------------- ### KdcServiceListener Source: https://context7.com/dotnet/kerberos.net/llms.txt Hosts an in-process Kerberos KDC server that listens for AS-REQ and TGS-REQ messages. ```APIDOC ## KdcServiceListener — Host an in-process KDC server `KdcServiceListener` starts a full Kerberos KDC that listens for AS-REQ and TGS-REQ messages on TCP/UDP port 88 (or a custom port). The `IRealmService` interface must be implemented to provide principal lookups, long-term keys, and PAC generation. ```csharp using Kerberos.NET.Server; using Kerberos.NET.Configuration; using Microsoft.Extensions.Logging; // IRealmService implementation provides principals and realm settings. // See FakeRealmService in Tests.Kerberos.NET for a complete in-memory example. var logFactory = LoggerFactory.Create(b => b.AddConsole().SetMinimumLevel(LogLevel.Trace)); var options = new ListenerOptions { Log = logFactory, DefaultRealm = "CORP.CONTOSO.COM", IsDebug = false, // RealmLocator maps incoming realm names to your IRealmService implementation RealmLocator = realm => new MyRealmService(realm) }; // Override the default port (88) for testing options.Configuration.KdcDefaults.KdcTcpListenEndpoints.Clear(); options.Configuration.KdcDefaults.KdcTcpListenEndpoints.Add("127.0.0.1:8888"); options.Configuration.KdcDefaults.ReceiveTimeout = TimeSpan.FromMinutes(10); using var listener = new KdcServiceListener(options); Console.WriteLine("KDC starting on 127.0.0.1:8888 ..."); await listener.Start(); // blocks until listener.Stop() / Dispose() ``` ``` -------------------------------- ### OWIN/Katana Middleware Integration Source: https://context7.com/dotnet/kerberos.net/llms.txt Integrates Kerberos.NET into an OWIN pipeline for transparent Kerberos/Negotiate authentication in ASP.NET Web API or MVC applications. ```APIDOC ## OWIN/Katana Middleware Integration Kerberos.NET can be dropped into an OWIN pipeline as middleware to provide transparent Kerberos/Negotiate authentication for ASP.NET Web API or MVC applications. ```csharp // Startup.cs using Owin; using Kerberos.NET; using Kerberos.NET.Crypto; using Microsoft.Owin; using System.Security.Claims; public class Startup { public void Configuration(IAppBuilder app) { app.Use(); app.UseWebApi(new HttpConfiguration()); } } public class KerberosMiddleware : OwinMiddleware { private readonly KerberosAuthenticator _authenticator; public KerberosMiddleware(OwinMiddleware next) : base(next) { var keytab = new KeyTable(File.ReadAllBytes("service.keytab")); _authenticator = new KerberosAuthenticator(keytab); } public override async Task Invoke(IOwinContext context) { if (!context.Request.Headers.ContainsKey("Authorization")) { context.Response.Headers.Add("WWW-Authenticate", new[] { "Negotiate" }); context.Response.StatusCode = 401; return; } try { var header = context.Request.Headers["Authorization"]; var identity = await _authenticator.Authenticate(header); context.Request.User = new ClaimsPrincipal(identity); } catch { context.Response.StatusCode = 403; return; } await Next.Invoke(context); } } ``` ``` -------------------------------- ### Checkout and Rebase Develop Branch Source: https://github.com/dotnet/kerberos.net/blob/develop/CONTRIBUTING.md Switch to the develop branch and rebase it against the upstream develop branch to incorporate the latest changes. ```git git checkout develop git rebase upstream/develop ``` -------------------------------- ### KerberosAsymmetricCredential Source: https://context7.com/dotnet/kerberos.net/llms.txt `KerberosAsymmetricCredential` is used for authentication with X.509 certificates (PKINIT). The certificate must include a private key. The username is optional and can be inferred from the certificate's Subject Alternative Name (SAN). ```APIDOC ## KerberosAsymmetricCredential — Certificate-based (PKINIT) credential `KerberosAsymmetricCredential` authenticates using a user's X.509 certificate (PKINIT). The certificate must contain a private key. ```csharp using System.Security.Cryptography.X509Certificates; using Kerberos.NET.Credentials; // Load certificate from the current user's personal store using var store = new X509Store(StoreName.My, StoreLocation.CurrentUser); store.Open(OpenFlags.ReadOnly); var certs = store.Certificates.Find( X509FindType.FindByThumbprint, "ABCDEF1234567890...", validOnly: false ); var cert = certs[0]; // must have HasPrivateKey == true // username is optionally a hint; if omitted it is pulled from the cert SAN var kerbCred = new KerberosAsymmetricCredential(cert, username: "alice@CORP.CONTOSO.COM"); ``` ``` -------------------------------- ### KeyTable Source: https://context7.com/dotnet/kerberos.net/llms.txt Loads and uses keytab files for server-side decryption, providing the long-term service keys needed to decrypt incoming Kerberos tickets. ```APIDOC ## KeyTable — Load and use keytab files for server-side decryption `KeyTable` reads standard `.keytab` files (as generated by `ktpass`) and provides the long-term service keys needed to decrypt incoming Kerberos tickets. ```csharp using Kerberos.NET.Crypto; // Load from a keytab file var keytab = new KeyTable(File.ReadAllBytes("service.keytab")); // Or create programmatically from a known password var key = new KerberosKey( "ServiceP@ssw0rd!", principalName: new PrincipalName( PrincipalNameType.NT_SRV_INST, "CORP.CONTOSO.COM", new[] { "http", "myservice.corp.contoso.com" } ), etype: EncryptionType.AES256_CTS_HMAC_SHA1_96, saltType: SaltType.ActiveDirectoryService ); var keytabFromKey = new KeyTable(key); Console.WriteLine($"Entries: {keytabFromKey.Entries.Count}"); // Output: Entries: 1 ``` ``` -------------------------------- ### Checkout and Rebase Feature Branch Source: https://github.com/dotnet/kerberos.net/blob/develop/CONTRIBUTING.md Switch back to your feature branch and rebase it against the updated develop branch. Resolve any merge conflicts that arise. ```git git checkout your-branch git rebase develop ``` -------------------------------- ### KerberosClient for AS-REQ and TGS-REQ Source: https://context7.com/dotnet/kerberos.net/llms.txt Handles the client-side Kerberos flow, including AS-REQ (authentication and TGT) and TGS-REQ (service ticket requests). Supports various transports and ticket caching. ```csharp using Kerberos.NET.Client; using Kerberos.NET.Credentials; using Microsoft.Extensions.Logging; // Set up structured logging (optional) var logFactory = LoggerFactory.Create(b => { b.AddConsole(o => o.IncludeScopes = true); b.SetMinimumLevel(LogLevel.Information); }); var client = new KerberosClient(logger: logFactory); // Pin a specific KDC (skip DNS lookup) client.PinKdc("CORP.CONTOSO.COM", "dc01.corp.contoso.com"); var kerbCred = new KerberosPasswordCredential("alice@CORP.CONTOSO.COM", "P@ssw0rd!"); // AS-REQ: authenticate and obtain TGT await client.Authenticate(kerbCred); Console.WriteLine($"Authenticated as: {client.UserPrincipalName}"); // Output: Authenticated as: alice@corp.contoso.com // TGS-REQ: request a service ticket and get an AP-REQ (KRB_AP_REQ) var apReq = await client.GetServiceTicket("host/fileserver.corp.contoso.com"); // Encode as Base64 for use in an HTTP Negotiate header var negotiateHeader = "Negotiate " + Convert.ToBase64String(apReq.EncodeGssApi().ToArray()); Console.WriteLine(negotiateHeader); // Output: Negotiate YIIHCAYGKwYBBQUC... ``` -------------------------------- ### Configure File-Based Ticket Caching Source: https://context7.com/dotnet/kerberos.net/llms.txt Utilize a file-based ticket cache for persistence across process restarts. Ensure the correct cache type and name are configured, and set `CacheInMemory` to false. ```csharp using Kerberos.NET.Client; using Kerberos.NET.Configuration; // File-based krb5 ticket cache (standard MIT ccache v4 format) var config = Krb5Config.CurrentUser(); config.Defaults.DefaultCCacheName = "FILE:/tmp/krb5cc_alice"; config.Defaults.CCacheType = 4; // version 4 required var client = new KerberosClient(config) { CacheInMemory = false, // use the file cache CacheServiceTickets = true, RenewTickets = true, // auto-renew expiring TGTs RenewTicketsThreshold = TimeSpan.FromMinutes(20) }; await client.Authenticate(new KerberosPasswordCredential("alice@CORP.CONTOSO.COM", "P@ssw0rd!")); // On the next run the TGT is loaded from disk — no re-authentication needed // unless the ticket has expired beyond its renewable window. ``` -------------------------------- ### Push Feature Branch with Force Source: https://github.com/dotnet/kerberos.net/blob/develop/CONTRIBUTING.md Push your updated feature branch to your GitHub repository. Use `--force` to overwrite the remote branch with your local changes after rebasing. ```git git push origin your-branch --force ``` -------------------------------- ### KerberosClient.GetServiceTicket (full RequestServiceTicket overload) Source: https://context7.com/dotnet/kerberos.net/llms.txt Provides fine-grained control over TGS-REQ parameters, including S4U2Proxy (constrained delegation) and AP options, for obtaining service tickets. ```APIDOC ## KerberosClient.GetServiceTicket (full RequestServiceTicket overload) The `RequestServiceTicket` overload provides fine-grained control over TGS-REQ parameters, including S4U2Proxy (constrained delegation) and AP options. ```csharp using Kerberos.NET.Client; using Kerberos.NET.Entities; // Authenticate first await client.Authenticate(new KerberosPasswordCredential("svc@CORP.CONTOSO.COM", "P@ssw0rd!")); // S4U2Self: get a ticket on behalf of another user var s4uSelf = await client.GetServiceTicket( "svc@CORP.CONTOSO.COM", ApOptions.MutualRequired, s4u: "alice@CORP.CONTOSO.COM" ); // S4U2Proxy: use the self-ticket to get a delegated service ticket var session = await client.GetServiceTicket( new RequestServiceTicket { ServicePrincipalName = "host/backend.corp.contoso.com", ApOptions = ApOptions.MutualRequired, S4uTicket = s4uSelf.Ticket // evidence ticket from S4U2Self } ); var apReq = session.ApReq; Console.WriteLine($"SPN: {apReq.Ticket.SName.FullyQualifiedName}"); // Output: SPN: host/backend.corp.contoso.com ``` ``` -------------------------------- ### KerberosClient Source: https://context7.com/dotnet/kerberos.net/llms.txt `KerberosClient` manages the complete client-side Kerberos authentication process, including AS-REQ (to obtain a TGT) and TGS-REQ (to request service tickets). It supports various transports, ticket caching, and automatic ticket renewal. ```APIDOC ## KerberosClient — Kerberos client for AS-REQ and TGS-REQ `KerberosClient` handles the full client-side Kerberos flow: authenticating to a KDC (AS-REQ → TGT) and requesting service tickets (TGS-REQ). It supports TCP, UDP, and HTTPS (KDC Proxy) transports, ticket caching, and automatic ticket renewal. ```csharp using Kerberos.NET.Client; using Kerberos.NET.Credentials; using Microsoft.Extensions.Logging; // Set up structured logging (optional) var logFactory = LoggerFactory.Create(b => { b.AddConsole(o => o.IncludeScopes = true); b.SetMinimumLevel(LogLevel.Information); }); var client = new KerberosClient(logger: logFactory); // Pin a specific KDC (skip DNS lookup) client.PinKdc("CORP.CONTOSO.COM", "dc01.corp.contoso.com"); var kerbCred = new KerberosPasswordCredential("alice@CORP.CONTOSO.COM", "P@ssw0rd!"); // AS-REQ: authenticate and obtain TGT await client.Authenticate(kerbCred); Console.WriteLine($"Authenticated as: {client.UserPrincipalName}"); // Output: Authenticated as: alice@corp.contoso.com // TGS-REQ: request a service ticket and get an AP-REQ (KRB_AP_REQ) var apReq = await client.GetServiceTicket("host/fileserver.corp.contoso.com"); // Encode as Base64 for use in an HTTP Negotiate header var negotiateHeader = "Negotiate " + Convert.ToBase64String(apReq.EncodeGssApi().ToArray()); Console.WriteLine(negotiateHeader); // Output: Negotiate YIIHCAYGKwYBBQUC... ``` ``` -------------------------------- ### Fetch Upstream Changes Source: https://github.com/dotnet/kerberos.net/blob/develop/CONTRIBUTING.md Fetch changes from the mainstream repository before rebasing your branch. ```git git fetch upstream ``` -------------------------------- ### Register Custom Decryptor in C# Source: https://github.com/dotnet/kerberos.net/blob/develop/README.md Associates an EncryptionType with a Func<> that instantiates new decryptors. Useful for adding support for algorithms like DES. ```C# KerberosRequest.RegisterDecryptor( EncryptionType.DES_CBC_MD5, (token) => new DESMD5DecryptedData(token) ); ``` -------------------------------- ### KerberosPasswordCredential for Password-Based Authentication Source: https://context7.com/dotnet/kerberos.net/llms.txt Represents a username and password identity for the AS-REQ flow. The domain can be part of the username or provided separately. ```csharp using Kerberos.NET.Credentials; // Domain inferred from UPN suffix var cred = new KerberosPasswordCredential("user@CORP.CONTOSO.COM", "P@ssw0rd!"); // Domain supplied explicitly var cred2 = new KerberosPasswordCredential("administrator", "P@ssw0rd!", "CORP.CONTOSO.COM"); Console.WriteLine(cred.UserName); // "user" Console.WriteLine(cred.Domain); // "CORP.CONTOSO.COM" ``` -------------------------------- ### Register Custom Encryption Type Decryptor Source: https://context7.com/dotnet/kerberos.net/llms.txt Associate a custom or legacy encryption type (e.g., DES_CBC_MD5) with its corresponding decryptor factory function. This allows the validator to handle tickets encrypted with non-default algorithms. ```csharp using Kerberos.NET.Entities; using Kerberos.NET.Crypto; KerberosRequest.RegisterDecryptor( EncryptionType.DES_CBC_MD5, (token) => new DESMD5DecryptedData(token) ); // Once registered, the validator will automatically use the custom decryptor // when it encounters a ticket encrypted with DES_CBC_MD5. ``` -------------------------------- ### Kerberos Ticket JSON Output Source: https://github.com/dotnet/kerberos.net/blob/develop/README.md This JSON represents the intermediate, decoded structure of a Kerberos ticket. It includes details about the request, decrypted ticket components, and computed information. Use this to understand the raw data before it's rendered in a tree view. ```js { "Request": { "KrbApReq": { "ProtocolVersionNumber": 5, "MessageType": "KRB_AP_REQ", "ApOptions": "Reserved", "Ticket": { "TicketNumber": 5, "Realm": "CORP.IDENTITYINTERVENTION.COM", "SName": { "FullyQualifiedName": "desktop-h71o9uu", "IsServiceName": false, "Type": "NT_PRINCIPAL", "Name": [ "desktop-h71o9uu" ] }, "EncryptedPart": { "EType": "AES256_CTS_HMAC_SHA1_96", "KeyVersionNumber": 3, "Cipher": "Vo4uodU2...snip...XBwjmsshgyjs+Vr+A==" } }, "Authenticator": { "EType": "AES256_CTS_HMAC_SHA1_96", "KeyVersionNumber": null, "Cipher": "NnLmEFkmO3HXCS...snip...up0YmNW5AicQVvvk" } }, "KrbApRep": null }, "Decrypted": { "Options": "Reserved", "EType": "AES256_CTS_HMAC_SHA1_96", "SName": { "FullyQualifiedName": "desktop-h71o9uu", "IsServiceName": false, "Type": "NT_PRINCIPAL", "Name": [ "desktop-h71o9uu" ] }, "Authenticator": { "AuthenticatorVersionNumber": 5, "Realm": "CORP.IDENTITYINTERVENTION.COM", "CName": { "FullyQualifiedName": "jack", "IsServiceName": false, "Type": "NT_PRINCIPAL", "Name": [ "jack" ] }, "Checksum": { "Type": "32771", "Checksum": "EAAAAAAAAAAAAAAAAAAAAAAAAAA8QAAA" }, "CuSec": 305, "CTime": "2021-04-21T17:38:11+00:00", "Subkey": { "Usage": "Unknown", "EType": "AES256_CTS_HMAC_SHA1_96", "KeyValue": "nPIQrMQu/tpUV3dmeIJYjdUCnpg0sVDjFGHt8EK94EM=" }, "SequenceNumber": 404160760, "AuthorizationData": [ { "Type": "AdIfRelevant", "Data": "MIHTMD+gBAICAI2hNwQ1M...snip...BJAE8ATgAuAEMATwBNAA==" } ] }, "Ticket": { "Flags": [ "EncryptedPreAuthentication", "PreAuthenticated", "Renewable", "Forwardable" ], "Key": { "Usage": "Unknown", "EType": "AES256_CTS_HMAC_SHA1_96", "KeyValue": "gXZ5AIsNAdQSo/qdEzkfw3RrLhhypyuG+YcZwqdX9mk=" }, "CRealm": "CORP.IDENTITYINTERVENTION.COM", "CName": { "FullyQualifiedName": "jack", "IsServiceName": false, "Type": "NT_PRINCIPAL", "Name": [ "jack" ] }, "Transited": { "Type": "DomainX500Compress", "Contents": "" }, "AuthTime": "2021-04-21T17:24:53+00:00", "StartTime": "2021-04-21T17:38:11+00:00", "EndTime": "2021-04-22T03:24:53+00:00", "RenewTill": "2021-04-28T17:24:53+00:00", "CAddr": null, "AuthorizationData": [ { "Type": "AdIfRelevant", "Data": "MIIDIjCCAx6gBAICAIChg...snip...muoGI9Mcg0=" }, { "Type": "AdIfRelevant", "Data": "MF0wP6AEAgIAj...snip...AXg9hCAgAACTDBBAAAAAA=" } ] }, "DelegationTicket": null, "SessionKey": { "Usage": null, "EncryptionType": "AES256_CTS_HMAC_SHA1_96", "Host": null, "PrincipalName": null, "Version": null, "Salt": "", "Password": null, "IterationParameter": "", "PasswordBytes": "", "SaltFormat": "ActiveDirectoryService", "RequiresDerivation": false }, "Skew": "00:05:00" }, "Computed": { "Name": "jack@corp.identityintervention.com", "Restrictions": { "KerbAuthDataTokenRestrictions": [ { "RestrictionType": 0, "Restriction": { "Flags": "Full", "TokenIntegrityLevel": "High", "MachineId": "Txr82+sI2kbFmPnkrjldLUfESt/oJzLaWWNqCkOgC7I=" }, "Type": "KerbAuthDataTokenRestrictions" }, { "RestrictionType": 0, "Restriction": { "Flags": "Full", "TokenIntegrityLevel": "High", ``` -------------------------------- ### KerberosAuthenticator Source: https://context7.com/dotnet/kerberos.net/llms.txt Wraps KerberosValidator to convert a validated AP-REQ into a ClaimsIdentity. This is the primary server-side API for integrating with ASP.NET authentication pipelines. ```APIDOC ## KerberosAuthenticator — Validate a ticket and produce a ClaimsIdentity `KerberosAuthenticator` wraps `KerberosValidator` and converts a validated AP-REQ into a `ClaimsIdentity` populated with user SID, group memberships, UPN, display name, and PAC claims. This is the primary server-side API for integrating with ASP.NET authentication pipelines. ```csharp using Kerberos.NET; using Kerberos.NET.Crypto; using System.Security.Claims; var keytab = new KeyTable(File.ReadAllBytes("service.keytab")); var authenticator = new KerberosAuthenticator(keytab); // Accept "Negotiate " or raw base64 string authorizationHeader = "Negotiate YIIHCAYGKwYBBQUC..."; ClaimsIdentity identity; try { identity = await authenticator.Authenticate(authorizationHeader); } catch (Exception ex) { // 401 — ticket invalid or expired Console.Error.WriteLine($"Authentication failed: {ex.Message}"); return; } Console.WriteLine($"Authenticated: {identity.Name}"); // Output: Authenticated: alice@corp.contoso.com foreach (var claim in identity.Claims) { Console.WriteLine($" {claim.Type} = {claim.Value}"); } // Output (example): // http://schemas.xmlsoap.org/ws/2005/.../sid = S-1-5-21-...-1126 // http://schemas.xmlsoap.org/ws/2005/.../nameidentifier = alice@corp.contoso.com // http://schemas.xmlsoap.org/ws/2005/.../givenname = Alice Smith // http://schemas.microsoft.com/.../groupsid = S-1-5-21-...-513 // http://schemas.microsoft.com/.../role = Domain Users ``` ``` -------------------------------- ### KerberosValidator Source: https://context7.com/dotnet/kerberos.net/llms.txt Decrypts and validates an inbound Kerberos AP-REQ using a provided keytab, verifying the ticket and checking for replay attacks. ```APIDOC ## KerberosValidator — Decrypt and validate an inbound Kerberos AP-REQ `KerberosValidator` accepts raw bytes (from an Authorization header or SSPI token), decrypts the AP-REQ using the provided keytab, verifies the ticket, and checks for replay attacks. ```csharp using Kerberos.NET; using Kerberos.NET.Crypto; // Load the keytab for the target service var keytab = new KeyTable(File.ReadAllBytes("service.keytab")); var validator = new KerberosValidator(keytab) { // ValidationActions.All = Replay + Pac + TokenWindow checks (default) ValidateAfterDecrypt = ValidationActions.All }; // Raw AP-REQ bytes received over the wire byte[] apReqBytes = Convert.FromBase64String(incomingBase64Token); try { var decrypted = await validator.Validate(apReqBytes); Console.WriteLine($"Client: {decrypted.Ticket.CName.FullyQualifiedName}"); Console.WriteLine($"Service: {decrypted.SName.FullyQualifiedName}"); // Output: // Client: alice@CORP.CONTOSO.COM // Service: http/myservice.corp.contoso.com } catch (ReplayException) { Console.WriteLine("Replay attack detected — reject the request."); } catch (KerberosValidationException ex) { Console.WriteLine($"Ticket validation failed: {ex.Message}"); } ``` ``` -------------------------------- ### KerberosPasswordCredential Source: https://context7.com/dotnet/kerberos.net/llms.txt `KerberosPasswordCredential` represents a username and password identity for use in the AS-REQ flow. The domain can be part of the username (UPN format) or provided separately. ```APIDOC ## KerberosPasswordCredential — Password-based user credential `KerberosPasswordCredential` represents a username/password identity used during the AS-REQ flow. The domain can be embedded in the username (`user@DOMAIN.COM`) or supplied separately. ```csharp using Kerberos.NET.Credentials; // Domain inferred from UPN suffix var cred = new KerberosPasswordCredential("user@CORP.CONTOSO.COM", "P@ssw0rd!"); // Domain supplied explicitly var cred2 = new KerberosPasswordCredential("administrator", "P@ssw0rd!", "CORP.CONTOSO.COM"); Console.WriteLine(cred.UserName); // "user" Console.WriteLine(cred.Domain); // "CORP.CONTOSO.COM" ``` ``` -------------------------------- ### Validate AP-REQ with KerberosAuthenticator Source: https://context7.com/dotnet/kerberos.net/llms.txt Use KerberosAuthenticator to validate an AP-REQ ticket and generate a ClaimsIdentity. This is suitable for ASP.NET authentication pipelines. Ensure you have a valid service.keytab file. ```csharp using Kerberos.NET; using Kerberos.NET.Crypto; using System.Security.Claims; var keytab = new KeyTable(File.ReadAllBytes("service.keytab")); var authenticator = new KerberosAuthenticator(keytab); // Accept "Negotiate " or raw base64 string authorizationHeader = "Negotiate YIIHCAYGKwYBBQUC..."; ClaimsIdentity identity; try { identity = await authenticator.Authenticate(authorizationHeader); } catch (Exception ex) { // 401 — ticket invalid or expired Console.Error.WriteLine($"Authentication failed: {ex.Message}"); return; } Console.WriteLine($"Authenticated: {identity.Name}"); // Output: Authenticated: alice@corp.contoso.com foreach (var claim in identity.Claims) { Console.WriteLine($" {claim.Type} = {claim.Value}"); } // Output (example): // http://schemas.xmlsoap.org/ws/2005/.../sid = S-1-5-21-...-1126 // http://schemas.xmlsoap.org/ws/2005/.../nameidentifier = alice@corp.contoso.com // http://schemas.xmlsoap.org/ws/2005/.../givenname = Alice Smith // http://schemas.microsoft.com/.../groupsid = S-1-5-21-...-513 // http://schemas.microsoft.com/.../role = Domain Users ``` -------------------------------- ### KerberosValidator for AP-REQ Validation Source: https://context7.com/dotnet/kerberos.net/llms.txt Decrypts and validates an incoming Kerberos AP-REQ using a provided keytab. Configures validation actions and handles potential exceptions like replay attacks. ```csharp using Kerberos.NET; using Kerberos.NET.Crypto; // Load the keytab for the target service var keytab = new KeyTable(File.ReadAllBytes("service.keytab")); var validator = new KerberosValidator(keytab) { // ValidationActions.All = Replay + Pac + TokenWindow checks (default) ValidateAfterDecrypt = ValidationActions.All }; // Raw AP-REQ bytes received over the wire byte[] apReqBytes = Convert.FromBase64String(incomingBase64Token); try { var decrypted = await validator.Validate(apReqBytes); Console.WriteLine($"Client: {decrypted.Ticket.CName.FullyQualifiedName}"); Console.WriteLine($"Service: {decrypted.SName.FullyQualifiedName}"); // Output: // Client: alice@CORP.CONTOSO.COM // Service: http/myservice.corp.contoso.com } catch (ReplayException) { Console.WriteLine("Replay attack detected — reject the request."); } catch (KerberosValidationException ex) { Console.WriteLine($"Ticket validation failed: {ex.Message}"); } ``` -------------------------------- ### KerberosClient.ChangePassword Source: https://context7.com/dotnet/kerberos.net/llms.txt Changes the authenticated user's password using the RFC 3244 Kerberos password-change protocol. Ensure the provided credentials are valid. ```csharp using Kerberos.NET.Client; using Kerberos.NET.Credentials; var client = new KerberosClient(); var cred = new KerberosPasswordCredential("alice@CORP.CONTOSO.COM", "OldP@ssw0rd!"); try { await client.ChangePassword(cred, newPassword: "NewP@ssw0rd!"); Console.WriteLine("Password changed successfully."); } catch (Exception ex) { Console.WriteLine($"Password change failed: {ex.Message}"); } ``` -------------------------------- ### KerberosClient.ChangePassword Source: https://context7.com/dotnet/kerberos.net/llms.txt Changes the authenticated user's password using the RFC 3244 Kerberos password-change protocol (kadmin/changepw service). ```APIDOC ## KerberosClient.ChangePassword — Change a Kerberos principal's password Uses the RFC 3244 Kerberos password-change protocol (kadmin/changepw service) to change the authenticated user's password. ```csharp using Kerberos.NET.Client; using Kerberos.NET.Credentials; var client = new KerberosClient(); var cred = new KerberosPasswordCredential("alice@CORP.CONTOSO.COM", "OldP@ssw0rd!"); try { await client.ChangePassword(cred, newPassword: "NewP@ssw0rd!"); Console.WriteLine("Password changed successfully."); } catch (Exception ex) { Console.WriteLine($"Password change failed: {ex.Message}"); } ``` ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.