Yet another presentation on the docket! I submitted an abstract to SharePoint Summit 2011 and they accepted! I will be presenting on SharePoint and how it manages Identity. More specifically, how SharePoint 2010 uses WIF to handle Claims based authentication and Federation.
Here are the details
Event: SharePoint Summit 2011, January 31st 2011 – February 2nd, 2011
When: 11:30 a.m. - 12:45 p.m. February 1st, 2011
Where: Four Seasons Hotel, Toronto
Abstract: Managing identities within an organization is relatively easy. However, as business changes, we need to be able to adapt quickly. Identity is something that often gets overlooked in adaptation. In this session we will discuss the Windows Identity Foundation and how SharePoint uses it to adapt easily to change.
Link: http://www.sharepointsummit2011.com/Toronto/conference_day2.htm#session_7_3
Earlier this morning I got an email from John
Bristowe congratulating me on being selected to present a session for the local
flavours track at TechDays in Toronto!
This bumps
up my count to 2. Needless to say I am REALLY excited.
I was a little disappointed to find out there weren’t any sessions on the Windows
Identity Foundation, so that just meant I had to submit my own to the local flavours
track…and they accepted it! Here are the details:
October 27, 3:40 PM to 4:45 PM
Breakout | LFT330: Windows Identity Foundation Simplified: All the Scary Things
Made Un-Scary
The Windows Identity Foundation helps simplify user access for developers by externalizing
user access from applications via claims and reducing development effort with pre-built
security logic and integrated .NET tools. This presentation is an intimate discussion
on the basics of the Windows Identity Foundation and its claims model. In this session,
you’ll learn how to refactor an existing sample set of applications to use WIF, to
connect identities to the Cloud, and to remove the burden of managing multiple disparate
user stores.
Location: Metro Toronto Convention
Centre - South Building (255 Front Street West, Toronto)
Room: TBA
There are times when you need to question what you are doing, and why you are doing
it. Take for instance the “evercookie” at http://samy.pl/evercookie/.
I came across this when Kevin Dente posted
a link to it on Twitter.
The jist of it is to use all the available resources of the browser and it’s plugins
to create a truly persistent cookie across browser resets and cookie cleanups.
I’ll admit, it’s kind of a neat idea, but realistically, it will only be used for
bad. As Kevin said, no good can come of this.
Now, nothing is ever truly persistent when it comes to browsers. At some point
you can clean everything. The problem is the plugins. Flash is…well, I
hate Flash. It is an abomination. Then there is Silverlight. Plus
Java, and any plugin or ActiveX control that ties into the browser that stores data
locally.
While I could get into the privacy and security debate over all of this, what it really
boils down to is that it’s just really annoying. I don’t want websites keeping
persistent data on my machine if I don’t want them to. It’s my PC, not theirs.
So I’ve started work on a little script. It will clear cache of IE 7+ and delete
all persistent storage for Flash, Java, and Silverlight.
Keep in mind this will delete your history as well!
RunDll32.exe InetCpl.cpl,ClearMyTracksByProcess 8
RunDll32.exe InetCpl.cpl,ClearMyTracksByProcess 2
RunDll32.exe InetCpl.cpl,ClearMyTracksByProcess 1
RunDll32.exe InetCpl.cpl,ClearMyTracksByProcess 16
RunDll32.exe InetCpl.cpl,ClearMyTracksByProcess 32
RunDll32.exe InetCpl.cpl,ClearMyTracksByProcess 255
RunDll32.exe InetCpl.cpl,ClearMyTracksByProcess 4351
cd %appdata%
cd "Macromedia\Flash Player\"
rmdir "#SharedObjects" /S /Q
cd %appdata%
cd "Macromedia\Flash Player\macromedia.com\support\flashplayer\"
rmdir "sys" /S /Q
cd "C:\Program Files (x86)\Java\jre6\bin"
javaws -Xclearcache -silent -Xnosplash
cd "%userprofile%"
cd AppData\LocalLow\Microsoft\Silverlight"
rmdir "is" /S /Q
Now, I should also give a word of caution. This is by no means a sure-fire way
to protect your privacy. That’s pretty hard to do. This is only designed
to do a very simple cleanup of the usual suspects. If you are really wanting
to keep your browsing anonymous, turn off all plugins, turn off all scripting, and
run in InPrivate Browsing mode.
I’ll update the script as necessary over time.
When you install an instance of Active Directory Federation Services v2, amongst other
things it will create a website within IIS to use as it’s Secure Token Service.
This is sort of fundamental to the whole design. There are some interesting
things to note about the situation though.
When Microsoft (or any ISV really) releases a new application or server that has a
website attached to it, they usually deliver it in a precompiled form, so all we do
is point IIS to the binaries and config files and we go from there. This serves
a number of purposes usually along the lines of performance, Intellectual Property
protection, defense in depth protection, etc. Interestingly though, when the
installer creates the application for us in IIS, it drops source code instead of a
bunch of assemblies.
There is a valid reason for this.
It gives us the opportunity to do a couple things. First, we can inspect the
code. Second, we can easily modify the code. Annoyingly, they don’t give
us a Visual Studio project to do so. Let’s create one then.
First off, lets take a look at what was created by the installer. By default
it drops the files in c:\inetpub\adfs\ls. We are given a few files and folders:
There isn’t much to it. These files only contain a few lines of code.
Next we create the actual project.
DISCLAIMER: I will not be held responsible if things break
or the server steals your soul. Please do NOT (I REPEAT) do NOT do this with
production servers please! (Notice I said please twice?)
Since we want to create a Visual Studio project, and since ADFS cannot be installed
on a workstation, we have two options:
-
Install Visual Studio on the server running ADFS
-
Copy the files to your local machine
Each options have their tradeoffs. The first requires a bit of a major overhaul
of your development environment. It’s very similar to SharePoint 2007 development.
The second option makes developing a lot easier, but testing is a pain because the
thing won’t actually work properly without the Windows Services running. You
would need to deploy the code to a test server with ADFS installed.
Since I have little interest in rebuilding my development box, I went with the second
option.
Okay, back to Visual Studio. The assemblies referenced were all built on Framework
3.5, so for the sake of simplicity lets create a 3.5 Web Application:
I haven’t tested 4.0 yet.
Since this is a Web Application and not a Web Site within Visual Studio, we need to
generate the *.designer.cs files for all the *.aspx pages. Right-click your
project and select Convert to Web Application:
At this point if you tried to compile the application it wouldn’t work. We are
missing a few assembly references. First, add Microsoft.IdentityModel.
This should be in the GAC or the Reference Assemblies folder in Program Files.
Next, go back to the ADFS server and navigate to C:\Program Files\Active Directory
Federation Services 2.0 and copy the following files:
-
Microsoft.IdentityServer.dll
-
Microsoft.IdentityServer.Compression.dll
Add these assemblies as references. The web application should compile successfully.
Next we need to sign the web application’s assemblies. If you have internal
policies on assembly signing, follow those. Otherwise double-click the properties
section in Solution Explorer and navigate to Signing:
Choose a key file or create a new one. Rebuild the web application.
So far we haven’t touched a line of code. This is all general deployment stuff.
You can deploy the web application back to the ADFS server and it should work as if
nothing had changed. You have a few options for this. The Publishing Features
in Visual Studio 2010 are awesome. Right click the project and Publish it:
Since I set up a test box for ADFS development, I’m just going to overwrite the files
on the server:
Pro Tip: If you do something terrible and need to revert back to original code (what
part of don’t do this on a production box didn’t make sense?
)
you can access the original files from C:\Program Files\Active Directory Federation
Services 2.0\WSFederationPassive.Web.
At this point we haven’t done much, but we now have a stepping point to modify the
default behavior of ADFS. This could range from simple theme changes to better
suit corporate policy, or to completely redefine the authentication workflow.
This also gives us the ability to better protect our code in the event that IIS craps
out and shows contents of files, not to mention the (albeit minor) performance boost
we get because the website doesn’t need to be recompiled.
Have fun!
In a domain environment it is really useful to switch user contexts in a web application.
This could be if you are needing to log in with credentials that have elevated permissions
(or vice-versa) or just needing to log in as another user.
It’s pretty easy to do this with Windows Identity Foundation and Claims Authentication.
When the WIF framework is installed, a service is installed (that is off by default)
that can translate Claims to Windows Tokens. This is called (not surprisingly)
the Claims to Windows Token Service or (c2WTS).
Following the deploy-with-least-amount-of-attack-surface methodology, this
service does not work out of the box. You need to turn it on and enable which
user’s are allowed to impersonate via token translation. Now, this doesn’t mean
which users can switch, it means which users running the process are allowed to switch.
E.g. the process running the IIS application pools local service/network service/local
system/etc (preferably a named service user other than system users).
To allow users to do this go to C:\Program Files\Windows Identity Foundation\v3.5\c2wtshost.exe.config
and add in the service users to <allowedCallers>:
<windowsTokenService>
<!--
By default no callers are allowed to use the Windows
Identity Foundation Claims To NT Token Service.
Add the identities you wish to allow below.
-->
<allowedCallers>
<clear/>
<!-- <add value="NT AUTHORITY\Network Service"
/> -->
<!-- <add value="NT AUTHORITY\Local Service" />
–>
<!-- <add value="nt authority\system" /> –>
<!-- <add value="NT AUTHORITY\Authenticated Users"
/> -->
</allowedCallers>
</windowsTokenService>
You should notice that by default, all users are not allowed. Once you’ve done
that you can start up the service. It is called Claims to Windows Token
Service in the Services MMC snap-in.
That takes care of the administrative side of things. Lets write some code.
But first, some usings:
using System;
using System.Linq;
using System.Security.Principal;
using System.Threading;
using Microsoft.IdentityModel.Claims;
using Microsoft.IdentityModel.WindowsTokenService;
The next step is to actually generate the token. From an architectural perspective,
we want to use the UPN claims type as that’s what the service wants to see.
To get the claim, we do some simple LINQ:
IClaimsIdentity identity = (ClaimsIdentity)Thread.CurrentPrincipal.Identity;
string upn = identity.Claims.Where(c => c.ClaimType == ClaimTypes.Upn).First().Value;
if (String.IsNullOrEmpty(upn))
{
throw new Exception("No UPN claim found");
}
Following that we do the impersonation:
WindowsIdentity windowsIdentity = S4UClient.UpnLogon(upn);
using (WindowsImpersonationContext ctxt = windowsIdentity.Impersonate())
{
DoSomethingAsNewUser();
ctxt.Undo(); // redundant with using { } statement
}
To release the token we call the Undo() method, but if you are within a using { }
statement the Undo() method is called when the object is disposed.
One thing to keep in mind though. If you do not have permission to impersonate
a user a System.ServiceModel.Security.SecurityAccessDeniedException will be thrown.
That’s all there is to it.
Implementation Details
In my opinion, these types of calls really shouldn’t be made all that often.
Realistically you need to take a look at how impersonation fits into the application
and then go from there. Impersonation is pretty weighty topic for discussion,
and frankly, I’m not an expert.
there comes a point where using an eavesdropping application to catch packets as they
fly between Secure Token Services and Relying Parties becomes tiresome. For
me it came when I decided to give up on creating a man-in-the-middle between SSL sessions
between ADFS and applications. Mainly because ADFS doesn’t like that.
At all.
Needless to say I wanted to see the tokens. Luckily, Windows Identity Foundation
has the solution by way of the Bootstrap token. To understand what it is, consider
how this whole process works. Once you’ve authenticated, the STS will POST a
chunk of XML (the SAML Token) back to the RP. WIF will interpret it as necessary
and do it’s magic generating a new principal with the payload. However, in some
instances you need to keep this token intact. This would be the case if you
were creating a web service and needed to forward the token. What WIF does is
generate a bootstrap token from the SAML token, in the event you needed to forward
it off to somewhere.
Before taking a look at it, let's add in some useful using statements:
using System;
using System.IdentityModel.Tokens;
using System.Text;
using System.Threading;
using System.Xml;
using Microsoft.IdentityModel.Claims;
using Microsoft.IdentityModel.Tokens;
using Microsoft.IdentityModel.Tokens.Saml11;
The bootstrap token is attached to IClaimsPrincipal identity:
SecurityToken bootstrapToken = ((IClaimsPrincipal)Thread.CurrentPrincipal).Identities[0].BootstrapToken;
However if you do this out of the box, BootstrapToken will be null. By default,
WIF will not save the token. We need to explicitly enable this in the web.config
file. Add this line under <microsoft.IdentityModel><service><securityTokenHandlers>:
<securityTokenHandlerConfiguration saveBootstrapTokens="true" />
Once you’ve done that, WIF will load the token.
The properties are fairly straightforward, but you can’t just get a blob from it:
Luckily we have some code to convert from the bootstrap token to a chunk of XML:
SecurityToken bootstrapToken = ((IClaimsPrincipal)Thread.CurrentPrincipal).Identities[0].BootstrapToken;
StringBuilder sb = new StringBuilder();
using (var writer = XmlWriter.Create(sb))
{
new Saml11SecurityTokenHandler(new SamlSecurityTokenRequirement()).WriteToken(writer, bootstrapToken);
}
string theXml = sb.ToString();
We get a proper XML document:
That’s all there is to it.
Just a quick little collection of useful code snippets when dealing with certificates.
Some of these don’t really need to be in their own methods but it helps for clarification.
Namespaces for Everything
using System.Security.Cryptography.X509Certificates;
using System.Security;
Save Certificate to Store
// Nothing fancy here. Just a helper method to parse strings.
private StoreName parseStoreName(string name)
{
return (StoreName)Enum.Parse(typeof(StoreName), name);
}
// Same here
private StoreLocation parseStoreLocation(string location)
{
return (StoreLocation)Enum.Parse(typeof(StoreLocation), location);
}
private void saveCertToStore(X509Certificate2 x509Certificate2, StoreName storeName, StoreLocation storeLocation)
{
X509Store store = new X509Store(storeName, storeLocation);
store.Open(OpenFlags.ReadWrite);
store.Add(x509Certificate2);
store.Close();
}
Create Certificate from byte[] array
private X509Certificate2 CreateCertificateFromByteArray(byte[] certFile)
{
return new X509Certificate2(certFile);
// will throw exception if certificate has private key
}
The comment says that it will throw an exception if the certificate has a private
key because the private key has a password associated with it. If you don't pass the
password as a parameter it will throw a System.Security.Cryptography.CryptographicException
exception.
Get Certificate from Store by Thumbprint
private bool FindCertInStore(
string thumbprint,
StoreName storeName,
StoreLocation storeLocation,
out X509Certificate2 theCert)
{
theCert = null;
X509Store store = new X509Store(storeName, storeLocation);
try
{
store.Open(OpenFlags.ReadWrite);
string thumbprintFixed = thumbprint.Replace(" ", "").ToUpperInvariant();
foreach (var cert in store.Certificates)
{
if (cert.Thumbprint.ToUpperInvariant().Equals(thumbprintFixed))
{
theCert = cert;
return true;
}
}
return false;
}
finally
{
store.Close();
}
}
Have fun!
Straight from Microsoft this is what the Windows Identity Foundation is:
Windows Identity Foundation helps .NET developers build claims-aware applications
that externalize user authentication from the application, improving developer productivity,
enhancing application security, and enabling interoperability. Developers can enjoy
greater productivity, using a single simplified identity model based on claims. They
can create more secure applications with a single user access model, reducing custom
implementations and enabling end users to securely access applications via on-premises
software as well as cloud services. Finally, they can enjoy greater flexibility in
application development through built-in interoperability that allows users, applications,
systems and other resources to communicate via claims.
In other words it is a method for centralizing user Identity information, very much
like how the Windows Live and OpenID systems work. The system is reasonably
simple. I have a Membership data store that contains user information.
I want (n) number of websites to use that membership store, EXCEPT I don’t want each
application to have direct access to membership data such as passwords. The
way around it is through claims.
In order for this to work you need a central web application called a Secure Token
Service (STS). This application will do authentication and provide a set of
available claims. It will say “hey! I am able to give you the person’s email
address, their username and the roles they belong to.” Each of those pieces
of information is a claim. This message exists in the application’s Federation
Metadata.
So far you are probably saying “yeah, so what?”
What I haven’t mentioned is that every application (called a Relying Party) that uses
this central application has one thing in common: each application doesn’t have to
handle authentication – at all. Each application passes off the authentication
request to the central application and the central application does the hard work.
When you type in your username and password, you are typing it into the central application,
not one of the many other applications. Once the central application authenticates
your credentials it POST’s the claims back to the other application. A diagram
might help:
Image borrowed from the Identity Training kit (http://www.microsoft.com/downloads/details.aspx?familyid=C3E315FA-94E2-4028-99CB-904369F177C0&displaylang=en)
The key takeaway is that only one single application does authentication. Everything
else just redirects to it. So lets actually see what it takes to authenticate
against an STS (central application). In future posts I will go into detail
about how to create an STS as well as how to use Active Directory Federation Services,
which is an STS that authenticates directly against (you guessed it) Active Directory.
First step is to install the Framework and SDK.
WIF RTW: http://www.microsoft.com/downloads/details.aspx?FamilyID=eb9c345f-e830-40b8-a5fe-ae7a864c4d76&displaylang=en
WIF SDK: http://www.microsoft.com/downloads/details.aspx?displaylang=en&FamilyID=c148b2df-c7af-46bb-9162-2c9422208504
The SDK will install sample projects and add two Visual Studio menu items under the
Tools menu. Both menu items do essentially the same thing, the difference being
that “Add STS Reference” pre-populates the wizard with the current web application’s
data.
Once the SDK is installed start up Visual Studio as Administrator. Create a
new web application. Next go to the Properties section and go into the Web section.
Change the Server Settings to use IIS. You need to use IIS. To
install IIS on Windows 7 check out this post.
So far we haven’t done anything crazy. We’ve just set a new application to use
IIS for development. Next we have some fun. Let’s add the STS Reference.
To add the STS Reference go to Tools > Add Sts Reference… and fill out the initial
screen:
Click next and it will prompt you about using an HTTPS connection. For the sake
of this we don’t need HTTPS so just continue. The next screen asks us about
where we get the STS Federation Metadata from. In this case I already have an
STS so I just paste in the URI:
Once it downloads the metadata it will ask if we want the Token that the STS sends
back to be encrypted. My recommendation is that we do, but for the sake of this
we won’t.
As an aside: In order for the STS to encrypt the token it will use a public key to
which our application (the Relying Party) will have the private key. When we
select a certificate it will stick that public key in the Relying Party’s own Federation
Metadata file. Anyway… When we click next we are given a list of available Claims
the STS can give us:
There is nothing to edit here; it’s just informative. Next we get a summary
of what we just did:
We can optionally schedule a Windows task to download changes.
We’ve now just added a crap-load of information to the *.config file. Actually,
we really didn’t. We just told ASP.NET to use the Microsoft.IdentityModel.Web.WSFederationAuthenticationModule
to handle authentication requests and Microsoft.IdentityModel.Web.SessionAuthenticationModule
to handle session management. Everything else is just boiler-plate configuration.
So lets test this thing:
-
Hit F5 – Compile compile compile compile compile… loads up http://localhost/WebApplication1
-
Page automatically redirects to https://login.myweg.com/login.aspx?ReturnUrl=%2fusers%2fissue.aspx%3fwa%3dwsignin1.0%26wtrealm%3dhttp%253a%252f%252flocalhost%252fWebApplication1%26wctx%3drm%253d0%2526id%253dpassive%2526ru%253d%25252fWebApplication1%25252f%26wct%3d2010-08-03T23%253a03%253a40Z&wa=wsignin1.0&wtrealm=http%3a%2f%2flocalhost%2fWebApplication1&wctx=rm%3d0%26id%3dpassive%26ru%3d%252fWebApplication1%252f&wct=2010-08-03T23%3a03%3a40Z (notice
the variables we’ve passed?)
-
Type in our username and password…
-
Redirect to http://localhost/WebApplication1
-
Yellow Screen of Death
Wait. What? If you are running IIS 7.5 and .NET 4.0, ASP.NET will probably
blow up. This is because the data that was POST’ed back to us from the STS had
funny characters in the values like angle brackets and stuff. ASP.NET does not
like this. Rightfully so, Cross Site Scripting attacks suck. To resolve
this you have two choices:
-
Add <httpRuntime requestValidationMode="2.0" /> to your web.config
-
Use a proper RequestValidator that can handle responses from Token Services
For the sake of testing add <httpRuntime requestValidationMode="2.0"
/> to the web.config and retry the test. You should be redirected to http://localhost/WebApplication1 and
no errors should occur.
Seems like a pointless exercise until you add a chunk of code to the default.aspx
page. Add a GridView and then add this code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Threading;
using System.IdentityModel;
using System.IdentityModel.Claims;
using Microsoft.IdentityModel.Claims;
namespace WebApplication1
{
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
IClaimsIdentity claimsIdentity = ((IClaimsPrincipal)(Thread.CurrentPrincipal)).Identities[0];
GridView1.DataSource = claimsIdentity.Claims;
GridView1.DataBind();
}
}
}
Rerun the test and you should get back some values. I hope some light bulbs
just turned on for some people :)
Over the past few months I have seen quite a few really cool technologies released
or announced, and I believe they have a very real potential in many markets.
A lot of companies that exist outside the realm of Software Development, rarely have
the opportunity to use such technologies.
Take for instance the company I work for: Woodbine
Entertainment Group. We have a few different businesses, but as a whole
our market is Horse Racing. Our business is not software development.
We don’t always get the chance to play with or use some of the new technologies released
to the market. I thought this would be a perfect opportunity to see what it
will take to develop a new product using only new technologies.
Our core customer pretty much wants Race information. We have proof of this
by the mere fact that on our two websites, HorsePlayer
Interactive and our main site, we have dedicated applications for viewing Races.
So lets build a third race browser. Since we already have a way of viewing races
from your computer, lets build it on the new Windows Phone 7.
The Phone – The application
This seems fairly straightforward. We will essentially be building a Silverlight
application. Let’s take a look at what we need to do (in no particular order):
-
Design the interface – Microsoft has loads of guidance on following with the Metro
design. In future posts I will talk about possible designs.
-
Build the interface – XAML and C#. Gotta love it.
-
Build the Business Logic that drives the views – I would prefer to stay away from
this, suffice to say I’m not entirely sure how proprietary this information is
-
Build the Data Layer – Ah, the fun part. How do you get the data from our internal
servers onto the phone? Easy, OData!
The Data
We have a massive database of all the Races on all the tracks that you can wager on
through our systems. The data updates every few seconds relative to changes
from the tracks for things like cancellations or runner odds. How do we push
this data to the outside world for the phone to consume? We create a WCF Data
Service:
-
Create an Entities Model of the Database
-
Create Data Service
-
Add Entity reference to Data Service (See code below)
public class RaceBrowserData : DataService
{ public static void InitializeService(DataServiceConfiguration config) { if (config
== null) throw new ArgumentNullException("config"); config.UseVerboseErrors
= true; config.SetEntitySetAccessRule("*", EntitySetRights.AllRead); //config.SetEntitySetPageSize("*",
25); config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2;
} }
That’s actually all there is to it for the data.
The Authentication
The what? Chances are the business will want to limit application access to
only those who have accounts with us. Especially so if we did something like
add in the ability to place a wager on that race. There are lots of ways to
lock this down, but the simplest approach in this instance is to use a Secure Token
Service. I say this because we already have a user store and STS, and duplication
of effort is wasted effort. We create a STS Relying Party (The application that
connects to the STS):
-
Go to STS and get Federation Metadata. It’s an XML document that tells relying
parties what you can do with it. In this case, we want to authenticate and get
available Roles. This is referred to as a Claim. The role returned is
a claim as defined by the STS. Somewhat inaccurately, we would do this:
-
App: Hello! I want these Claims for this user: “User Roles”. I am now going
to redirect to you.
-
STS: I see you want these claims, very well. Give me your username and password.
-
STS: Okay, the user passed. Here are the claims requested. I am going
to POST them back to you.
-
App: Okay, back to our own processes.
-
Once we have the Metadata, we add the STS as a reference to the Application, and call
a web service to pass the credentials.
-
If the credentials are accepted, we get returned the claims we want, which in this
case would be available roles.
-
If the user has the role to view races, we go into the Race view. (All users
would have this role, but adding Roles is a good thing if we needed to distinguish
between wagering and non-wagering accounts)
One thing I didn’t mention is how we lock down the Data Service. That’s a bit
more tricky, and more suited for another post on the actual Data Layer itself.
So far we have laid the ground work for the development of a Race Browser application
for the Windows Phone 7 using the Entity Framework and WCF Data Services, as well
as discussed the use of the Windows Identity Foundation for authentication against
an STS.
With any luck (and permission), more to follow.
I’ve been working on getting a testable ADFS environment setup for evaluation and
development. Basically, because of laziness (and timeliness), I’m using Windows
Virtual PC to host Server 2008 guests for testing. I didn’t have the time to
setup a fully working x64 environment, so I couldn’t go to R2.
One of the issues I’ve been running into is that the Windows Service won’t start properly.
Or rather, at all. It’s running into a timing issue when running as Network
Service, as its timing out while waiting for a network connection. More Googling
with Bing returned the fix for me from here.
In the file [C:\Program Files\Active Directory Federation Services 2.0\Microsoft.IdentityServer.Servicehost.exe.config]
add this entry to it:
<runtime>
<generatePublisherEvidence enabled="false"/>
</runtime>
Other places have noted that this isn’t a problem on R2. I haven’t tested this
yet, so I don’t know if it’s true.