Monday, August 11, 2014

SharePoint External Architecture & Implementation - Part 3

 

Previous Blog : SharePoint External Architecture & Implementation - Part 2

Authentication is a very important factor when building an external environment. One of the most important thing to understand is that, an external platform is usually used by non-corporate users; namely customers and suppliers. There are also applications which are used by corporate employees. For all applications that are accessed by corporate employees, the standard mode of authentication is Active directory (Kerberos). If your application is to be used by corporate employees, very good, because there is already a good authentication mechanism in place. All you have to do is build your application and join it with corporate domain. Well, it’s easier said than done, however there are more challenges to be faced when your application also caters to non-corporate users.

Before we talk about external authentication mechanism, let’s take a look at the authentication mechanism used for any external application.

First, what is Authentication?

“Authentication is the process of determining whether someone or something is, in fact, who or what it is declared to be.”

To successfully and accurately determine identity of a user, it necessary to have a reference list, database, password or any such method which can uniquely identity it. Let’s understand different authentication scenarios from two examples.

Example 1:

I book an airline ticket online. On scheduled date, I arrive at the airport for check-in. Security staff asks me for my ticket, and I show a locally printed ticket to them. They are satisfied that it’s a valid ticket with for a travel that would initiate in some time. However, they would still ask me for my identity verification; to ensure that I’m what I claim to be. This identity verification can be done with my driving license or a passport. They would look at the photograph on the identity card and then at me and will let me board the flight only when they think it belongs to me.

Example 2:

I book a ticket for a movie. I arrive at the movie theater to claim my seat. The gate-keeper asks me for my ticket, and I present it to him. I takes a look at the ticket, validates that it’s for the right show and lets me in.

The major difference in above examples is that, in example 1 – even after I claimed that I’ve a valid ticket, I was asked to prove my identity. While in example 2 – my claim is sufficient. Example 1 showcases working of an active directory authentication mechanism. After I pay for my ticket, through password - I’m issued a ticket with a fixed validity period. My operating system uses this ticket to access applications, and applications on their part validate with Active Directory services that the ticket is valid and was indeed issues to me. Example 2 is a typical scenario for a claim based authentication, usually done for external facing application. Because non-corporate users don’t have valid account in corporate directory service, they are issued a ticket through a mutually trusted use store. Example of such user stores are, Microsoft Live, Microsoft Azure, Google+, Facebook, LinkedIn etc...… Once a user is authenticated through the user store, Identity provider issues a time bound token to the user’s browser or client application. This token may have attributes such as login name, email address, country etc...… User presents this token to external application and the application accepts it, NO QUESTIONS ASKED. It doesn’t go back to user store to validate, it simply trusts it.

External facing applications, which are accessed by non-corporate users work on same mechanism as described in example 2. Valid users are issued tokens after they are authenticated. This token is stored on client machines through cookies.

If external users have to be authorized and authenticated, there needs to be a user store/repository through which these users can be validated. Now it completely depends on the organizational preferences. It could be either an external users repository such as Microsoft Azure, Google + or an internal repository such as IBM Tivoli directory service or any other open LDAP director service.

In absence of active directory, SharePoint uses a custom authentication provider, namely a claims Federation agent. Special configurations have to be put in place to configure this Federation agent with SharePoint. This configuration is done with the help of Power Shell. In this post I’ll walk you through the process of configuring a custom Federation agent and how it works.

During the configuration of Federation agent in SharePoint, you will also define the login URL for the SharePoint. When user request hits SharePoint, SharePoint will redirect user to this login URL. This login URL will belong to an authentication mechanism which will take supplied user credentials and validate them against the user store. Once this authentication mechanism validates that the user is a valid one, it will pass this information to the Federation agent. Also this authentication mechanism will pass any required attributes for this user such as username, email address, et cetera. Federation agent on receiving these attributes; will convert them into a claim token and then it sends this claim token to the SharePoint. SharePoint uses claims authentication within the farm to communicate within servers and services.

