IT tutorials
 
Technology
 

Sharepoint 2013 : Claims-based authentication, federated identities, and OAuth (part 2) - Building an STS

9/21/2013 7:35:36 PM
- Free product key for windows 10
- Free Product Key for Microsoft office 365
- Malwarebytes Premium 3.7.1 Serial Keys (LifeTime) 2019

2. Implementing an IP/STS with WIF

WIF is a framework natively provided by Microsoft in Microsoft .NET Framework 4.5. WIF supports .NET developers while developing claims-based solutions, whether they work on the service provider side or implement an IP/STS of their own. Targeting .NET 3.5 and 4.0, WIF 1.0 is still available, as well. In fact, SharePoint 2013 internally uses WIF 1.0 with some custom extension libraries to provide OAuth support. The WIF 4.5 runtime is included in the .NET 4.5 runtime, while the WIF 1.0 runtime is available as a free download from http://www.microsoft.com/downloads/en/details.aspx?FamilyID=eb9c345f-e830-40b8-a5fe-ae7a864c4d76.

Note

If you need to develop custom solutions, download the .NET Framework 4.5 software development kit (SDK), which is included in Visual Studio 2012, and the Identity and Access Tool, which is available at http://visualstudiogallery.msdn.microsoft.com/e21bf653-dfe1-4d81-b3d3-795cb104066e. If you want to create custom solutions based on WIF 1.0, download the WIF 1.0 SDK, which is available at http://www.microsoft.com/downloads/en/details.aspx?FamilyID=c148b2df-c7af-46bb-9162-2c9422208504.

WIF 1.0 is compatible with WIF 4.5, so in this article you will worth with WIF 4.5 on the IP/STS side. (The WS-Federation active scenario is out of scope for this book.) In the next sections, you will learn how to use WIF 4.5 to implement an IP/STS solution, which can be used to implement a web-based WS-Federation passive requestor scenario, suitable for realizing a single-sign-on user experience shared across multiple sites, whether or not they are implemented with SharePoint. To better follow along, open the .NET solution called DevLeap.IPSTS, which is available in the companion code samples. To work with this code, you must have .NET 4.5, WIF 4.5, and the Identity and Access Tool. Remember, Visual Studio 2012 already includes WIF 4.5 as part of .NET 4.5.

2.1 Building an STS

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.

An excerpt of the web.config file of the IP/STS sample web application

<?xml version="1.0"?>
<configuration>
<!-- Configuration omitted for the sake of brevity -->
<system.web>
<compilation debug="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5" />
<authorization>
<deny users="?" />
</authorization>
<authentication mode="Forms">
<forms name=".DEVLEAPIPSTS"
requireSSL="true"
defaultUrl="~/Default.aspx"
loginUrl="~/Issue.aspx"
cookieless="UseDeviceProfile"
enableCrossAppRedirects="false"
slidingExpiration="false"
timeout="300" />
</authentication>
<membership defaultProvider="FBASQLMembershipProvider">
<providers>
<add connectionStringName="SharePointFBA" applicationName="/"
passwordAttemptWindow="5" enablePasswordRetrieval="false"
enablePasswordReset="false" requiresQuestionAndAnswer="true"
requiresUniqueEmail="true" passwordFormat="Hashed"
name="FBASQLMembershipProvider"
type="System.Web.Security.SqlMembershipProvider, System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
</providers>
</membership>
<roleManager enabled="true" defaultProvider="FBASQLRoleManager">
<providers>
<add connectionStringName="SharePointFBA" applicationName="/"
name="FBASQLRoleManager"
type="System.Web.Security.SqlRoleProvider, System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
</providers>
</roleManager>
<profile defaultProvider="FBASQLProfile">
<properties>
<add name="Name" type="String" />
<add name="Email" type="String" />
<add name="Gender" type="String" defaultValue="Neutral" />
<add name="FavoriteColor" type="String" defaultValue="Yellow" />
</properties>
<providers>
<add connectionStringName="SharePointFBA" applicationName="/"
name="FBASQLProfile"
type="System.Web.Profile.SqlProfileProvider, System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
</providers>
</profile>

</system.web>
<!-- Configuration omitted for the sake of brevity -->
</configuration>

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.

The ASPX code of the Issue.aspx page

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Issue.aspx.cs" Inherits="DevLeap.IPSTS.Issue" %>
<!DOCTYPE html>
<html >
<head runat="server">
<title>Sample IP/STS Issue Page</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:Login ID="loginControl" runat="server"
OnAuthenticate="loginControl_Authenticate" /> </div>
</form>
</body>
</html>

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.

A code excerpt illustrating the loginControl_Authenticate event handler method of the Login control

protected void loginControl_Authenticate(object sender, AuthenticateEventArgs e) {
IIdentity identity = null;
if (Membership.ValidateUser(loginControl.UserName, loginControl.Password)) {
// Authentication succeeded
identity = new GenericIdentity(loginControl.UserName);
}
else {
return;
}
if (identity != null) {
// Set Authentication cookie
FormsAuthentication.SetAuthCookie(identity.Name,
loginControl.RememberMeSet);
// Generate and issue the security token
ProcessRequest(identity);
}
else {
return;
}
}

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.

The full implementation of the ProcessRequest method within the Issue.aspx page

protected void ProcessRequest(IIdentity identity) {
var principal = new ClaimsPrincipal(
new ClaimsIdentity[] { (ClaimsIdentity)identity });
FederatedPassiveSecurityTokenServiceOperations.ProcessRequest(
this.Request,
principal,
DevLeapSecurityTokenServiceConfiguration.Current.
CreateSecurityTokenService(),
this.Response);
}

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 source code of the DevLeapSecurityTokenServiceConfiguration class

public class DevLeapSecurityTokenServiceConfiguration : SecurityTokenServiceConfiguration
{
private static Lazy<DevLeapSecurityTokenServiceConfiguration>
_configuration =
new Lazy<DevLeapSecurityTokenServiceConfiguration>(delegate {
return (new DevLeapSecurityTokenServiceConfiguration());
}, true);
public DevLeapSecurityTokenServiceConfiguration() :
base(ConfigurationManager.AppSettings["IssuerUri"],
X509Helper.RetrieveSigningCredentials()) {
SecurityTokenService = typeof(DevLeapSecurityTokenService);
}
public static DevLeapSecurityTokenServiceConfiguration Current {
get { return _configuration.Value; }
}
}

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 source code of the DevLeapSecurityTokenService class

public class DevLeapSecurityTokenService : SecurityTokenService {
/// <summary>
/// Creates an instance of DevLeapSecurityTokenService.
/// </summary>
/// <param name="configuration">The SecurityTokenServiceConfiguration.
/// </param>
public DevLeapSecurityTokenService(SecurityTokenServiceConfiguration configuration)
: base(configuration) {
}
/// <summary>
/// This method returns the configuration for the token issuance request.
/// The configuration is represented by the Scope class. In our case,
/// we are only capable of issuing a token for a single RP identity
/// represented by the EncryptingCertificateName.
/// </summary>
/// <param name="principal">The caller's principal.</param>
/// <param name="request">The incoming RST.</param>
/// <returns>The scope information to be used for
/// the token issuance.</returns>
protected override Scope GetScope(System.Security.Claims.ClaimsPrincipal
principal,
System.IdentityModel.Protocols.WSTrust.RequestSecurityToken request) {
// RP validation disabled for the sake of simplicity
// ValidateAppliesTo(request.AppliesTo);
Scope scope = new Scope(request.AppliesTo.Uri.OriginalString,
SecurityTokenServiceConfiguration.SigningCredentials);
scope.ReplyToAddress = scope.AppliesToAddress;
scope.SymmetricKeyEncryptionRequired = false;
scope.TokenEncryptionRequired = false;
return (scope);
}
/// <summary>
/// This method returns the claims to be issued in the token.
/// </summary>
/// <param name="principal">The caller's principal.</param>
/// <param name="request">The incoming RST, to obtain additional
/// information.</param>
/// <param name="scope">The scope information corresponding to this
/// request.</param>
/// <returns>The outgoing claimsIdentity to be included in the issued
/// token.</returns>
protected override System.Security.Claims.ClaimsIdentity
GetOutputClaimsIdentity(System.Security.Claims.ClaimsPrincipal principal,
System.IdentityModel.Protocols.WSTrust.RequestSecurityToken request,
Scope scope) {
if (null == principal) {
throw new ArgumentNullException("principal");
}
Claim[] targetClaims = null;
XmlSerializer xs = new XmlSerializer(typeof(ClaimTypes));
ProfileBase profile = ProfileBase.Create(principal.Identity.Name);
if (profile != null) {
using (StreamReader sr = new StreamReader(
HttpContext.Current.Server.MapPath(
ConfigurationManager.AppSettings["ClaimTypesFilePath"]))) {
ClaimTypes cts = xs.Deserialize(sr) as ClaimTypes;
targetClaims =
(from c in new List<ClaimTypesClaimType>(cts.ClaimType)
select new Claim(c.Type,
(String)profile.GetPropertyValue(c.Name),
ClaimValueTypes.String)
).ToArray();

}
}
ClaimsIdentity ci = new ClaimsIdentity(targetClaims);
return (ci);
}
}

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.

The XML file with the full list of claims provided by the sample IP/STS

<?xml version="1.0" encoding="utf-8" ?>
<ClaimTypes xmlns="http://schemas.devleap.com/SampleIPSTS/ClaimTypes">
<ClaimType Name="Email"
Description="The Email address of the subject."
Optional="false"
Type="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/
¬ emailaddress" />
<ClaimType Name="Name"
Description="The Name of the subject."
Optional="false"
Type="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name" />
<ClaimType Name="Gender"
Description="The Gender of the subject."
Optional="true"
Type="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/gender" />
<ClaimType Name="FavoriteColor"
Description="The Favorite Color of the subject."
Optional="true"
Type="http://schemas.devleap.com/SampleIPSTS/claims/favoritecolor" />
</ClaimTypes>

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.

 
Others
 
- Sharepoint 2013 : Claims-based authentication, federated identities, and OAuth (part 1)
- Windows 8 : Printers and Devices - Start Screen Device Management
- Windows 8 : Printers and Devices - Desktop Printing
- Windows 8 : Desktop Printer and Device Installation
- Windows Small Business Server 2011 : Working with Groups
- Windows Small Business Server 2011 : Working with Computers (part 2) - Assigning Computers to Users
- Windows Small Business Server 2011 : Working with Computers (part 1) - Running the Connect Computer Program
- Windows Phone 8 : Using Push Notifications (part 6) - Handling Push Notification Errors
- Windows Phone 8 : Using Push Notifications (part 5) - Creating Live Tiles
- Windows Phone 8 : Using Push Notifications (part 4) - Sending Toast Notifications
 
 
Top 10
 
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Finding containers and lists in Visio (part 2) - Wireframes,Legends
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Finding containers and lists in Visio (part 1) - Swimlanes
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Formatting and sizing lists
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Adding shapes to lists
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Sizing containers
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 3) - The Other Properties of a Control
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 2) - The Data Properties of a Control
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 1) - The Format Properties of a Control
- Microsoft Access 2010 : Form Properties and Why Should You Use Them - Working with the Properties Window
- Microsoft Visio 2013 : Using the Organization Chart Wizard with new data
Technology FAQ
- Is possible to just to use a wireless router to extend wireless access to wireless access points?
- Ruby - Insert Struct to MySql
- how to find my Symantec pcAnywhere serial number
- About direct X / Open GL issue
- How to determine eclipse version?
- What SAN cert Exchange 2010 for UM, OA?
- How do I populate a SQL Express table from Excel file?
- code for express check out with Paypal.
- Problem with Templated User Control
- ShellExecute SW_HIDE
programming4us programming4us