Real World Claims Part 4: Configuring ADFS and SharePoint STS

This post is part 4 of a series, and is a companion to my presentation titled Real World Claims in ADFS and SharePoint 2010. This presentation will be given Saturday, April 13th, 12 noon at SharePoint Saturday, The Conference, Washington, DC April 11-13, 2011. Table of contents, additional links, slides, video recording, and other funny liner notes will be posted in Part 1 as they become available.

 

In the last chapter, we set up the SharePoint web application to accommodate our ADFS deployment. We created three sites, one original and two extended, provide an anonymous access via HTTP, a secure HTTPS access for logged in users, and a safety net site that we can use internally for services that don't support claims login – or in the [oh-so-unlikely] event that ADFS malfunctions at some point.

Now, we need to do some substantial configuration to get ADFS working with SharePoint. SharePoint actually ships with its own Secure Token Service. If you've set things up like we have and configured your web applications to use claims authentication (as opposed to classic mode), then you're already using the SharePoint STS. What we need to do now is to configure SharePoint to use ADFS as a Trusted Identity Provider – and conversely set up ADSFS to allow our SharePoint web sites as a Relying Parties.

For the short run, we'll just configure ADFS to use Active Directory. Later, I'll add additional identity providers to ADFS to allow users to log in with accounts that come from other sources.

Allow me a final word about the architecture we're using here. Strictly speaking it is not really necessary to use ADFS in this way; you could set up your own custom STS web site(s) and tie directly into the SharePoint STS. You can write your own custom claim provider in SharePoint that ties directly into its STS, and if you want a custom user picker you'll actually need to. But doing these things requires lots of code and lots of PowerShell. Putting ADFS in the position of being the claims broker for SharePoint can greatly simplify your overall configuration, improve reliability, and provide a path for load balancing and enhanced performance. This choice is a topic I plan to cover in more detail during my presentation.

Generate Certificates for ADFS Token Signing

Let's get started. The ADFS server installs with its own self-signed certificate. You can view these from the ADFS Management Console.

 

 


Viewing this certificate, you can clearly see that there is something wrong with it. The problem is that it's self-signed. We could add the certificate to Trusted Root Certificates store like they suggest in the warning, but we want to try to learn to do this the right way. So, let's create a certificate that has the correct chain of authority for our domain.

On the ADFS computer (DEMO\MasterControl), click on Start > Run and type "mmc". This will bring up the management console.

 

In the management console, go to File > Add/Remove Snap In.

 


Click Certificates, then the Add button. A pop-up will appear.

 


Pick "Computer account" to show the machine certificate store.

 


...for this computer, not another one. :-/

 


It'll look like this, so hit OK.

This brings us into the computer's certificate store. Leave this open as we'll get a lot of use out of this as we continue. Assuming all went well, we'll request a certificate to use for ADFS encryption and signing next.

 


A successfully created certificate manager snap-in will look like this.

 


Let's do a File > Save As and store this MSC file someplace so we don't have to do all these steps again the next time we need it.

 


Request a certificate by expanding Personal > Certificates, then right-click and choose All Tasks > Request New Certificate.

 


Request templates come from Active Directory. Sometimes an external partner may give you a URL that you can use to add additional Certificate Enrollment Policy servers to this list manually.

 


Check the box for "Legacy STS" then click the link to provide the additional information. (Yes, the screen shot is wrong. See the section in Part 2 on setting up the certificate template to find out why.)

A Note from Captain Hindsight: When I tried this, I found first that it took a while for my certificate template to replicate into my DEMO domain - I had some health issues in both domain replication and the enterprise CA, and secondly that the rights I had given for the template weren't enough to request the certificate in this way. In this walkthrough, I've gone back in time and retroactively corrected my instructions.

 

Provide just the information that follows. I have seen that providing too much information may cause ADFS to reject the certificate later.

CN= mastercontrol.demo.colossusconsulting.com
O=Colossus Consulting LLC
OU=Liquid Mercury Solutions
L=Baltimore
S=Maryland
C=US
Alternative name – DNS: adfs.demo.colossusconsulting.com
The last item is optional. I wanted to try an experiment using SANs (Subject Alternative Names). (Again, the screenshots are wrong; I reversed SAN and CN and used a different DNS in my SAN.)

 


