Showing posts with label Authentication. Show all posts
Showing posts with label Authentication. Show all posts

Friday, February 16, 2018

Kerberos authentication

I finally had a chance to look into this subject rather thoroughly, till having arrived to a certain result. Though in the end, I decided to not to use it, and pursued a different solution to implement the requirement in hand.

First of all, why Kerberos?

In the previous post, I wrote about SharePoint .NET client object model. I looked at it, in order to implement an ASP.NET web app, which allows the users to perform operations such as creation of a document library, on a remote SharePoint. The SharePoint is of “on-premises”. We are not yet on Office 365. Everybody cannot create the document libraries, of course. The users logon to the web app. And only those who are authorized (granted the permission at the SharePoint site) can. Yes, it is the famous “authentication double hop”, or whatever else you may call it, scenario.

To date, in our environment, “Windows authentication” = NTLM. Nowhere Kerberos is used, as far as my knowledge goes. But, it is known that the web server cannot pass to another server, the user credential that it acquires with NTLM authentication. In a scenario such as the above, you need to implement the “Kerberos delegation”.

I was new to Kerberos, leant it only on the university textbook many years ago, so started with some reading of blog posts such as this one: https://blogs.technet.microsoft.com/askds/2008/03/06/kerberos-for-the-busy-admin/. I read it now once again. Still not so easy to read. But in short, this is how I understand it works.

When you choose the “Windows Authentication” for the web app on the IIS Manager, since it comes first in the list, when the client such as Internet Explorer accesses the app and receives the 401 challenge response, it goes to the domain controller and see if the corresponding SPN (Service Principal Name), HTTP/the_web_server in this case, exists.

winowsauthproviders

In case the SPN does exists, under the account (machine or domain) that indeed runs the service, the IIS worker process in this case, your authentication against the web app with Kerberos should succeed.

In short, the key to the success is as simple as registering the correct SPN with the correct account.

1. Service Principal Name

It looks something like HTTP/the_web_server. The first part is called “service class”, and HTTP for web access which uses the default port 80. The same “HTTP” for https (433) as well.

Then the second portion is the name of the web server. This is a bit tricky. This documentation by Microsoft support reads that in case a hostname based virtual web site is in use, the hostname should be registered with the SPN. What I found is different though. It is always the server’s BIOS name, or the machine name that the IE always looks for to the domain controller. And actually, due to this fact, I decided to not to go for this solution. I would like to talk about it later in more detail.

2. The account running the service

When you register or add a SPN, you issue the command like follows on the domain controller.

CMD> setspn –a SPN account_running_the_service

The Kerberos ticket the client gets from the domain controller and then submits to the web server is encrypted using the account specified, its password hash. The web server, the IIS worker process to be more precise, decrypts the ticket submitted with the password hash of the account who runs the process. Therefore, this is imperative that you register the SPN with the account that runs your web app.

However, in the case of IIS, things are a little more complicated.

winowsauthadvancedsettings

This is the advanced settings of the windows authentication. It reads that by default the so-called kernel-mode authentication is used. What is kernel-mode authentication? How it changes the behavior?

When the kernel-mode authentication is used, it is always the machine account, something like the machine BIOS name followed by a $ sign, is used to decrypt the tickets, not the custom identity specified for the application pool, that is the worker process. So, if you, without knowing it, register the SPN with the custom identity of the application pool, the authentication fails, with the KRB_AP_ERR_MODIFIED error. By the way, this error you find in the client Event Viewer is super cryptic. I “decrypted” it, thanks to this blog post.

Abandoned nevertheless. Why?

Our organization aggregates many web services under one single hostname, or a domain name; ourorganization.org. You access one such web service at its URL ourorganization.org/webservice1, another at ourorganization.org/webservice2 and so on.

In such an environment, image that I register the SPN for my web app, which is accessed as ourorganization.org/mywebapp just like all the others, as HTTP/ourorganization.org with the custom identity of the application pool that runs the app.

What happened was that for all other web services to which the Windows authentication is chosen, the authentication had started failing!! For none of them, Kerberos is intended to use, but it is there as the first choice by default!! And the kernel-mode authentication is chosen, again not by intention, but by default!! And the authentication fails because they cannot decrypt the Kerberos tickets encrypted using my custom identity. So I retreated. Too heavy side-effects...

Other references:

Tuesday, July 2, 2013

WSS_KeepSessionAuthenticated

As becoming the de-fact, when asking users to authenticate, we change i.e. redirect to SSL. But then, if he/she opens another browser window and comes to us on http, to view two pages from our site simultaneously, on the second windows, he/she goes back anonymous. He/She has authenticated on the SSL i.e. https session, but not on http.

We first implemented this mechanism on SharePoint 2007. We may have wanted to redirect the second session to SSL so that the user finds himself logged-in on both windows. But due to some technical constraint not really of SharePoint, it was not that straightforward.

Anyway, this is how we started.

Then, when upgraded to 2010, we saw that the user is asked for username/password on the second session, even though the page that he is trying to open is anonymously accessible. After some research, we found out that this seems due to the WSS_KeepSessionAuthenticated cookie, that is sent. SharePoint forces the user to authenticate when it finds the cookie in the request.

To overcome, we created and hooked up a HttpModule to clear it at the beginning of the request made on http. It is an acceptable workaround for us, because we do not ask users to send their passwords as clear text.

Today, I found out that it is no longer needed with SharePoint 2013. The problem was that with SP2010, the cookie was set as non-secure. It is set when the user authenticates, and sent back to the server whether the session is secure or not. While with SP2013, it is set as secure when authenticated on https, and is sent back only when the communication is secured i.e. on SSL.