Kerberos.NET icon indicating copy to clipboard operation
Kerberos.NET copied to clipboard

How best to use this package for client access

Open RussKahler1970 opened this issue 2 years ago • 7 comments

I am working on building an integration between two environments and will be making a lot of HttpClient Posts to a legacy IIS site internal in our network that is running windows authentication. In testing below is a sample of my code I used to test getting a Kerberos ticket and attaching it to my HttpClient as an Auth header. this works. I am working from a linux container not running in our domian so I need to set authentication into my HttpClient to authenticate into the site.

            var apiHost = "http://[internal web server]";
            Guard.Against.NullOrEmpty(apiHost);
            var hostUri = new Uri(apiHost);
            using var client= ClientFactory.CreateClient("[Facotry client name]");
            client.BaseAddress = hostUri;

            DnsQuery.RegisterImplementation(new PlatformIndependentDnsClient());

            using var kClient = new KerberosClient();
            var kerbCred = new KerberosPasswordCredential("[Account]", "[Password]", "[]Domain");

            await kClient.Authenticate(kerbCred);

            var ticket = await kClient.GetServiceTicket($"http/{hostUri.Host}");

            client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Negotiate", Convert.ToBase64String(ticket.EncodeGssApi().ToArray()));

            var apiPath= "[Path to App]";

            string inputJson = Newtonsoft.Json.JsonConvert.SerializeObject(GetEvent());
            HttpContent inputContent = new StringContent(inputJson, System.Text.Encoding.UTF8, "application/json");
     
            var apiResponse = await client.PostAsync(apiPath, inputContent);
            apiResponse.EnsureSuccessStatusCode();

I am wonder if there are some ideas to make it perform with high volume of calls coming through? Is there a cache I should use? Do I make singleton to provide the token and only refresh it as needed? I guess any ideas you have to use this logic in a high volume (using the same account ) environment would be greatly appreciated.

RussKahler1970 avatar Dec 05 '23 14:12 RussKahler1970

There are a handful of knobs you can use to make it work well.

  • KerberosClient is per-user meaning that if you only ever have a single identity for the lifetime of the app, you can make the client static. Internal TCP stacks use pooled resources to make this cheap.
  • The expensive operation in Kerberos is getting the TGT. That occurs on the call to Authenticate(cred).
  • The TGT is cached in memory by default for the lifetime of the KerberosClient. This can be persisted to disk using the Krb5TicketCache class.
  • TGTs do not refresh automatically. You can set that on individual clients with client.RenewTickets = true.
  • Services tickets are also cached in the same cache as the TGT. GetServiceTicket is expensive for the first call for each SPN, but additional calls are cheap.
  • Always call GetServiceTicket for every request. This generates a new authenticator for each request, but doesn't reach out to the DC. The server app receiving the AP-REQ needs a new authenticator for each request otherwise it will drop it as a replay.

Otherwise, I think it's just a matter of profiling and monitoring where things are running poorly.

SteveSyfuhs avatar Dec 05 '23 17:12 SteveSyfuhs

thanks for the info. So if I set the client to RenewTickets will it handle the renewal of the TGT when it needs to?

Since its caching for the lifetime of the client if I maintain a client for the lifetime of my app will each call to Authenticate(cred) just get from the cache as it finds tickets and renew when it needs to? Or do I just call authenticate once and then just call GetServiceTicket which will deal with authenication renewal if it needs to?

Thanks again for all your help with this.

RussKahler1970 avatar Dec 05 '23 23:12 RussKahler1970

TGT will renew as it nears expiration. Service tickets will not. That's another reason to keep calling GetServiceTicket.

Avoid calling Authenticate repeatedly. It will always get a new TGT. You will find that on extremely long-running app lifetimes, the TGT will expire after it has run out of renewals. That will require a reauth.