It should look like this when you're done. (Again, SAN and CN reversed.)

 


Verify we meet the requirements for what we're trying to do. 2048 bits and exportable keys.

 


Captain Hindsight: Now would be a good time to add permissions to the DEMO\adfs.service account too! More on this step later.

 


Note that each box you check here will ultimately have to be added to a list of trusted authorities we'll provide to the SharePoint STS.

 


Provide everything it wants and the link should disappear. (Again, we're using "Legacy STS" template not "Secure Token Server".)

 


Click Enroll to send the request to the CA. Assuming you have permission to enroll on the CA, this should succeed. If not, you can manually Issue the certificate at using the CA's MMC snap-in.

Changing the Certificates Used by ADFS Server

So, let's take the new certificate we created and set up ADFS to work with it instead.

 

Here's a little PowerShell script that we use to do just that.

param($tf)
Add-PSSnapIn Microsoft.Adfs.PowerShell
Set-ADFSProperties -AutoCertificateRollover $tf

Note: to get scripts to run, I had to do this:

Set-ExecutionPolicy Unrestricted
c:\TEMP\ADFSSetEditCerts $false

But there are certainly more secure ways to get your scripts to work, like actually signing them. When you're done, you can run the same script with $true to restore the lock. It will throw an error, but you can safely ignore it. Here's the screenshot:

 

Going back to the ADFS console, when you click Add Token Signing Certificate and Add Token Decription Certificate, you'll be prompted with a menu like this one.

 


Choose your desired certificate and click OK.

For both new certificate entries, right-click and choose "Set as Primary".

 


You might be given a warning like this one. We haven't created any Relying Party trusts yet though, so don't worry about it.

You'll be greeted with this reminder.

 

 

This is a really important step, and if DEMO\adfs-service can't access the private keys, you'll get error 133 in the event logs. This particular event happens for lots of reasons, so troubleshooting it is a pain. Best not to omit this step, as its one more thing you'll have to troubleshoot later. Assuming you didn't add these rights when you created the certificate in the first place, let's take care of this now before we forget. Back to Certificate Manager!

 

 


Give Read access to both NETWORK SERVICE and DEMO\adfs-service accounts.

Test your changes by restarting the ADFS service after you've added new certificates, to make sure they are compatible before your move forward.

After you successfully restart the ADFS service without any 133 events, you can safely delete the two self-signed certificates that ADFS included when it installed.

 


When you've finished, it should look like this. And, we got no warnings about the key strength of the certificates we chose.

 


You can view the certificate and see there are no warnings or errors.

Configure ADFS Relying Party Trust

With the correct certificate in place, we can configure ADFS to trust SharePoint as a Relying Party. This means that SharePoint will consume claims from ADFS – in other words, rely on it.

We do this in the ADFS Management Console on MASTERCONTROL.

 


Above are a couple places you can click to get started.

 


Step 1: Enter the RP information manually. SharePoint does not provide a FederationMetadata.xml file. However, you could choose to create and maintain such a file yourself - and publish it in a document library or by some other means.

 


Step 2: Just a description that will help you remember what this RP is for will be fine.

 


Step 3: Choose the ADFS 2.0 profile.

 


Step 4: We're not setting up token signing and encryption at this time, but we can [and should] revisit this later.

 


Step 5: The URL for the passive endpoint in SharePoint takes a standard format.

 


Step 6: It's okay to leave the default identifier in place, but later we'll configure a custom realm identifier in SharePoint. We add it here in anticipation of doing this soon.

 


Step 7: In secure environments, you start by denying access to all then open it to some. I just want my demo to work; save security for another day.

 


Step 8: Confirm your settings.

 


Step 9: The last screen will take you directly into the Rules manager.

 


We'll need to create one rule for AD, and three rules to support other claim providers.

 


"Send LDAP Attributes as Claims" is used to pass through Active Directory claims.

 


We need 3 attributes from AD: E-mail Addresses, Token Groups, and User Principal Name. I used the qualified token groups, because I want to be able to make a distinction between different domains on my network. UPN also makes a distinction between domains, so if you want to merge sub-domains under a single identity you could do that with a rule or by using unqualified account name instead.

 


One down, three to go.

 


We need to pass through three claims. Each one must be done with a separate rule.

 


Passing through e-mail address is fairly straightforward.

 


Now, we do the same for Role.

 


And finally, UPN.

 


Some of my providers actually pass through even more claims than this. For the sake of the demo, I'll keep this simple for now. We can always add more later on if we want to.

 


And you now see our completed RP configuration.

Exporting the ADFS Certificates to SharePoint Server

Now, we need to tell SharePoint to trust the certificate that we're using in ADFS. Additionally, SharePoint will need to trust every certificate in its chain of authority, so any subordinate CA or root CA in the chain will need to be added as well. We can easily get to the certificate chain from the ADFS console.

 


View the certificate to see its chain of authority.

 


Starting with the certificate itself, under Details, you can Copy to File in order to export the certificate.

 


Note that you *do not must be exportable)* need to put the private key on SharePoint. This is an important aspect to federated security. While your ADFS server needs access to its own private keys (they must be exportable), you should not need to give your private key to any federating partner – even one inside your own organization.

 

Note: for SharePoint to encrypt tokens, it will need its own certificate with a private key. To show that we don't need (or want) to share private keys, we'll issue a separate certificate for the SharePoint server, and then bring the public key back to ADFS and configure it. This will be done a little later.

 


Any format that can be read by SharePoint and PowerShell should be fine.

 


Save the file to a location we can access from SMARTYPANTS.

 


Once we've exported the certificate, we can use the Certification Path to view each certificate in the chain of authority. For each one, export it in the same way as was just done above.

 


For the certificate authority's certificate, obviously we give it a different file name.

 


So, you can see now we have all the certificates we'll need to use in SharePoint STS.

Configure the Trusted Identity Provider in SharePoint

Now that we have these certs on the SharePoint server, we need to tell SharePoint to trust them. We can do this from the SharePoint 2010 Management Shell.

param($certFilePath,$name)
if ($args) {"'$args is $args"}
"Configuring SharePoint Root Certificate Authority ..."
$root = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2("$certFilePath")
if ($root) {
    New-SPTrustedRootAuthority -Name "$name" -Certificate $root
    "Done."
}

File C:\TEMP\AddSPTrustedRootAuth.ps1


Table: parameters for AddSPTrustedRootAuth.ps1

We can call the file with a script like this one:

Set-ExecutionPolicy Unrestricted # Have to do this again, because we're on a different server.
y
CD c:\TEMP
.\AddSPTrustedRootAuth "C:\Temp\ADFS Keys\ADFS-Encryption.cer" "ADFS (adfs.demo.colossusconsulting.com)"
.\AddSPTrustedRootAuth "C:\Temp\ADFS Keys\CA.cer" "Root CA (whopper.colossusconsulting.com)"


Of course, don't forget to lock down your execution policy later.

The output should look something like this:

PS C:\Users\Administrator.DEMO> Set-ExecutionPolicy Unrestricted # have to do th
is again, because we're on a different server

Execution Policy Change
The execution policy helps protect you from scripts that you do not trust.
Changing the execution policy might expose you to the security risks described
in the about_Execution_Policies help topic. Do you want to change the execution
policy?
[Y] Yes [N] No [S] Suspend [?] Help (default is "Y"): y
PS C:\Users\Administrator.DEMO> CD c:\TEMP
PS C:\TEMP> .\AddSPTrustedRootAuth "C:\Temp\ADFS Keys\ADFS-Encryption.cer" "ADFS
(adfs.demo.colossusconsulting.com)"
Configuring SharePoint Root Certificate Authority ...


Certificate : [Subject]
CN=adfs.demo.colossusconsulting.com, OU=Liquid
Mercury Solutions, O=Colossus Consulting LLC, L=B
altimore, S=Maryland, C=US

[Issuer]
CN=colossusconsulting-WHOPPER-CA, DC=colossusco
nsulting, DC=com

[Serial Number]
779BE341000000000049

[Not Before]
8/10/2011 8:17:15 PM

[Not After]
8/9/2013 8:17:15 PM

[Thumbprint]
296632E3BB00ACDB05B4887BBCB44AEA9F5C3C0B

Name : ADFS (adfs.demo.colossusconsulting.com)
TypeName : Microsoft.SharePoint.Administration.SPTrustedRoot
Authority
DisplayName : ADFS (adfs.demo.colossusconsulting.com)
Id : 9ab83a92-31d5-427d-bda2-b6aae4177fd9
Status : Online
Parent : SPTrustedRootAuthorityManager
Version : 15816
Properties : {}
Farm : SPFarm Name=SharePoint_Config
UpgradedPersistedProperties : {}

Done.


PS C:\TEMP> .\AddSPTrustedRootAuth "C:\Temp\ADFS Keys\CA.cer" "Root CA (whopper.
colossusconsulting.com)"
Configuring SharePoint Root Certificate Authority ...


Certificate : [Subject]
CN=colossusconsulting-WHOPPER-CA, DC=colossusco
nsulting, DC=com

[Issuer]
CN=colossusconsulting-WHOPPER-CA, DC=colossusco
nsulting, DC=com

[Serial Number]
501B7B43AE80D28F4A5590C2ABBD7FAC

[Not Before]
2/11/2010 3:20:28 PM

[Not After]
2/11/2020 3:30:20 PM

[Thumbprint]
B0E8925EA3D3C5E57D6ED88E80CD010AC30EC179

Name : Root CA (whopper.colossusconsulting.com)
TypeName : Microsoft.SharePoint.Administration.SPTrustedRoot
Authority
DisplayName : Root CA (whopper.colossusconsulting.com)
Id : 048afda4-c072-4f04-995c-a51252e672d8
Status : Online
Parent : SPTrustedRootAuthorityManager
Version : 15818
Properties : {}
Farm : SPFarm Name=SharePoint_Config
UpgradedPersistedProperties : {}

Done.


PS C:\TEMP>

Now, we need to tell SharePoint to use ADFS as its IdP-STS (Identity Provider Secure Token Service).

param($certFilePath,$adfsDns,$name,$description)

if ($args) {"'$args is $args"}

"Configuring SharePoint STS as RP for ADFS ..."

$cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2("$certFilePath")

if ($cert) {

$map1 = New-SPClaimTypeMapping "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn" -IncomingClaimTypeDisplayName "Account ID" –SameAsIncoming

$map2 = New-SPClaimTypeMapping "http://schemas.microsoft.com/ws/2008/06/identity/claims/role" -IncomingClaimTypeDisplayName "Role" –SameAsIncoming

$map3 = New-SPClaimTypeMapping "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress" -IncomingClaimTypeDisplayName "Email Address" –SameAsIncoming

$realm = "urn:sp2010:adfs"

$signinurl = "https://$adfsDns/adfs/ls/"

$ap = New-SPTrustedIdentityTokenIssuer -Name "$name" -Description "$description" -Realm $realm -ImportTrustCertificate $cert -ClaimsMappings $map1, $map2, $map3 -SignInUrl $signinurl -IdentifierClaim $map1.InputClaimType

"Done."

}

File: SPConfigureADFS.ps1

Parameter Name
Description
$certFilePath
File path to the certificate we exported from ADFS.
$adfsDns
DNS name of our ADFS server or an ADFS proxy if we are using one. Note that unless you configure multiple providers, all SharePoint sites will use the same one.
$name
Name of provider. This will appear in SP-STS realm selector as well as prefix in all claims based user names.
$description
A friendly description, in case the name doesn't tell the whole story.
Table: parameters for SPConfigureADFS.ps1

So, we can use a command like this to run the script:

C:\TEMP\SPConfigureADFS "C:\Temp\ADFS Keys\ADFS-Encryption.cer" "login.aperturelabs.local" "Aperture ADFS" "Point to ADFS Proxy server (login.aperturelabs.local) on SmartyPants"


And, get the results:

PS C:\Users\Administrator.DEMO> C:\TEMP\SPConfigureADFS "C:\Temp\ADFS Keys\ADFS-
Encryption.cer" "login.aperturelabs.local" "Aperture ADFS" "Point to ADFS Proxy
server (login.aperturelabs.local) on SmartyPants"
Configuring SharePoint STS as RP for ADFS ...
Done.
PS C:\Users\Administrator.DEMO> Get-SPSecurityTokenServiceConfig


SecurityTokenServicePublicUrlSuffix : /_vti_bin/spsecuritytokenservicea
ctive.svc
SecurityTokenServiceMetadataPublicUrlSuffix : /_vti_bin/spsecuritytokenservicea
ctive.svc/mex
LocalLoginProvider : Microsoft.SharePoint.Administrati
on.Claims.SPLocalLoginProvider
TrustedLoginProviderNames : {Aperture ADFS}
TrustedLoginProviders : {Aperture ADFS}
TrustedAccessProviders : {}
UseSessionCookies : False
WindowsTokenLifetime : 10:00:00
FormsTokenLifetime : 10:00:00
ServiceTokenLifetime : 10:00:00
MaxLogonTokenCacheItems : 250
MaxLogonTokenOptimisticCacheItems : 100000
LogonTokenCacheExpirationWindow : 00:10:00
MaxServiceTokenCacheItems : 250
MaxServiceTokenOptimisticCacheItems : 100000
ServiceTokenCacheExpirationWindow : 00:10:00
Name : SecurityTokenServiceManager
TypeName : Microsoft.SharePoint.Administrati
on.Claims.SPSecurityTokenServiceM
anager
DisplayName : SecurityTokenServiceManager
Id : d720f68c-e45c-4aae-bfe0-e11304fd4
8b6
Status : Online
Parent : SPSecurityTokenService Name=Secur
ityTokenService
Version : 15907
Properties : {}
Farm : SPFarm Name=SharePoint_Config
UpgradedPersistedProperties : {}

 

PS C:\Users\Administrator.DEMO> Get-SPTrustedIdentityTokenIssuer


ProviderUri : https://login.aperturelabs.local/adfs/ls/
DefaultProviderRealm : urn:sp2010:adfs
ProviderRealms : {}
ClaimTypes : {http://schemas.xmlsoap.org/ws/2005/05/identity/
claims/upn, http://schemas.microsoft.com/ws/2008
/06/identity/claims/role, http://schemas.xmlsoap
.org/ws/2005/05/identity/claims/emailaddress}
HasClaimTypeInformation : True
ClaimTypeInformation : {Account ID, Role, Email Address}
IdentityClaimTypeInformation : Microsoft.SharePoint.Administration.Claims.SPTru
stedClaimTypeInformation
ClaimProviderName :
UseWReplyParameter : False
UseWHomeRealmParameter : False
Description : Point to ADFS Proxy server (login.aperturelabs.l
ocal) on SmartyPants
SigningCertificate : [Subject]
CN=adfs.demo.colossusconsulting.com, OU=Liquid
Mercury Solutions, O=Colossus Consulting LLC, L
=Baltimore, S=Maryland, C=US

[Issuer]
CN=colossusconsulting-WHOPPER-CA, DC=colossusc
onsulting, DC=com

[Serial Number]
779BE341000000000049

[Not Before]
8/10/2011 8:17:15 PM

[Not After]
8/9/2013 8:17:15 PM

[Thumbprint]
296632E3BB00ACDB05B4887BBCB44AEA9F5C3C0B

Name : Aperture ADFS
TypeName : Microsoft.SharePoint.Administration.Claims.SPTru
stedLoginProvider
DisplayName : Aperture ADFS
Id : c5b9ce06-7358-4c13-8d25-4c614f11a709
Status : Online
Parent : SPSecurityTokenServiceManager Name=SecurityToken
ServiceManager
Version : 15901
Properties : {}
Farm : SPFarm Name=SharePoint_Config
UpgradedPersistedProperties : {}

 

PS C:\Users\Administrator.DEMO>

 

You might realize by this point that we can configure multiple Trusted Identity Token Issuers for multiple SharePoint web applications. If so, your insight would be correct, which would allow us to host several differently branded proxy servers for a variety of customers on the same farm. In reality though, this will probably not happen for very many folks. It is a really neat idea though.

We're almost done configuring SharePoint, but still missing something. Recall that back when we configured the Relying Party in ADFS, we added a couple of realm identifiers. Why did we do this exactly? The answer is simple. Say we want to use the same Trusted Identity Token Issuer for multiple web sites that have different URLs. Say for example that later we want to add https://aperturelabs.local as a synonym for https://www.aperturelabs.local, or possibly we want to make a secure site for employees like https://intranet.aperturelabs.local. Adding ProviderRealms in addition to the default realm is how we can accomplish this without sending ADFS into fits of confusion.

We can add one with a PowerShell Script like this:

$t = Get-SPTrustedIdentityTokenIssuer "Aperture ADFS"

$uri = New-Object System.Uri("https://www.aperturelabs.local/")

$t.ProviderRealms.Add($uri, "urn:sp2010:adfs:www-aperture")

$t.Update()

Code Example: Script to add an item to ProviderRealms collection of a Trusted Identity Token Issuer

Configuring the SharePoint Web Applications to Use the Trusted Provider

Now, we should be able to configure the web applications to accept claims from ADFS.

Go to Central Administration > Application Management > Manage Web Applications.

 

 


Click the web application, then hit Authentication Providers in the Ribbon.

 


Click each of the three links in turn, and do the following for each Zone.

 


Enable the "Aperture ADFS" provider by checking the boxes, then hit Save.

It's All Downhill from Here!

So, we've done all the configuration for both ADFS and SharePoint. It's time to test things to see if they work.

Honestly, even though I have done maybe more than a dozen of these configurations before, this did not go well for me this time. Chalk it up to burning the midnight oil I guess. Several screwdrivers later, I was eventually able to get to the answer – and even finished before the sun came up. I'm assuming you value your sleep though, so I'm going ot share a little of the pain with you in the hopes that you'll have an easier time of it.

Testing the ADFS Proxy Login Page

Browsing to https://www.apertuelabs.local will give you SharePoint's realm selector prompt.

 

Well, at this point SharePoint did redirect me to the ADFS proxy URL. But, instead of getting the expected, I got a 404 Not Found. Turned out the Default Web Site hadn't been started. Started it and I get a different error instead. This time, the kind of error that is really annoying because it's under a locked filing cabinet in a disused bathroom at the bottom of the [collapsed] basement stairs! (The "Beware the Leopard" sign had apparently been stolen by someone who came before me.)

 

"Never you mind!" I says. "I knows me lotsa tricks fo' working an' lurking around thee ol' Aye Dee Eff Ess, I does! We'll sort this bugger out, we will!"

So I jump into the web.config in C:\inetpub\adfs\ls and make some changes. Uncomment a couple lines and make a little cosmetic modification while I'm there.

<add key="displayExceptions" />

<add key="logo" value="aperture_logo.png" />

Excerpt from file C:\inetpub\adfs\ls\web.config

 

Well now, that extra information was certainly very helpful, wasn't it? What do you mean, "no"?

This error happens because the ADFS Proxy can't talk to the ADFS Server. Well, that can happen for lots of reasons.

A Night Spent Shaving Yaks on the ADFS Server

Investigation into this error led me to some errors in the ADFS server event logs that were preventing ADFS Server from starting. My certificate s were set up incorrectly. Before I got to the heart of the problem, I went down a rabbit hole for a little while, thinking maybe my issue was insufficient rights for the service account. I was wrong about that, but I'll show you how to check for the permissions anyway.

 

 

 

 

 

 

 

 

 

 

 

