From 79d24690d182cd21f29e1b890e60086325173eaf Mon Sep 17 00:00:00 2001
From: Rob
Date: Tue, 6 May 2014 10:15:33 -0700
Subject: [PATCH] Add Federation Metadata Endpoint for HRD
---
.../Constants.cs | 1 +
.../Endpoints.cs | 8 ++
.../FederationMetadataController.cs | 33 ++++-
.../WSFederationMetadataGenerator.cs | 46 ++++++-
.../Home/Index.cshtml.Designer.cs | 19 ++-
.../App_LocalResources/Home/Index.cshtml.resx | 127 +++++++++---------
.../WebSite/App_Start/ProtocolConfig.cs | 6 +
.../WebSite/Controller/HomeController.cs | 1 +
src/OnPremise/WebSite/Views/Home/Index.cshtml | 4 +
9 files changed, 171 insertions(+), 74 deletions(-)
diff --git a/src/Libraries/Thinktecture.IdentityServer.Core/Constants.cs b/src/Libraries/Thinktecture.IdentityServer.Core/Constants.cs
index fdd3701f..cce7071b 100644
--- a/src/Libraries/Thinktecture.IdentityServer.Core/Constants.cs
+++ b/src/Libraries/Thinktecture.IdentityServer.Core/Constants.cs
@@ -58,6 +58,7 @@ public static class Roles
public static class CacheKeys
{
public const string WSFedMetadata = "Cache_WSFedMetadata";
+ public const string WSFedRPMetadata = "Cache_WSFedRPMetadata";
}
}
}
diff --git a/src/Libraries/Thinktecture.IdentityServer.Core/Endpoints.cs b/src/Libraries/Thinktecture.IdentityServer.Core/Endpoints.cs
index 83b7c3ae..33a10687 100644
--- a/src/Libraries/Thinktecture.IdentityServer.Core/Endpoints.cs
+++ b/src/Libraries/Thinktecture.IdentityServer.Core/Endpoints.cs
@@ -15,6 +15,7 @@ public class Endpoints
public Uri WSFederation { get; set; }
public Uri WSFederationHRD { get; set; }
public Uri WSFederationMetadata { get; set; }
+ public Uri WSFederationRPMetadata { get; set; }
public Uri WSTrustMex { get; set; }
public Uri PrivacyNotice { get; set; }
@@ -43,6 +44,7 @@ public static class Paths
public const string WSFedHRDSelect = "issue/hrd/select";
public const string WSFedHRDSignoutRedirect = "issue/hrd/SignoutRedirect";
public const string WSFedMetadata = "FederationMetadata/2007-06/FederationMetadata.xml";
+ public const string WSFedRPMetadata = "FederationMetadataRP/2007-06/FederationMetadata.xml";
public const string PrivacyNotice = "privacyNotice.txt";
public const string WSTrustBase = "issue/wstrust";
public const string SimpleHttp = "issue/simple";
@@ -164,6 +166,12 @@ public static Endpoints Create(string baseUriString, int httpPort, int httpsPort
builder.Scheme = Uri.UriSchemeHttps;
builder.Port = httpsPort;
ep.WSFederationMetadata = builder.Uri;
+
+ var wsfedrpmd = new Uri(baseUriString + Paths.WSFedRPMetadata);
+ builder = new UriBuilder(wsfedrpmd);
+ builder.Scheme = Uri.UriSchemeHttps;
+ builder.Port = httpsPort;
+ ep.WSFederationRPMetadata = builder.Uri;
var adfs = new Uri(baseUriString + Paths.AdfsIntegration);
builder = new UriBuilder(adfs);
diff --git a/src/Libraries/Thinktecture.IdentityServer.Protocols/FederationMetadata/FederationMetadataController.cs b/src/Libraries/Thinktecture.IdentityServer.Protocols/FederationMetadata/FederationMetadataController.cs
index a674fd16..e200b0f9 100644
--- a/src/Libraries/Thinktecture.IdentityServer.Protocols/FederationMetadata/FederationMetadataController.cs
+++ b/src/Libraries/Thinktecture.IdentityServer.Protocols/FederationMetadata/FederationMetadataController.cs
@@ -5,7 +5,6 @@
using System;
using System.ComponentModel.Composition;
-using System.Web;
using System.Web.Mvc;
using Thinktecture.IdentityServer.Helper;
using Thinktecture.IdentityServer.Repositories;
@@ -60,5 +59,35 @@ public ActionResult Generate()
return new HttpNotFoundResult();
}
}
+
+ public ActionResult GenerateRPMetadata()
+ {
+ if (ConfigurationRepository.FederationMetadata.Enabled)
+ {
+ return Cache.ReturnFromCache(CacheRepository, Constants.CacheKeys.WSFedRPMetadata, 1, () =>
+ {
+ var host = ConfigurationRepository.Global.PublicHostName;
+ if (String.IsNullOrWhiteSpace(host))
+ {
+ host = HttpContext.Request.Headers["Host"];
+ }
+ var endpoints = Endpoints.Create(
+ host,
+ HttpContext.Request.ApplicationPath,
+ ConfigurationRepository.Global.HttpPort,
+ ConfigurationRepository.Global.HttpsPort);
+
+ return new ContentResult
+ {
+ Content = new WSFederationMetadataGenerator(endpoints).GenerateRelyingPartyMetadata(),
+ ContentType = "text/xml"
+ };
+ });
+ }
+ else
+ {
+ return new HttpNotFoundResult();
+ }
+ }
}
-}
+}
\ No newline at end of file
diff --git a/src/Libraries/Thinktecture.IdentityServer.Protocols/FederationMetadata/WSFederationMetadataGenerator.cs b/src/Libraries/Thinktecture.IdentityServer.Protocols/FederationMetadata/WSFederationMetadataGenerator.cs
index 37151574..30a56543 100644
--- a/src/Libraries/Thinktecture.IdentityServer.Protocols/FederationMetadata/WSFederationMetadataGenerator.cs
+++ b/src/Libraries/Thinktecture.IdentityServer.Protocols/FederationMetadata/WSFederationMetadataGenerator.cs
@@ -43,28 +43,47 @@ public WSFederationMetadataGenerator(Endpoints endpoints)
Container.Current.SatisfyImportsOnce(this);
}
+ //Builds federation metadata for using Id Srv as an IdP using the wsfed endpoint
public string Generate()
{
- var tokenServiceDescriptor = GetTokenServiceDescriptor();
+ var tokenServiceDescriptor = GetTokenServiceDescriptor(_endpoints.WSFederation.AbsoluteUri);
+ return GenerateMetadata(tokenServiceDescriptor);
+ }
+
+ //Builds federation metadata for using Id Srv as an RP using the HRD endpoint
+ public string GenerateRelyingPartyMetadata()
+ {
+ var tokenServiceDescriptor = GetTokenServiceDescriptor(_endpoints.WSFederationHRD.AbsoluteUri);
+ var appServiceDescriptor = GetApplicationServiceDescriptor();
+
+ return GenerateMetadata(tokenServiceDescriptor, appServiceDescriptor);
+ }
+
+ private string GenerateMetadata(params RoleDescriptor[] roles)
+ {
var id = new EntityId(ConfigurationRepository.Global.IssuerUri);
var entity = new EntityDescriptor(id);
entity.SigningCredentials = new X509SigningCredentials(ConfigurationRepository.Keys.SigningCertificate);
- entity.RoleDescriptors.Add(tokenServiceDescriptor);
+ foreach (var roleDescriptor in roles)
+ {
+ entity.RoleDescriptors.Add(roleDescriptor);
+ }
+
var ser = new MetadataSerializer();
var sb = new StringBuilder(512);
ser.WriteMetadata(XmlWriter.Create(new StringWriter(sb), new XmlWriterSettings { OmitXmlDeclaration = true }), entity);
return sb.ToString();
}
-
- private SecurityTokenServiceDescriptor GetTokenServiceDescriptor()
+
+ private SecurityTokenServiceDescriptor GetTokenServiceDescriptor(string passiveRequestorEndpoint)
{
var tokenService = new SecurityTokenServiceDescriptor();
tokenService.ServiceDescription = ConfigurationRepository.Global.SiteName;
tokenService.Keys.Add(GetSigningKeyDescriptor());
- tokenService.PassiveRequestorEndpoints.Add(new EndpointReference(_endpoints.WSFederation.AbsoluteUri));
+ tokenService.PassiveRequestorEndpoints.Add(new EndpointReference(passiveRequestorEndpoint));
tokenService.TokenTypesOffered.Add(new Uri(TokenTypes.OasisWssSaml11TokenProfile11));
tokenService.TokenTypesOffered.Add(new Uri(TokenTypes.OasisWssSaml2TokenProfile11));
@@ -101,6 +120,23 @@ private SecurityTokenServiceDescriptor GetTokenServiceDescriptor()
return tokenService;
}
+ private ApplicationServiceDescriptor GetApplicationServiceDescriptor()
+ {
+ var appDescriptor = new ApplicationServiceDescriptor();
+
+ appDescriptor.ServiceDescription = ConfigurationRepository.Global.SiteName;
+ appDescriptor.Keys.Add(GetSigningKeyDescriptor());
+
+ appDescriptor.PassiveRequestorEndpoints.Add(new EndpointReference(_endpoints.WSFederationHRD.AbsoluteUri));
+ appDescriptor.TokenTypesOffered.Add(new Uri(TokenTypes.OasisWssSaml11TokenProfile11));
+ appDescriptor.TokenTypesOffered.Add(new Uri(TokenTypes.OasisWssSaml2TokenProfile11));
+
+ ClaimsRepository.GetSupportedClaimTypes().ToList().ForEach(claimType => appDescriptor.ClaimTypesOffered.Add(new DisplayClaim(claimType)));
+ appDescriptor.ProtocolsSupported.Add(new Uri("http://docs.oasis-open.org/wsfed/federation/200706"));
+
+ return appDescriptor;
+ }
+
private KeyDescriptor GetSigningKeyDescriptor()
{
var certificate = ConfigurationRepository.Keys.SigningCertificate;
diff --git a/src/OnPremise/WebSite/App_LocalResources/Home/Index.cshtml.Designer.cs b/src/OnPremise/WebSite/App_LocalResources/Home/Index.cshtml.Designer.cs
index 00ce2d12..6344cb3e 100644
--- a/src/OnPremise/WebSite/App_LocalResources/Home/Index.cshtml.Designer.cs
+++ b/src/OnPremise/WebSite/App_LocalResources/Home/Index.cshtml.Designer.cs
@@ -1,17 +1,17 @@
//------------------------------------------------------------------------------
//
// This code was generated by a tool.
-// Runtime Version:4.0.30319.18033
+// Runtime Version:4.0.30319.18449
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
//
//------------------------------------------------------------------------------
-namespace Thinktecture.IdentityServer.Web.App_LocalResources.Home
-{
-
-
+namespace Thinktecture.IdentityServer.Web.App_LocalResources.Home {
+ using System;
+
+
///
/// A strongly-typed resource class, for looking up localized strings, etc.
///
@@ -78,6 +78,15 @@ public static string ViewWsFederationMetadata {
}
}
+ ///
+ /// Looks up a localized string similar to View WS-Federation Metadata (RP).
+ ///
+ public static string ViewWSFederationMetadataRP {
+ get {
+ return ResourceManager.GetString("ViewWSFederationMetadataRP", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to Welcome to {0}.
///
diff --git a/src/OnPremise/WebSite/App_LocalResources/Home/Index.cshtml.resx b/src/OnPremise/WebSite/App_LocalResources/Home/Index.cshtml.resx
index 53e4c485..2613e42c 100644
--- a/src/OnPremise/WebSite/App_LocalResources/Home/Index.cshtml.resx
+++ b/src/OnPremise/WebSite/App_LocalResources/Home/Index.cshtml.resx
@@ -1,6 +1,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- text/microsoft-resx
-
-
- 2.0
-
-
- System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
Application integration
-
+
View WS-Federation Metadata
-
+
+ View WS-Federation Metadata (RP)
+
+
Welcome to {0}
\ No newline at end of file
diff --git a/src/OnPremise/WebSite/App_Start/ProtocolConfig.cs b/src/OnPremise/WebSite/App_Start/ProtocolConfig.cs
index d418f694..2fbde72b 100644
--- a/src/OnPremise/WebSite/App_Start/ProtocolConfig.cs
+++ b/src/OnPremise/WebSite/App_Start/ProtocolConfig.cs
@@ -26,6 +26,12 @@ public static void RegisterProtocols(HttpConfiguration httpConfiguration, RouteC
// federation metadata
if (configuration.FederationMetadata.Enabled)
{
+ routes.MapRoute(
+ "FederationMetadataRP",
+ Thinktecture.IdentityServer.Endpoints.Paths.WSFedRPMetadata,
+ new { controller = "FederationMetadata", action = "GenerateRPMetadata" }
+ );
+
routes.MapRoute(
"FederationMetadata",
Thinktecture.IdentityServer.Endpoints.Paths.WSFedMetadata,
diff --git a/src/OnPremise/WebSite/Controller/HomeController.cs b/src/OnPremise/WebSite/Controller/HomeController.cs
index 4c4545b5..9abae234 100644
--- a/src/OnPremise/WebSite/Controller/HomeController.cs
+++ b/src/OnPremise/WebSite/Controller/HomeController.cs
@@ -56,6 +56,7 @@ public ActionResult AppIntegration()
if (Configuration.FederationMetadata.Enabled)
{
list.Add("WS-Federation metadata", endpoints.WSFederationMetadata.AbsoluteUri);
+ list.Add("WS-Federation metadata (RP)", endpoints.WSFederationRPMetadata.AbsoluteUri);
}
// ws-federation
diff --git a/src/OnPremise/WebSite/Views/Home/Index.cshtml b/src/OnPremise/WebSite/Views/Home/Index.cshtml
index ea469246..1956c4ef 100644
--- a/src/OnPremise/WebSite/Views/Home/Index.cshtml
+++ b/src/OnPremise/WebSite/Views/Home/Index.cshtml
@@ -9,6 +9,10 @@
@Html.ActionLink(Index_cshtml.ViewWsFederationMetadata, "Generate", "FederationMetadata")
+
+ @Html.ActionLink(Index_cshtml.ViewWSFederationMetadataRP, "GenerateRPMetadata", "FederationMetadata")
+
+
@Html.ActionLink(Index_cshtml.ApplicationIntegration, "appintegration", "home")
\ No newline at end of file