Preparing the Identity Server Source Code Project
Applies To: Windows Azure Pack
Preparing the thinktecture Identity Server Visual Studio project requires downloading of the project source code from GitHub, ensuring the correct NuGet packages are installed and making required updates to the source code.
The original thinktecture Identity Server source code requires two updates for it to work with Windows Azure Pack. The first change adds a new claim “upn” value and the second adds a value to satisfy the minimum signing certificate requirements.
Finally the solution website has to be published to the desired destination.
Preparing the Visual Studio Solution
To Prepare the thinktecture Identity Server Visual Studio Solution
Download the thinktecture Visual Studio Project from https://github.com/thinktecture/Thinktecture.IdentityServer.v2.
Open the thinktecture Identity Server solution in Visual Studio 2012
In Solution Explorer, right-click the ‘Thinktecture.IdentityServer’ solution and select Manage NuGet Packages for Solution to open the Manage NuGet Packages dialog box.
Select the Restore button to restore any missing NuGet packages.
select Updates and install any required updates.
Build the Thinktecture.IdentityServer solution.
Adding a New Claim “upn” Value
To work correctly with Windows Azure Pack a new “upn” value must be added to the thinktecture Identity Serveer source code.
To Add a New Claim “upn” Value
In the solution Thinktecture.IdentityServer, open the file TokenService.cs in \Libraries\Thinktecture.IdentityServer.core\TokenService.
In the function GetExternalOutputClaims, find the following code:
id.AddClaim(new Claim(Constants.Claims.IdentityProvider, idp.Name));
Place the following code immediately afterwards:
var emailaddress = id.Claims.Single(c => c.Type == ClaimTypes.Email); id.AddClaim(new Claim("upn", emailaddress.Value));
Build the solution and correct any errors.
The code section now should look as follows:
protected virtual ClaimsIdentity GetExternalOutputClaims(ClaimsPrincipal principal, RequestDetails requestDetails)
{
var idpClaim = principal.FindFirst(c => c.Type == Constants.Claims.IdentityProvider && c.Issuer == Constants.InternalIssuer);
if (idpClaim == null)
{
throw new InvalidOperationException("No identity provider claim found.");
}
IdentityProvider idp = null;
if (IdentityProviderRepository.TryGet(idpClaim.Value, out idp))
{
var transformedClaims = ClaimsTransformationRulesRepository.ProcessClaims(SanitizeInternalClaims(principal), idp, requestDetails);
var id = new ClaimsIdentity(transformedClaims, "External");
id.AddClaim(new Claim(Constants.Claims.IdentityProvider, idp.Name));
var emailaddress = id.Claims.Single(c => c.Type == ClaimTypes.Email);
id.AddClaim(new Claim("upn", emailaddress.Value));
return id;
}
throw new InvalidRequestException("Invalid identity provider.");
}
Satisfying the Minimum Signing Certificate Requirements
The signing certificate requirements have to be updated to work correctly with Windows Azure Pack.
To Satisfy Minimum Signing Certificate Requirements
In the solution Thinktecture.IdentityServer, open the file Global.asax.cs in \WebSite\Global.asax.
At the top of the file add the following using statements:
using System.IdentityModel.Tokens; using System.Reflection;
Add the following function at the end of the class MvcApplication.
private void HijackMinimumSigningCertificateRequirements() { var _type = typeof(SignatureProviderFactory); var _minimumAsymmetricKeySizeInBitsForSigning = _type.GetField("_minimumAsymmetricKeySizeInBitsForSigning", BindingFlags.NonPublic | BindingFlags.Static); _minimumAsymmetricKeySizeInBitsForSigning.SetValue(null, 1024u); }
Add a call for the new function as the end of the Application_Start() method with the following code:
HijackMinimumSigningCertificateRequirements();
Build the solution and correct any errors.
The completed code should look like this:
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
using System.Data.Entity;
using System.Security.Claims;
using System.Web.Helpers;
using System.Web.Http;
using System.Web.Mvc;
using System.Web.Optimization;
using System.Web.Routing;
using Thinktecture.IdentityServer.Repositories;
using Thinktecture.IdentityServer.Repositories.Sql;
using System.IdentityModel.Tokens;
using System.Reflection;
namespace Thinktecture.IdentityServer.Web
{
public class MvcApplication : System.Web.HttpApplication
{
[Import]
public IConfigurationRepository ConfigurationRepository { get; set; }
[Import]
public IUserRepository UserRepository { get; set; }
[Import]
public IRelyingPartyRepository RelyingPartyRepository { get; set; }
protected void Application_Start()
{
// create empty config database if it not exists
Database.SetInitializer(new ConfigurationDatabaseInitializer());
// set the anti CSRF for name (that's a unqiue claim in our system)
AntiForgeryConfig.UniqueClaimTypeIdentifier = ClaimTypes.Name;
// setup MEF
SetupCompositionContainer();
Container.Current.SatisfyImportsOnce(this);
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters, ConfigurationRepository);
RouteConfig.RegisterRoutes(RouteTable.Routes, ConfigurationRepository, UserRepository);
ProtocolConfig.RegisterProtocols(GlobalConfiguration.Configuration, RouteTable.Routes, ConfigurationRepository, UserRepository, RelyingPartyRepository);
BundleConfig.RegisterBundles(BundleTable.Bundles);
HijackMinimumSigningCertificateRequirements();
}
private void SetupCompositionContainer()
{
Container.Current = new CompositionContainer(new RepositoryExportProvider());
}
private void HijackMinimumSigningCertificateRequirements()
{
var _type = typeof(SignatureProviderFactory);
var _minimumAsymmetricKeySizeInBitsForSigning = _type.GetField("_minimumAsymmetricKeySizeInBitsForSigning", BindingFlags.NonPublic | BindingFlags.Static);
_minimumAsymmetricKeySizeInBitsForSigning.SetValue(null, 1024u);
}
}
}
Publishing the Website Code
Once the solution has been successfully compiled, you can publish the website code to either the local file system or publish it to the server it will be run from. The following steps demonstrate publishing to the local file system
To Publish to the Local File System
In Visual Studio Solution Explorer, right-click the project WebSite and select Publish.
In the Profile section, select <New…> in the drop down list box, enter a new profile name and press OK.
In the Connection section, select File System from the Publish method drop down list box.
Set the Target location text box to the location you want to publish the site to.
In the Settings section, choose the configuration you want in the Configuration drop down list box. By default the configuration is Release.
Review your settings in the Review Section and click Publish to publish the website.