Eventually, I figured out that my problem was that my certificates were just plain wrong. Specifically, I am talking about the settings for the certificate template. These are what led me to create the Legacy STS template I talked about previously. This was the point where I had to go back in time and do everything right from the beginning, thus leading to my recommendation that – well – that you do everything right from the beginning. :-)

 

Test #2 of the ADFS Login Page

Well, I finally got all of that sorted out. Looks like I'm not getting any sleep before heading to Virginia for SharePoint Saturday (The Conference). <arm-stretch><yawn /></arm-stretch>

 


Notice that the URL for the browser and the name as reported by ADFS reflect the fact that we're hitting the ADFS server through the proxy.

Later, I'll change the name of the ADFS Service to be something more cosmetically appealing. Note that this setting will be passed through to every proxy you create, in case this affects you in a multi-tenant situation.

 


Oh, yes? Is this another one of those really *helpful* error screens? Let me just see if I can find the answer here in Nuclear Reactors for Dummies. <pageflip/><pageflip/><pageflip/><pageflip/><pageflip/><pageflip/><pageflip/><pageflip/><pageflip/><pageflip/> Ahh, the re we go!

Jumping into web.config for SharePoint to expose the error. Refresh. And…

 

Aaagh! Okay, well maybe that one's my fault. I have kind of made a mess of things.

A little help from Jimmie's Sharings on MSDN Blogs, who had the same problem, and I was able to cobble together a PowerShell to fix myself up. Seems I'd forgotten to update the signing certificate for the trusted identity provider when I replaced the certificate for ADFS after switching templates.

Setting Right for Claims Based Users

Another try, and…

 


Okay, that's not so bad. It means I just have to add some rights for the claims-based version of DEMO\Administrator. SharePoint treats the ADFS and Windows Authentication versions of the same user as different identities.

But, in order to login as the other account, I have to delete my cookies.

 

Rights are granted in Site Actions > Site Settings > people and Groups just like for Windows users.

 


Click the address book icon to bring up the people picker.

 


This is a multi-step process: 1) Type the UPN for the user you want to add. 2) Click "Account" to show only account claims based on UPN, otherwise you'll see three identical claims. 3) Click the only remaining claim. 4) Click Add button to add it to the list. Optionally, you can add multiple users in the way before you continue. 5) Click OK when done.

 


Your resolved claims will appear in the list. Sometimes, a claim may be listed here with a red underline. In those cases, click the name to bring up a list of claims to choose that will resolve the ambiguity.

Final Test: 3rd Time is the Charm

Need to delete my cookies again, just to be sure. Let's try the federated login again.

 


Realm selector: That's getting old. :-|

 


Credentials entered, and... <drumroll />

 


All Right!! It works!

Adding Encryption on the SharePoint STS

Encryption and signing of certificate from the SharePoint server is handled entirely in the web.config for the SharePoint application. Let's give it a try, shall we?

Creating a Certificate for SharePoint STS Token Encryption


Start in the Certificate Management Console, as usual.

   


Choose the Legacy STS template to ensure ADFS won't choke on it.

 


Provide a subject name. Unlike an SSL certificate, I don't think it really matter what you provide.

CN=sts.aperturelabs.local
O=Aperture Laboratories
OU=AS Enrichment Center
L=Knoxville
S=TN
C=US


Give it a name and description so you can remember what it's for.

Other tabs should be okay with the default settings.

 

 

 

 

Setting up the Web Server

Once we have the certificate, we can configure SharePoint to start encrypting tokens. This has to be done for each web.config file on sites that leverage ADFS. So, that's three files in our case. Each config file is located in the root of the web site in IIS, under C:\inetpub\wwwroot\wss\VirtualDirectories.

Find the "microsoft.identityModel" section near the bottom of the file. You need to change the file to add the following extra elements and attributes.

<microsoft.identityModel>

<service saveBootstrapTokens="true">

<audienceUris />

<issuerNameRegistry type="Microsoft.SharePoint.IdentityModel.SPPassiveIssuerNameRegistry, Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" />

<securityTokenHandlers>

<clear />

<add type="Microsoft.IdentityModel.Tokens.X509SecurityTokenHandler, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />

<add type="Microsoft.SharePoint.IdentityModel.SPSaml11SecurityTokenHandler, Microsoft.SharePoint.IdentityModel, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c">

<samlSecurityTokenRequirement>

<nameClaimType value="http://schemas.microsoft.com/sharepoint/2009/08/claims/userid" />

</samlSecurityTokenRequirement>

</add>

<add type="Microsoft.SharePoint.IdentityModel.SPTokenCache, Microsoft.SharePoint.IdentityModel, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" />

<!-- added: must be added to support encrypted tokens from ADFS -->

<add type="Microsoft.IdentityModel.Tokens.EncryptedSecurityTokenHandler, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />

<!-- END added -->

</securityTokenHandlers>

<!-- added: must be added to support encrypted tokens from ADFS -->

<serviceCertificate>

<certificateReference x509FindType="FindBySubjectName" findValue="sts.aperturelabs.local" storeLocation="LocalMachine" storeName="My" />

</serviceCertificate>

<!-- END added -->

<federatedAuthentication>

<wsFederation passiveRedirectEnabled="false" issuer="https://none" realm="https://none" />

<!-- added domain below so that other web sites can share cookies to this one -->

<cookieHandler mode="Custom" domain=".aperturelabs.local" path="/">

<customCookieHandler type="Microsoft.SharePoint.IdentityModel.SPChunkedCookieHandler, Microsoft.SharePoint.IdentityModel, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" />

</cookieHandler>

</federatedAuthentication>

</service>

</microsoft.identityModel>

File excerpt: web.config

After making these changes, you need to adjust the settings in your ADFS Relying Party configuration to adjust to the change.

Export a copy of your certificate (without the private key) and place it on the ADFS server.

At this point, you also need to ensure the SharePoint application pool has access to the private key for this certificate. This is done on SMARTYPANTS using the Certificate Management console. Add DEMO\ap-aperture permissions in the usual way. (This was covered in an earlier section.)

 

I then imported the certificate to the machine store on MASTERCONTROL.

Now we can set the encryption certificate in ADFS Management Console. It turns out, you need the *.CER file to do this, so theoretically you can just skip putting the certificate into the machine store.

 

 

 

 

This configuration does not include a signature.

A Moment to Review

Now, you'll just have to take my word for it, but after I did all this, it worked great. I had a small error because I hadn't given the application pool the key access rights I described above, but that was easily fixed and everything continued to work fine.

What do we have now, and is it any different than it was yesterday? Well, instead of three separate sites that use Windows Authentication, we now have three separate sites that use can use either ADFS or Windows Authentication. We have the added nuisance of a realm selector page, every time we log in we now have to choose where we want to log in from.

I had assumed that logging in via our public (anonymous HTTP) web site still isn't supported. In past deployments, I have definitely had problems with this where I got the infamous cookie looping problem. Maybe I didn't face this because the DNA names for our two sites are identical. Maybe it worked well because we added the domain attribute to the cookie handler in web.config. I'll never know, because right now I'm not going to test it. There are definitely configurations where it's a problem, and solving that requires code – code that won't be needed today.

But, as it turns out, we also can't effectively log out of SharePoint anymore, or switch users. So, there are still problems with the configuration that need to be addressed. In the next section, we're going to introduce some code to solve these problems, and add some enhancements too.

As it happens, I'm also giving my presentation at SharePoint Saturday tomorrow, so it will probably be a day or two before the next installment in this series hit the web.

See you on the other side!

More Reading

http://adfs2.blogspot.com/2011/02/adfs-20-setup-configuration.html
http://technet.microsoft.com/en-us/library/dd807040(WS.10).aspx
http://marcvaneijk.wordpress.com/2010/06/12/sharepoint-2010-and-adfs-2-0-the-complete-step-by-step-guide/
http://fimguru.com/2010/06/installation-of-ad-fs-2-0-federation-proxy/
http://blogs.technet.com/b/adfs/archive/2008/06/04/interesting-common-problem-when-adding-an-adfs-proxy.aspx
Tags: SharePoint 2010, Configuration