Showing posts with label IIS. Show all posts
Showing posts with label IIS. Show all posts

Friday, December 2, 2011

Authentication Types and Authentication Providers - SharePoint and IIS

I have been having an interesting discussion with my client that has nearly caused my head to explode. The discussion centers around Negotiate, Kerberos, NTLM, IIS, and SharePoint.

A little background first. The client wanted to set up a SharePoint site that could be accessed both by Kerberos and NTLM. SharePoint 2010 only allows for a singe Windows Authentication per zone, so you need to set up two zones for a single web application. One that is configured for Kerberos, and one that is configured for NTLM. Pretty straight forward stuff.
I created a Web Application diagram detailing out the need for these two zones, and was called out by my client. He remarked that if you set your Web Application up for "Negotiate" you can use both Kerberos and NTLM, so the extra zone is not needed.
Wait... What?? Negotiate uses both NTLM and Kerberos?? Eh?? My world had just turned upside down. Kerberos and NTLM are mutually exclusive authentication methods, and can not be mixed together. You are using NTLM, or you are using Kerberos, there is nothing in between. This is evident in Central Administration by having to select either NTLM or Kerberos as your Windows Authentication.

So what is NTLM and Kerberos? Why don't they work together? Well, Kerberos is a token based authentication method that requires all parties involved to be registered with Active Directory, and trusted to use Kerberos. I like to call this connection to AD the Kerberos chain. Why? Well, because everything is registered and trusted in AD, special things can happen. Once a user is authenticated, servers and applications can use that user credential for many authentications. Thus Kerberos can make multiple "hops" without having to re-authenticate the user. It makes a "chain" of authentication.
It works like this... The user attempts to connect to a web site that uses a database back end. The web site is secured with Kerberos. The user is first prompted for their credentials, and authenticated by AD. The user is issued a "token" by the authenticating Domain Controller, called the Kerberos Domain Controller (KDC).
The web site then makes a call to the back end database. The database asks who wants the data, and the web server responds with the user's token. The database says well, the user is trusted by the KDC, the Web server is trusted by the KDC, the web site is trusted by the KDC, I'm trusted by the KDC, and since I trust the KDC, I will send the user the data requested. Everything is chained together by AD, thus the Kerberos chain.
As you can imagine, Kerberos takes some configuration... This can be the tricky part, because all pieces of the puzzle need to be included in AD. That means that the SQL instances and DNS aliases used in IIS need to be registered with Security Principal Names. All servers that host the SQL and IIS instances need to be trusted for delegation in AD. And all users involved need to have their SPNs as well. By default, users get an SPN when they are created in Active Directory Users and Computers, but servers are not trusted for delegation by default.
Here is a GREAT whitepaper on how to configure Kerberos for SharePoint.
NTLM is a simple challenge response authentication method that only requires the user to be registered in AD. Because of this, NTLM can not make the multiple security hops that Kerberos can make. So for each additional hop that is required by the application, the user will need to re-authenticate, or some other trusted credential needs to be used.

Getting back to the story... As you can imagine, the situation set off a flurry of emails, me trying to explain that you cannot do such a thing, and the client insisting on he has done this impossibility in his test environment. So, like my Physics professors told me many years ago, when things don't make sense, go back to the scientific method. I didn't do that...
Instead of having my client describe his environment in excruciating detail, I tried to come up with ways in which he could be thinking NTLM and Kerberos could be working in concert. I asked him if he was talking about his IIS settings, which could indeed be set to be open to using Kerberos and NTLM.

Back in the good old days of the IIS Metabase, there was a property called NtAuthenticationProviders. You could use this property to explicitly state which Windows authentication method you wanted to use. In the IIS 6 days, if you wanted to use Kerberos, you needed to make sure that the "Negotiate" value was set. If you wanted to use both, you set the property to Negotiate,NTLM. (If you want to know more about setting this property in IIS 5 and 6 click the link.)
In IIS 7 Microsoft changed IIS fundamentally. Instead of the proprietary Metabase, an XML file is used for configuration. This file is found by default in the ApplicationHost.config file at %SYSTEMROOT%\system32\inetsrv\config.
In that file there is a property called windowsAuthentication, and under that property is the providers property. In that area you can see the values for Negotiate and NTLM. (If you want to know more about setting this property in IIS 7 and 7.5 click the link.)

This is where things can get tricky... SharePoint is nothing more than an IIS hosted .NET application. IIS is a service on the Windows server platform. Windows, by default, uses Kerberos as its authentication method. Therefore, if your Kerberos chain is configured (all servers trusted for delegation and SPNs for all DNS aliases, SQL instances, as well as users) IIS will authenticate the user using Kerberos DESPITE the SharePoint web application being set for NTLM. User impersonation will not be used, but the initial authentication will be Kerberos. A check of the Windows Security logs will confirm this.

So, knowing all that I thought that perhaps my client had his SharePoint web application authentication method set for NTLM, but was seeing Kerberos in his security logs. Not the case. A screen shot later proved that he was indeed configured to use Kerberos.

So now I finally get smart and start to apply the scientific method. I ask for a complete description of their environment and what evidence he had to say that he was being authenticated via NTLM. And the truth finally emerged.
He was creating his web application in his intranet. He would then VPN in to the network from an outside network, and then connect to the site with his browser. He was prompted for credentials in a standard NT challenge response window. It was this window that he was calling NTLM. He thought that Kerberos needed to include the client's computer in the Kerberos chain, and that Kerberos could only be configured if the user's browser was configured to pass the user's logged on credentials. This, of course is false. Only the user needs to be authenticated, and it is the SECOND computer in the chain that needs to be trusted for delegation. The first hop you get with just the password. Because of this, ANY user can be used as the impersonated user, as long as they are registered with AD. It is how you can change the logged on user in SharePoint. Because his Kerberos chain is in tact, Kerberos can be successfully used as the authentication method.

And with that, the mystery was solved and all was well with the world. A second zone was not needed for NTLM, because Kerberos could be used. Despite my diagrams and explanations, my client STILL can not get his head around the fact that NTLM is not being used at any point. He thinks that if the challenge response window pops up, you are in NTLM's grip...

The moral of this story is to use the scientific method first to solve issues, rather than attempting to prove someone wrong, and that you are the smartest guy in the room first... Goes better for client relations too.

Wednesday, August 18, 2010

Web Sites, Databases and Kerberos

For some reason the documentation on how to set up Kerberos in your environment seems to be very sketchy out there. So I will write out what you need to do to get things to work.
In my example we will think of a system where we have a user, a web application server, and a database server. In our situation the database server is set up so that the user is granted execute access to the stored procedures called by the web application.
  1. ALL servers that you will be using need to be trusted for delegation in AD. No exceptions. If any servers involved are not trusted for delegation, the chain fails and the user credential will not propagate to the next hop. That means that all web servers, all database servers, and whatever application servers you have in your environment need to be trusted, regardless of the next steps.
  2. All users involved need to be trusted for delegation. This includes the end users, and any service accounts that may be running your application pools.
  3. If you are using a DNS alias for your web site a Service Principal Name needs to be created for that alias. This is where things get tricky.
    • If there is only one web server in your environment you would register the DNS alias with that server. You would then use the Network Account as the ID to run your application pool under.
      • setspn -a HTTP\MyDNSName WEBSERVER
    • If you have a web farm, the IP that owns the DNS alias exists on some other device, so what server do you register your SPN under? You need a domain account to register your DNS SPN. If you are using IIS 6, you will need to use this account that the DNS SPN is registered under as the ID that your application pool uses for its identity. If you are using IIS 7 and up, you do not need to use this account, but any account the application pool uses as its identity will be need to be trusted for delegation.
      • setspn -a HTTP\MyDNSName MyDomain\ServiceAccount
  4. Any database that is used will need to be registered with a SPN as well. If you are using a named instance as your server, you will need to register the instance as ServerName:PortNumber. Again, you will need a domain user, trusted for delegation, to register your database instances under. This account does not necessarily need to be the account you installed SQL under, but it does need to be a valid domain account.
    • setspn –a MSSQLSvc/ServerName:PortNumber MyDomain\SQLServiceAccount
  5. In IIS, the web site must be set to Integrated Windows Authentication. You still need to get the user credential from the user, this is how it is obtained. No other type of authentication will work, it must be Windows Authentication.
    • If your application is a .NET application, you will want to make sure that your authentication tag in your web.config is set to Windows.
      In IIS 7 and up, just by clicking Windows Authentication will update your web.config file, but in IIS 6 you will have to make sure it is there.
    • If your app is not a .NET app, IIS will handle the authentication part for you, however the next step might be tricky...
  6. Next, you will need to tell your application to impersonate the user that is logging on to the system. In IIS 7 and up that is easy, you simply check the box in the Authentication section that says ASP.NET Impersonation, and you are done. In IIS 6 you will need to add an identity tag to your web config, then set impersonation equal to true (<identity impersonate=true />)
    • If your app is not a .NET application, and you are not using IIS 7 and up, you will need to follow whatever steps your platform uses to impersonate users.

  7. Finally, you will need to write your connection string so that it uses integrated windows authentication. For a MS SQL server that is Integrated Security=SSPI. That is all you need do, no user name, no password.
    • If you want to use Integrated Security, but instead of the end user, you wanted to use the application pool identity, all you would need to do is uncheck ASP.NET Impersonation option (IIS 7 and higher), or remove the >identity /> tag (IIS 6) from the web.config. The IIS impersonation credential hierarchy is user, app pool, web site anonymous account.

I hope this helps. I have found that where I tend to make mistakes is making sure my applications are set to Windows Security, and the Database instances have SPNs.