Let’s understand how to configure an authentication provider for SharePoint.

   1: $root = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2("path to root certificate")
   2: New-SPTrustedRootAuthority -Name "Root" -Certificate $root
   3:  
   4: $cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2("path to certificate provided by federation agent")
   5: New-SPTrustedRootAuthority -Name "<authenticatino provider name>" -Certificate $cert
   6:  
   7: $upnClaimMap = New-SPClaimTypeMapping -IncomingClaimType "http://schemas.xmlsoap.org/claims/UID" -IncomingClaimTypeDisplayName "UID" -SameAsIncoming
   8: $emailClaimMap = New-SPClaimTypeMapping -IncomingClaimType "http://schemas.xmlsoap.org/claims/EmailAddress" -IncomingClaimTypeDisplayName "EmailAddress" -SameAsIncoming
   9: $CNClaimMap = New-SPClaimTypeMapping -IncomingClaimType "http://schemas.xmlsoap.org/claims/CommonName" -IncomingClaimTypeDisplayName "CommonName" -SameAsIncoming
  10: $FirstNameClaimMap = New-SPClaimTypeMapping -IncomingClaimType "http://schemas.xmlsoap.org/claims/FirstName" -IncomingClaimTypeDisplayName "FirstName" -SameAsIncoming
  11: $LastNameClaimMap = New-SPClaimTypeMapping -IncomingClaimType "http://schemas.xmlsoap.org/claims/LastName" -IncomingClaimTypeDisplayName "LastName" -SameAsIncoming
  12:  
  13:  
  14: $realm = "urn:sharepoint:<environment_name>"
  15: $signInURL = "<login url, would be given by federation agent>"
  16: $ap = New-SPTrustedIdentityTokenIssuer -Name "<authentication provider name>" -Description "<description>" -realm $realm -ImportTrustCertificate $cert -ClaimsMappings $upnClaimMap,$emailClaimMap,$CNClaimMap,$FirstNameClaimMap,$LastNameClaimMap -SignInUrl $signInURL -IdentifierClaim $upnClaimMap.InputClaimType
  17:  
  18: $sts = Get-SPSecurityTokenServiceConfig
  19: $sts.LogonTokenCacheExpirationWindow = (New-TimeSpan –minutes 1)
  20: $sts.Update()
  21: iisreset

Lets understand each of above code lines.


$root = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2("path to root certificate")
New-SPTrustedRootAuthority -Name "Root" -Certificate $root
 
$cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2("path to certificate provided by federation agent")
New-SPTrustedRootAuthority -Name "<authenticatino provider name>" -Certificate $cert


Above commands import certificates in SharePoint’s trust store. Federation agent always sends a signature with token to SharePoint. For SharePoint to trust that token, the signature should match with available signatures in its trust store. First certificate that we are importing above in SharePoint belongs to your domain name (trust chain). Next certificate belongs to the federation agent.


$upnClaimMap = New-SPClaimTypeMapping -IncomingClaimType "http://schemas.xmlsoap.org/claims/UID" -IncomingClaimTypeDisplayName "UID" -SameAsIncoming
$emailClaimMap = New-SPClaimTypeMapping -IncomingClaimType "
http://schemas.xmlsoap.org/claims/EmailAddress" -IncomingClaimTypeDisplayName "EmailAddress" -SameAsIncoming
$CNClaimMap = New-SPClaimTypeMapping -IncomingClaimType "
http://schemas.xmlsoap.org/claims/CommonName" -IncomingClaimTypeDisplayName "CommonName" -SameAsIncoming
$FirstNameClaimMap = New-SPClaimTypeMapping -IncomingClaimType "
http://schemas.xmlsoap.org/claims/FirstName" -IncomingClaimTypeDisplayName "FirstName" -SameAsIncoming
$LastNameClaimMap = New-SPClaimTypeMapping -IncomingClaimType "
http://schemas.xmlsoap.org/claims/LastName" -IncomingClaimTypeDisplayName "LastName" -SameAsIncoming


Here we are mapping SharePoint claims with incoming claims in the token sent by federation agent. Total number of claims to be used depends on your requirement. Also the ClaimType format (http://schemas.xmlsoap.org/claims/LastName) depends on your choosing.


$realm = "urn:sharepoint:<environment_name>"
$signInURL = "<login url, would be given by federation agent>"
$ap = New-SPTrustedIdentityTokenIssuer -Name "<authentication provider name>" -Description "<description>" -realm $realm -ImportTrustCertificate $cert -ClaimsMappings $upnClaimMap,$emailClaimMap,$CNClaimMap,$FirstNameClaimMap,$LastNameClaimMap -SignInUrl $signInURL -IdentifierClaim $upnClaimMap.InputClaimType


In above lines, first we are identifying SharePoint as client for federation agent and vice versa. The sing-in URL would be provided by the federation agent. All previous commands were a preparation for the configuration of an authentication provider. With New-SPTrustedIdentityTokenIssuer we are finally implementing it. With this command, we specify all certificates that we have imported, all claims mappings, realm and the sign-in URL. If this final command completed without error, you have setup you custom authentication provider.


To check whether authentication provider is setup run – Get-SPTrustedIdentityTokenIssuer


However there is a great chance that you still can not login to your new site collection created with this authentication provider. You might face the problem where the federation agent sends the token, but SharePoint does not accept it or to put it more accurately – SharePoint authentication goes in a loop. This happens because SharePoint default expiration window for tokens is 10 minutes; whereas most of federation agents create a token with expiration window of just 2 minutes. When SharePoint receives the token from federation agent, it checks the expiration window of the token received. Once it realizes that this token will expire before its own expiry window; it rejects the token and again sends a request to federation agent for new token, and this goes on and on. To fix this problem set SharePoint token expiry window to less than expiry window provided by federation agent. This way SharePoint knows that token is valid for its entire expiry duration. To set the SharePoint token expiry window:


$sts = Get-SPSecurityTokenServiceConfig
$sts.LogonTokenCacheExpirationWindow = (New-TimeSpan –minutes 1)
$sts.Update()
iisreset


With this, you will be able to use your new authentication system.






No comments:

Post a Comment