Imagine
your company maintains a shared repository of credentials that is based
on the standard ASP.NET Membership Providers infrastructure for
authenticating users, and you plan to use it for accessing both a
SharePoint site and a classic ASP.NET site. To implement a new STS for
this scenario, you first need to create a new website project of type
ASP.NET Empty Web Application in Visual Studio 2012.
Important
The WIF 1.0 SDK includes an STS Web Site template, but the WIF 4.5
SDK does not. Moreover, because many of the types and namespaces
defined in the WIF libraries were renamed and changed between WIF 1.0
and WIF 4.5, you cannot start creating an IP/STS project with WIF 1.0
and then upgrade it to WIF 4.5.
The project template prepares a new empty website project to which you must add a few pages and code files:
-
Default.aspx
. A welcome page providing some useful links to
interact with the IP/STS.
-
Issue.aspx
. The page that provides the authentication UI and that wraps the IP/STS service on the back end.
-
FederationMetadata.xml
. An XML file providing all the information about the
endpoint and the security configuration of the IP/STS. It is
fundamental, and, for security reasons, it will be digitally signed.
You can create it manually, or you can use some out-of-the-box classes
of WCF and WIF to generate it automatically.
Moreover, to use the WIF 4.5 libraries in the IP/STS website
project, you need to add references to the System.IdentityModel,
System.IdentityModel.Selectors, and System.IdentityModel.Services
assemblies.
Next, you need to configure the ASP.NET profile, membership, and
role providers. This example uses the ASP.NET Profile engine to store
information for custom user profiles, which will be converted into
claims.
As shown highlighted in bold, the configuration defines a user profile made of four properties:
-
Name. A string representing the user’s name
-
Email. A string representing the user’s email
-
Gender. A string representing the user’s gender
-
Favorite Color. A string providing the user’s favorite color
Later, you will use these profile properties to populate users’
claims. Moreover, in the “Creating a custom claims provider” section,
you will authorize users based on their gender and favorite color.
Now consider The ASPX code of the Issue.aspx page:
the ASPX code defining the Issue.aspx page. From a UI perspective, this
page provides only the controls for authenticating end users. Because
in the current sample IP/STS we will use the out-of-the-box Membership
Provider API of ASP.NET, the Issue.aspx page will simply contain an
ASP.NET Login web control.
As you can see, the core business logic of the Issue.aspx page is behind the OnAuthenticate event of the Login control, which is handled by the loginControl_Authenticate event handler method. By default, the Login
control authenticates users by itself, using ASP.NET membership.
Nevertheless, to implement a custom IP/STS, you will need to provide
some custom code for users’ authentication.
Aside
from implementing the authentication logic, the event handler simply
creates a .NET identity, which is an instance of a type implementing
the IIdentity interface, and passes it to a ProcessRequest method, which does the real job from the WS-Federation viewpoint.
As the code excerpt illustrates, aside from creating an instance of the ClaimsPrincipal type, the ProcessRequest method simply invokes the ProcessRequest method of the FederatedPassiveSecurityTokenServiceOperations type, which is available out of the box in WIF 4.5. That method accepts some arguments related to the current HTTP Request and Response objects, the current user principal, and an instance of a type that inherits from the SecurityTokenService
class, which is the real core engine of the IP/STS. The infrastructural
types are defined in a dedicated class library project so that the code
for the sample project can be better organized.
The source code of the DevLeapSecurityTokenServiceConfiguration class shows the implementation of the DevLeapSecurityTokenServiceConfiguration type, which is defined in the infrastructural class library and handles the creation of the custom SecurityTokenService instance.
The main part of the DevLeapSecurityTokenServiceConfiguration class is the constructor, which uses the base class constructor to define the type of the class inheriting from SecurityTokenService that will implement the STS business logic. In the current example, the class inheriting from SecurityTokenService is the DevLeapSecurityTokenService, shown in The source code of the DevLeapSecurityTokenService class.
The two key points of interest in the DevLeapSecurityTokenService class are the GetScope and GetOutputClaimsIdentity methods. The GetScope
method defines the scope of the token issuance. In particular, it
defines the X.509 certificate that will be used to sign and eventually
encrypt the security token that the IP/STS will release. In the GetScope
method, you could also validate the calling relying parties if you want
to accept token requests from authorized relying parties only—and
generally speaking, you should do that. Moreover, the GetOutputClaimsIdentity method is the core method of the STS and provides, as its result, an instance of the ClaimsIdentity type, which will represent the claims that will be included in the output security token. As shown in The source code of the DevLeapSecurityTokenService class, the DevLeapSecurityTokenService
class populates the collection of claims of the current user by
accessing his or her user profile and reading the list of available
claims from an XML file like the one shown in The XML file with the full list of claims provided by the sample IP/STS.
Notice that the claims defined in The XML file with the full list of claims provided by the sample IP/STS correspond exactly to the user-profile properties declared in the web.config file in An excerpt of the web.config file of the IP/STS sample web application.
Note
To create your own FederationMetadata.xml file, you can try two freely
distributed tools from Thinktecture: Federation Metadata Generator (http://static.thinktecture.com/christianweyer/FederationMetadataGenerator_1.0.zip) and the StarterSTS project (http://startersts.codeplex.com/). Be careful, however, because these tools target WIF 1.0, not
WIF 4.5. Although they are fine for generating the FederationMetadata
tool, you should not use them for creating an IP/STS. Moreover, if you
are looking for a ready to go IP/STS solution you can take a look at
the IdentityServer project made available by ThinkTecture at the
following URL: http://thinktecture.github.io/.
With the fundamental parts of the custom IP/STS
implementation in place, you’re ready to consume it, first from an
ASP.NET relying party and then from SharePoint 2013.