Mar 23, 2009

Authentication process: Kerberos or NTLM? and delegations

I ever post on how to register SPN. SPN is pretty much all needed for Kerberos authentication. The common misunderstanding is, authentication first try Kerberos, and if it fails, then try NTLM. Kerberos fallback to NTLM is referring selection process,not authentication itself. For example, when a client is trying to access server, NTLM will be selected if:
  • client such as IE has "Integrated window Authentication" unchecked (even if server IIS have NTAuthenticationProvider paramenter set to "Negotiate, NTLM": NTLM failback);
  • or server IIS have NTAuthenticationProvider paramenter set to "NTLM" (even if IE has "integrated window Authentication" enabled)
  • or SPN is not found from KDC
IIS 5 has default setting as "Negotiate, NTLM", in IIS 6 NTAuthenticationProvider paramenter is not set, but IIS 6 use "Negotiate, NTLM" as default just like IIS 5.

If both client and server support Kerberos (ie, server IIS has "Negotiate,NTLM" and IE support "Integrated window Authentication") kerberos will be selected.Negation starts: if client can get a ticket (SPN), it will send kerberos ticket, otherwise client will ask to use NTLMssp for authencation. if server doesn't have SPN, If client sends a wrong ticket, server will keep chanllenging client, and the result is: the authentication fail: server pop for password, but fail on any credentials. The authentication process can't fallback to NTLM at this point.

One of common cases that client could get wrong tickets is, the request uses Netbios name such as http://servername/, http/servername is not registered, but Host/servername always exists. The result is client keep sending ticket for HOST/servername while server expect HTTP/servername ticket.

Now it comes why we need delegation? You need delegation when you want to forward logon user's credential to another system. your ASP web needs to access resources in other server (double hop issue). This can happen when you have custom code to connect to anther SQL server, or you try to retrieve BDC data(other option for BDC is SSO), or you need to use Excel Service to display data from SQL report.

First, how to get logon user's credential?

  • System.Net.CredentialCache.DefaultCredentials when impersonate=true
  • User.Identity.Name when it is not anonymous
Second, how to hop?

  •  trust the server account (whatever it is, i.e, application pool, ssp service accout or mySite account etc) for delegation;
  • grant authenticated user (rather than service accounts) an access to target server/data.

Need to turst Computer Account for delegation? No, but only when your service is running under network service, local service or local system. When configuring computer account for delegation, 1) registering specific service (option 3) rather than all service (option 2), see here for insturction; 2)reboot server to make it effective.
Remember delegation has both timing and location constrains.

here is the checklist for kerberos delegation

Mar 21, 2009

Add Javascript on SharePoint pages

Some tips to inject javascript into sharepoint page:

1) _spBodyOnLoadFunctionNames is a good friend. It will be called on page onload. So to make a javascript function call, you just need to put this


and your function definition in a CEWP on any sharepoint page.

2) toolpaneView=2 is the trick to insert CEWP on list forms such as Edit, View, New.

3) delegate control with Id ="AdditionalPageHead" to add script cross pages.

Implement this control with a user control in the /controltemplates, and the user control can control nothing but your custom javascript files under _layouts. For example, to include JQuery library:

<%@ Control % >
< script src="./_layouts/jquery-1.2.6.js" type="text/javascript" / >

To use custom CSS files without modifying master page, see this post.

Update 04/13/2010:
4) Use CustomAction in Sharepoint 2010.

SharePoint Kerberos: How to register SPN

To enable Kerberos authentication for sharepoint, the first step is to register SPN for differernt serveice accout.

1. SQl service account

it should be in the following format:

setspn -A MSSQLSvc/ accountname
setspn -A MSSQLSvc/ accountname

After that you can verify the kerberos by running the following query:

select auth_scheme from sys.dm_exec_connections where session_id=@@spid

note: you have to remotely connect to your SQL server, otherwise if you run SQL Studio inside the SQL server as I normally did, the above query always returns NTLM

2 web application pool account:
Assuming you have 2 web applications, one is at 80 and the other is at 8888.The best practice is to register in the format of:


if a FQDN is used in place of Netbios, make sure FQDN is a A record in DNS, not a CNAME. CNAME will be translated into a different FQDN. How to find the type?

>Set type=A (or CNAME)
> your FQDN

note: do NOT append append default 80, it will break if browser strips off 80, and also the bonus is it can make IE6 which doesn't append port number work without hotfix.
for eaxmple, if a request is made from IE 6.0, IE 6 will compose SPN as http/ which happens to match the one registered. It can fail if HTTP/ is registered instead. If the same request is made from IE7, the SPN will be http/, and that is why we need the second format.