From: RussKahler1970 @.> Sent: Tuesday, December 5, 2023 3:10:38 PM To: dotnet/Kerberos.NET @.> Cc: Comment @.>; Subscribed @.> Subject: Re: [dotnet/Kerberos.NET] How best to use this package for client access (Issue #363)

thanks for the info. So if I set the client to RenewTickets will it handle the renewal of the TGT when it needs to?

Since its caching for the lifetime of the client if I maintain a client for the lifetime of my app will each call to Authenticate(cred) just get from the cache as it finds tickets and renew when it needs to? Or do I just call authenticate once and then just call GetServiceTicket which will deal with authenication renewal if it needs to?

Thanks again for all your help with this.

— Reply to this email directly, view it on GitHubhttps://github.com/dotnet/Kerberos.NET/issues/363#issuecomment-1841774862 or unsubscribehttps://github.com/notifications/unsubscribe-auth/AAJHTYIRW4MYKA3GPKPDS5TYH6SW5BFKMF2HI4TJMJ2XIZLTSSBKK5TBNR2WLJDUOJ2WLJDOMFWWLO3UNBZGKYLEL5YGC4TUNFRWS4DBNZ2F6YLDORUXM2LUPGBKK5TBNR2WLJDUOJ2WLJDOMFWWLLTXMF2GG2C7MFRXI2LWNF2HTAVFOZQWY5LFUVUXG43VMWSG4YLNMWVXI2DSMVQWIX3UPFYGLAVFOZQWY5LFVE2TMNBSG4ZDGNJXURXGC3LFVFUGC427NRQWEZLMVRZXKYTKMVRXIX3UPFYGLLCJONZXKZKDN5WW2ZLOOSTHI33QNFRXHE4CUR2HS4DFVJZGK4DPONUXI33SPGSXMYLMOVS2QOBVGQ4DSMJTHCBKI5DZOBS2K2LTON2WLJLWMFWHKZNKGIYDENRUGA3DAMJWQKSHI6LQMWSWYYLCMVWKK5TBNR2WLKJVGY2DENZSGM2TPJ3UOJUWOZ3FOKTGG4TFMF2GK. You are receiving this email because you commented on the thread.

Triage notifications on the go with GitHub Mobile for iOShttps://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Androidhttps://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.

SteveSyfuhs avatar Dec 06 '23 03:12 SteveSyfuhs

Sounds good, so should I reauthenticate daily? would that be often enough? Or should I do it more frequent?

RussKahler1970 avatar Dec 06 '23 13:12 RussKahler1970

Whenever you get an exception from GetServiceTicket telling you to.


From: RussKahler1970 @.> Sent: Wednesday, December 6, 2023 5:12:13 AM To: dotnet/Kerberos.NET @.> Cc: Comment @.>; Subscribed @.> Subject: Re: [dotnet/Kerberos.NET] How best to use this package for client access (Issue #363)

Sounds good, so should I reauthenticate daily? would that be often enough? Or should I do it more frequent?

— Reply to this email directly, view it on GitHubhttps://github.com/dotnet/Kerberos.NET/issues/363#issuecomment-1842851990 or unsubscribehttps://github.com/notifications/unsubscribe-auth/AAJHTYO4FOXUZSDJEY7HBTDYIBVK5BFKMF2HI4TJMJ2XIZLTSSBKK5TBNR2WLJDUOJ2WLJDOMFWWLO3UNBZGKYLEL5YGC4TUNFRWS4DBNZ2F6YLDORUXM2LUPGBKK5TBNR2WLJDUOJ2WLJDOMFWWLLTXMF2GG2C7MFRXI2LWNF2HTAVFOZQWY5LFUVUXG43VMWSG4YLNMWVXI2DSMVQWIX3UPFYGLAVFOZQWY5LFVE2TMNBSG4ZDGNJXURXGC3LFVFUGC427NRQWEZLMVRZXKYTKMVRXIX3UPFYGLLCJONZXKZKDN5WW2ZLOOSTHI33QNFRXHE4CUR2HS4DFVJZGK4DPONUXI33SPGSXMYLMOVS2QOBVGQ4DSMJTHCBKI5DZOBS2K2LTON2WLJLWMFWHKZNKGIYDENRUGA3DAMJWQKSHI6LQMWSWYYLCMVWKK5TBNR2WLKJVGY2DENZSGM2TPJ3UOJUWOZ3FOKTGG4TFMF2GK. You are receiving this email because you commented on the thread.

Triage notifications on the go with GitHub Mobile for iOShttps://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Androidhttps://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.

SteveSyfuhs avatar Dec 06 '23 16:12 SteveSyfuhs

Should I do it on any exception or is there a typed exception I should react to?

RussKahler1970 avatar Dec 06 '23 16:12 RussKahler1970

Specifically the call to GetServiceticket will throw an exception InvalidOperationException("Cannot request a service ticket until a user is authenticated"). I would avoid doing it on all exceptions, as you could also potentially see networking or name resolution failures due to environmental issues here as well under different exception types.

SteveSyfuhs avatar Dec 06 '23 17:12 SteveSyfuhs