Beaware though, after registering Http\NetBiosName, it will overtake Host\NetBiosName which can cause Http 401.1 error as described in this post.

3. SSP service account
Don't even bother to register SPN in the format of HTTP/. It won't work. You have to install Infrastructure Update or CU which includes IP,and then use the new custom format:

Assuming SSP name is mySSP. read more here

4. Farm Admin and My Site serveice accounts
You can register them either using header or port number to avoid duplicates. It really should not matter, but normally people use port for Farm Admin, and use header for MySite.

Note: if any service account is using newbiosname account(Network Service, Local Service and Local System), you don't have to set SPN for them, since they already have a SPN (HOST/netbioname) by default.

with SPN registration done, you can verify kerberos authentication from the event logs. I will cover delegation in another post.

This post is based on IIS 6.0 for ISS 7 please read here.

Mar 19, 2009

Sharepoint Application Pool ID Account

SharePoint always impersonate authentication users in web.config by this entry: <entity impersonate="true" /> and it also has a Application Pool Account. What does this account do?

  1. In case Kerberos is used, this is the account that clients(such as IE) try to communicate with. This is why this account has be registered with a SPN for Kerberos authentication;
  2. In case you have custom code which need to hop to another server (SQL, File or any web service server), this account will forward login user credential(ticket in kerberos term) to the other server. This is why this account needs to be trusted for delegation;

  3. This is the account that sharepoint use to connect its own Content Database, which I bet is through a call RunWithElevatedPrivelege.

A couple other things I learn about web application pool account:

if you try to create an application from directly from IIS, you have to run:

ASPNET_regiis.exe -ga domain\pollIdAccount

if you use NetWork Service as pool id in window server 2k, you have to grant "Act as part of the operating system" privilege for impersonation to work. This is not necessary in Server 2003.

All application pool id should be in the IIS_WPG group which grant most permission they need. See here for a full list permission IIS built-in accounts have.

double hop issue and sharepoint sql communication

double hop big picture: IE browser--->Web Front End----->SQL (0r any 0ther server)

The double hop issue is all about passing window security token, so if you use SQL connection string, you don't have this annonying problem; or if
your ASP Web uses trusted subsystem (instead of impersonation which is configured in the web.config: < identity impersonate="“true”/ >). In the case of trusted system, it is the web application pool account who hops (only 1) to another server.

One of my colleagues responded this by asking, "why sharepoint doesn't have double hop issue when its WFE connects to its SQL database?"

Well this is the question I don't know the answer to. We all know kerberos is not required for sharepoint, impersonate is the default setting in sharepoint web.config, and window authentication in SQL is default too. so I go to google, no found a direct answer though, the closest one is:

< identity impersonate = “true” username=”Domain\UserName” password=”pword” / > can fix the problem.

I went back to my sharepiont web.config, of course, I didn't see it. But it does shed light. If impersonation in web.config can fix this problem, then impersonation in code should have done the same thing. In Sharepoint, RunWithElevatedPrivilege is designed for network calls: this little guy impersonates Application Pool Account, and this account always has SQL access.

I hope this bold assertion can trigger some interests on how sharepoint intra-farm communication work and someone can either confirm or correct it.

Mar 16, 2009

Share a Document Library among different sites

There are many times people ask: how to share a whole document library among different sites? You can of course do with DVWP or CQWP, but neither of them gives a good user interface. You can also use LinkTo content type, but that is an item-by-item solution.
There is a third addons: but it requires server access and intallation.

We know list view web part can perfectly display a document library, but OOB it can only be added within same site. Is there a workaround?

The answer is yes, since we all know we can convert List View webpart into DVWP, and then we can export to a .webpart file and then import it to any site in the collection.

If you just do that, you will get a generic error. The problem is, in the .webpart file, only listId is specified, no WebUrl.

We need to add WebUrl:

1) open .webpart file in any editor
2) search and find "ListID", there are 3 of them
3) after each "ListID" add the followings:

<asp:Parameter DefaultValue="siteName" Name="WebUrl" />

After saving the change, import it to any site in the collection, you will see it works just like a charm.

BTW, Even though you need to use SPD when converting LVWP to DVWP, you can avoid un-ghosting by deleting the page containing the initial LVWP.

a great idea on how to deploy DVWP from one farm to another: