diff --git a/src/.nuget/NuGet.Config b/src/.nuget/NuGet.Config
new file mode 100644
index 0000000..6a318ad
--- /dev/null
+++ b/src/.nuget/NuGet.Config
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/.nuget/NuGet.exe b/src/.nuget/NuGet.exe
new file mode 100644
index 0000000..9f8781d
Binary files /dev/null and b/src/.nuget/NuGet.exe differ
diff --git a/src/.nuget/NuGet.targets b/src/.nuget/NuGet.targets
new file mode 100644
index 0000000..3f8c37b
--- /dev/null
+++ b/src/.nuget/NuGet.targets
@@ -0,0 +1,144 @@
+
+
+
+ $(MSBuildProjectDirectory)\..\
+
+
+ false
+
+
+ false
+
+
+ true
+
+
+ false
+
+
+
+
+
+
+
+
+
+
+ $([System.IO.Path]::Combine($(SolutionDir), ".nuget"))
+
+
+
+
+ $(SolutionDir).nuget
+
+
+
+ $(MSBuildProjectDirectory)\packages.$(MSBuildProjectName.Replace(' ', '_')).config
+ $(MSBuildProjectDirectory)\packages.$(MSBuildProjectName).config
+
+
+
+ $(MSBuildProjectDirectory)\packages.config
+ $(PackagesProjectConfig)
+
+
+
+
+ $(NuGetToolsPath)\NuGet.exe
+ @(PackageSource)
+
+ "$(NuGetExePath)"
+ mono --runtime=v4.0.30319 "$(NuGetExePath)"
+
+ $(TargetDir.Trim('\\'))
+
+ -RequireConsent
+ -NonInteractive
+
+ "$(SolutionDir) "
+ "$(SolutionDir)"
+
+
+ $(NuGetCommand) install "$(PackagesConfig)" -source "$(PackageSources)" $(NonInteractiveSwitch) $(RequireConsentSwitch) -solutionDir $(PaddedSolutionDir)
+ $(NuGetCommand) pack "$(ProjectPath)" -Properties "Configuration=$(Configuration);Platform=$(Platform)" $(NonInteractiveSwitch) -OutputDirectory "$(PackageOutputDir)" -symbols
+
+
+
+ RestorePackages;
+ $(BuildDependsOn);
+
+
+
+
+ $(BuildDependsOn);
+ BuildPackage;
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Owin.Security.Saml/Owin.Security.Saml.csproj b/src/Owin.Security.Saml/Owin.Security.Saml.csproj
index 43ffb32..e429e8f 100644
--- a/src/Owin.Security.Saml/Owin.Security.Saml.csproj
+++ b/src/Owin.Security.Saml/Owin.Security.Saml.csproj
@@ -1,92 +1,101 @@
-
-
-
-
- Debug
- AnyCPU
- {0054DAFD-1A69-4807-B24E-A6A6B71927C7}
- Library
- Properties
- Owin.Security.Saml
- Owin.Security.Saml
- v4.5
- 512
-
-
- true
- full
- false
- bin\Debug\
- DEBUG;TRACE
- prompt
- 4
-
-
- pdbonly
- true
- bin\Release\
- TRACE
- prompt
- 4
-
-
-
- ..\packages\Microsoft.IdentityModel.Protocol.Extensions.1.0.1\lib\net45\Microsoft.IdentityModel.Protocol.Extensions.dll
-
-
- ..\packages\Microsoft.Owin.3.0.0\lib\net45\Microsoft.Owin.dll
-
-
- ..\packages\Microsoft.Owin.Security.3.0.0\lib\net45\Microsoft.Owin.Security.dll
-
-
- ..\packages\Owin.1.0\lib\net40\Owin.dll
-
-
-
-
- ..\packages\System.IdentityModel.Tokens.Jwt.4.0.1\lib\net45\System.IdentityModel.Tokens.Jwt.dll
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {75e5bad2-a20c-43cc-b5c8-38004cedbdfd}
- SAML2.Core
-
-
-
+
+
+
+
+ Debug
+ AnyCPU
+ {0054DAFD-1A69-4807-B24E-A6A6B71927C7}
+ Library
+ Properties
+ Owin.Security.Saml
+ Owin.Security.Saml
+ v4.5
+ 512
+ ..\
+ true
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+ ..\packages\Microsoft.IdentityModel.Protocol.Extensions.1.0.1\lib\net45\Microsoft.IdentityModel.Protocol.Extensions.dll
+
+
+ ..\packages\Microsoft.Owin.3.0.0\lib\net45\Microsoft.Owin.dll
+
+
+ ..\packages\Microsoft.Owin.Security.3.0.0\lib\net45\Microsoft.Owin.Security.dll
+
+
+ ..\packages\Owin.1.0\lib\net40\Owin.dll
+
+
+
+
+ ..\packages\System.IdentityModel.Tokens.Jwt.4.0.1\lib\net45\System.IdentityModel.Tokens.Jwt.dll
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {75e5bad2-a20c-43cc-b5c8-38004cedbdfd}
+ SAML2.Core
+
+
+
+
+
+
+ This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
+
+
+
+ -->
\ No newline at end of file
diff --git a/src/Owin.Security.Saml/SamlMessage.cs b/src/Owin.Security.Saml/SamlMessage.cs
index e353a6a..118b66d 100644
--- a/src/Owin.Security.Saml/SamlMessage.cs
+++ b/src/Owin.Security.Saml/SamlMessage.cs
@@ -159,10 +159,10 @@ private string AuthnRequestForIdp(IdentityProvider identityProvider, Saml20Authn
context.Authentication.AuthenticationResponseChallenge.Properties.Dictionary != null &&
context.Authentication.AuthenticationResponseChallenge.Properties.Dictionary.Count > 0)
redirectBuilder.RelayState = context.Authentication.AuthenticationResponseChallenge.Properties.Dictionary.ToDelimitedString();
- logger.DebugFormat(TraceMessages.AuthnRequestSent, redirectBuilder.Request);
-
- var redirectLocation = request.Destination + "?" + redirectBuilder.ToQuery();
- return redirectLocation;
+ logger.DebugFormat(TraceMessages.AuthnRequestSent, redirectBuilder.Request);
+
+ var redirectLocation = string.Format( "{0}{1}{2}", request.Destination, ( request.Destination.EndsWith( "?" ) ? "&" : "?" ), redirectBuilder.ToQuery() );
+ return redirectLocation;
case BindingType.Post:
throw new NotImplementedException();
//logger.DebugFormat(TraceMessages.AuthnRequestPrepared, identityProvider.Id, Saml20Constants.ProtocolBindings.HttpPost);
@@ -201,7 +201,6 @@ private string AuthnRequestForIdp(IdentityProvider identityProvider, Saml20Authn
logger.Error(SAML2.ErrorMessages.EndpointBindingInvalid);
throw new Saml20Exception(SAML2.ErrorMessages.EndpointBindingInvalid);
}
- throw new NotImplementedException();
}
private static NameValueCollection BuildParams(IReadableStringCollection query)
diff --git a/src/SAML2.AspNet/Protocol/Saml20LogoutHandler.cs b/src/SAML2.AspNet/Protocol/Saml20LogoutHandler.cs
index 80bb0eb..1a409e2 100644
--- a/src/SAML2.AspNet/Protocol/Saml20LogoutHandler.cs
+++ b/src/SAML2.AspNet/Protocol/Saml20LogoutHandler.cs
@@ -328,7 +328,7 @@ private void HandleRequest(HttpContext context)
Logger.DebugFormat(TraceMessages.LogoutResponseSent, builder.Response);
- context.Response.Redirect(destination.Url + "?" + builder.ToQuery(), true);
+ context.Response.Redirect(string.Format( "{0}{1}{2}", destination.Url, destination.Url.EndsWith("?") ? "&" : "?" , builder.ToQuery()), true);
return;
}
diff --git a/src/SAML2.AspNet/Protocol/Saml20SignonHandler.cs b/src/SAML2.AspNet/Protocol/Saml20SignonHandler.cs
index 1de5334..f410916 100644
--- a/src/SAML2.AspNet/Protocol/Saml20SignonHandler.cs
+++ b/src/SAML2.AspNet/Protocol/Saml20SignonHandler.cs
@@ -189,7 +189,7 @@ private void TransferClient(IdentityProvider identityProvider, Saml20AuthnReques
Logger.DebugFormat(TraceMessages.AuthnRequestSent, redirectBuilder.Request);
- var redirectLocation = request.Destination + "?" + redirectBuilder.ToQuery();
+ var redirectLocation = string.Format( "{0}{1}{2}", request.Destination, ( request.Destination.EndsWith( "?" ) ? "&" : "?" ), redirectBuilder.ToQuery() );
context.Response.Redirect(redirectLocation, true);
break;
case BindingType.Post:
diff --git a/src/SAML2.AspNet/SAML2.AspNet.csproj b/src/SAML2.AspNet/SAML2.AspNet.csproj
index 04eb9c7..2bf9908 100644
--- a/src/SAML2.AspNet/SAML2.AspNet.csproj
+++ b/src/SAML2.AspNet/SAML2.AspNet.csproj
@@ -1,119 +1,116 @@
-
-
-
-
- Debug
- AnyCPU
- {D2136BFD-D2DA-4105-920B-8E05C090C597}
- Library
- Properties
- SAML2.AspNet
- SAML2.AspNet
- v4.5
- 512
-
-
- true
- full
- false
- bin\Debug\
- DEBUG;TRACE
- prompt
- 4
-
-
- pdbonly
- true
- bin\Release\
- TRACE
- prompt
- 4
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- aspxcodebehind
-
-
- aspxcodebehind
-
-
- aspxcodebehind
-
-
-
-
-
-
-
-
-
-
-
-
- {75e5bad2-a20c-43cc-b5c8-38004cedbdfd}
- SAML2.Core
-
-
-
-
-
-
+
+
+
+
+ Debug
+ AnyCPU
+ {D2136BFD-D2DA-4105-920B-8E05C090C597}
+ Library
+ Properties
+ SAML2.AspNet
+ SAML2.AspNet
+ v4.5
+ 512
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ aspxcodebehind
+
+
+ aspxcodebehind
+
+
+ aspxcodebehind
+
+
+
+
+
+
+
+
+
+
+
+
+ {75e5bad2-a20c-43cc-b5c8-38004cedbdfd}
+ SAML2.Core
+
+
+
+ -->
\ No newline at end of file
diff --git a/src/SAML2.Core/Bindings/HttpArtifactBindingBuilder.cs b/src/SAML2.Core/Bindings/HttpArtifactBindingBuilder.cs
index 4e9ce13..a412236 100644
--- a/src/SAML2.Core/Bindings/HttpArtifactBindingBuilder.cs
+++ b/src/SAML2.Core/Bindings/HttpArtifactBindingBuilder.cs
@@ -14,17 +14,16 @@ public class HttpArtifactBindingBuilder : HttpSoapBindingBuilder
{
private readonly Saml2Configuration config;
private readonly Action redirect;
- private readonly Action sendResponseMessage;
-
-
-
- ///
- /// Initializes a new instance of the class.
- ///
- /// The current http context.
- /// Action to perform when redirecting. Parameter will be destination URL
- /// Action to send messages to response stream
- public HttpArtifactBindingBuilder(Saml2Configuration config, Action redirect, Action sendResponseMessage)
+ private readonly Action sendResponseMessage;
+
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ /// Action to perform when redirecting. Parameter will be destination URL
+ /// Action to send messages to response stream
+ public HttpArtifactBindingBuilder(Saml2Configuration config, Action redirect, Action sendResponseMessage)
{
if (config == null) throw new ArgumentNullException("config");
if (redirect == null) throw new ArgumentNullException("redirect");
@@ -32,59 +31,63 @@ public HttpArtifactBindingBuilder(Saml2Configuration config, Action redi
this.redirect = redirect;
this.config = config;
this.sendResponseMessage = sendResponseMessage;
- }
-
- ///
- /// Creates an artifact and redirects the user to the IdP
- ///
- /// The destination of the request.
- /// The authentication request.
- /// Relay state from client. May be null
- public void RedirectFromLogin(IdentityProviderEndpoint destination, Saml20AuthnRequest request, string relayState, Action cacheInsert)
+ }
+
+ ///
+ /// Creates an artifact and redirects the user to the IdP
+ ///
+ /// The destination of the request.
+ /// The authentication request.
+ /// Relay state from client. May be null
+ ///
+ public void RedirectFromLogin(IdentityProviderEndpoint destination, Saml20AuthnRequest request, string relayState, Action cacheInsert)
{
var index = (short)config.ServiceProvider.Endpoints.DefaultSignOnEndpoint.Index;
var doc = request.GetXml();
XmlSignatureUtils.SignDocument(doc, request.Request.Id, config.ServiceProvider.SigningCertificate);
ArtifactRedirect(destination, index, doc, relayState, cacheInsert);
- }
-
-
- ///
- /// Creates an artifact for the LogoutRequest and redirects the user to the IdP.
- ///
- /// The destination of the request.
- /// The logout request.
- /// The query string relay state value (relayState) to add to the communication
- public void RedirectFromLogout(IdentityProviderEndpoint destination, Saml20LogoutRequest request, string relayState, Action cacheInsert)
+ }
+
+
+ ///
+ /// Creates an artifact for the LogoutRequest and redirects the user to the IdP.
+ ///
+ /// The destination of the request.
+ /// The logout request.
+ /// The query string relay state value (relayState) to add to the communication
+ ///
+ public void RedirectFromLogout(IdentityProviderEndpoint destination, Saml20LogoutRequest request, string relayState, Action cacheInsert)
{
var index = (short)config.ServiceProvider.Endpoints.DefaultLogoutEndpoint.Index;
var doc = request.GetXml();
XmlSignatureUtils.SignDocument(doc, request.Request.Id, config.ServiceProvider.SigningCertificate);
ArtifactRedirect(destination, index, doc, relayState, cacheInsert);
- }
-
- ///
- /// Creates an artifact for the LogoutResponse and redirects the user to the IdP.
- ///
- /// The destination of the response.
- /// The logout response.
- /// The query string relay state value to add to the communication
-
- public void RedirectFromLogout(IdentityProviderEndpoint destination, Saml20LogoutResponse response, string relayState, Action cacheInsert)
+ }
+
+ ///
+ /// Creates an artifact for the LogoutResponse and redirects the user to the IdP.
+ ///
+ /// The destination of the response.
+ /// The logout response.
+ /// The query string relay state value to add to the communication
+ ///
+ public void RedirectFromLogout(IdentityProviderEndpoint destination, Saml20LogoutResponse response, string relayState, Action cacheInsert)
{
var index = (short)config.ServiceProvider.Endpoints.DefaultLogoutEndpoint.Index;
var doc = response.GetXml();
XmlSignatureUtils.SignDocument(doc, response.Response.ID, config.ServiceProvider.SigningCertificate);
ArtifactRedirect(destination, index, doc, relayState, cacheInsert);
- }
-
- ///
- /// Resolves an artifact.
- ///
- /// A stream containing the artifact response from the IdP
- /// artifact from request ("SAMLart")
- public Stream ResolveArtifact(string artifact, string relayState, Saml2Configuration config)
+ }
+
+ ///
+ /// Resolves an artifact.
+ ///
+ /// A stream containing the artifact response from the IdP
+ /// artifact from request ("SAMLart")
+ ///
+ ///
+ public Stream ResolveArtifact(string artifact, string relayState, Saml2Configuration config)
{
var idpEndPoint = DetermineIdp(artifact);
if (idpEndPoint == null)
@@ -113,13 +116,14 @@ public Stream ResolveArtifact(string artifact, string relayState, Saml2Configura
Logger.DebugFormat(TraceMessages.ArtifactResolved, artifactResolveString);
return GetResponse(endpointUrl, artifactResolveString, idpEndPoint.ArtifactResolution, relayState);
- }
-
- ///
- /// Handles responses to an artifact resolve message.
- ///
- /// The artifact resolve message.
- public void RespondToArtifactResolve(ArtifactResolve artifactResolve, XmlElement samlDoc)
+ }
+
+ ///
+ /// Handles responses to an artifact resolve message.
+ ///
+ /// The artifact resolve message.
+ ///
+ public void RespondToArtifactResolve(ArtifactResolve artifactResolve, XmlElement samlDoc)
{
var response = Saml20ArtifactResponse.GetDefault(config.ServiceProvider.Id);
response.StatusCode = Saml20Constants.StatusCodes.Success;
@@ -156,16 +160,17 @@ private static bool ByteArraysAreEqual(byte[] a, byte[] b)
}
return true;
- }
-
- ///
- /// Handles all artifact creations and redirects.
- ///
- /// The destination.
- /// Index of the local endpoint.
- /// The signed SAML message.
- /// The query string relay state value to add to the communication
- private void ArtifactRedirect(IdentityProviderEndpoint destination, short localEndpointIndex, XmlDocument signedSamlMessage, string relayState, Action cacheInsert)
+ }
+
+ ///
+ /// Handles all artifact creations and redirects.
+ ///
+ /// The destination.
+ /// Index of the local endpoint.
+ /// The signed SAML message.
+ /// The query string relay state value to add to the communication
+ ///
+ private void ArtifactRedirect(IdentityProviderEndpoint destination, short localEndpointIndex, XmlDocument signedSamlMessage, string relayState, Action cacheInsert)
{
Logger.DebugFormat(TraceMessages.ArtifactRedirectReceived, signedSamlMessage.OuterXml);
@@ -174,9 +179,9 @@ private void ArtifactRedirect(IdentityProviderEndpoint destination, short localE
var messageHandle = ArtifactUtil.GenerateMessageHandle();
var artifact = ArtifactUtil.CreateArtifact(HttpArtifactBindingConstants.ArtifactTypeCode, localEndpointIndex, sourceIdHash, messageHandle);
- cacheInsert(artifact, signedSamlMessage);
-
- var destinationUrl = destination.Url + "?" + HttpArtifactBindingConstants.ArtifactQueryStringName + "=" + Uri.EscapeDataString(artifact);
+ cacheInsert(artifact, signedSamlMessage);
+
+ var destinationUrl = string.Format( "{0}{1}{2}{3}{4}", destination.Url, ( destination.Url.EndsWith( "?" ) ? "&" : "?" ), HttpArtifactBindingConstants.ArtifactQueryStringName, "=", Uri.EscapeDataString( artifact ) );
if (!string.IsNullOrEmpty(relayState))
{
destinationUrl += "&relayState=" + relayState;
diff --git a/src/SAML2.Core/Config/Metadata.cs b/src/SAML2.Core/Config/Metadata.cs
index 0db1103..0032f56 100644
--- a/src/SAML2.Core/Config/Metadata.cs
+++ b/src/SAML2.Core/Config/Metadata.cs
@@ -9,8 +9,6 @@ namespace SAML2.Config
///
public class Metadata
{
-
-
///
/// Gets or sets a value indicating whether to exclude artifact endpoints in metadata generation.
///
@@ -36,7 +34,12 @@ public class Metadata
/// Gets or sets the requested attributes.
///
/// The requested attributes.
- public IList RequestedAttributes { get; set; }
+ public IList RequestedAttributes { get; set; }
+
+ ///
+ /// Set Metadata validUntil attribute to be the days from now. The default is to ignore the validUntil attribute so the metadata will not expire.
+ ///
+ public int? ValidForDays { get; set; }
public Metadata()
{
diff --git a/src/SAML2.Core/ErrorMessages.Designer.cs b/src/SAML2.Core/ErrorMessages.Designer.cs
new file mode 100644
index 0000000..81603f4
--- /dev/null
+++ b/src/SAML2.Core/ErrorMessages.Designer.cs
@@ -0,0 +1,459 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by a tool.
+// Runtime Version:4.0.30319.34209
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+namespace SAML2 {
+ using System;
+
+
+ ///
+ /// A strongly-typed resource class, for looking up localized strings, etc.
+ ///
+ // This class was auto-generated by the StronglyTypedResourceBuilder
+ // class via a tool like ResGen or Visual Studio.
+ // To add or remove a member, edit your .ResX file then rerun ResGen
+ // with the /str option, or rebuild your VS project.
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ public class ErrorMessages {
+
+ private static global::System.Resources.ResourceManager resourceMan;
+
+ private static global::System.Globalization.CultureInfo resourceCulture;
+
+ [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+ internal ErrorMessages() {
+ }
+
+ ///
+ /// Returns the cached ResourceManager instance used by this class.
+ ///
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ public static global::System.Resources.ResourceManager ResourceManager {
+ get {
+ if (object.ReferenceEquals(resourceMan, null)) {
+ global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("SAML2.ErrorMessages", typeof(ErrorMessages).Assembly);
+ resourceMan = temp;
+ }
+ return resourceMan;
+ }
+ }
+
+ ///
+ /// Overrides the current thread's CurrentUICulture property for all
+ /// resource lookups using this strongly typed resource class.
+ ///
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ public static global::System.Globalization.CultureInfo Culture {
+ get {
+ return resourceCulture;
+ }
+ set {
+ resourceCulture = value;
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Artifact is not from a known identity provider.
+ ///
+ public static string ArtifactResolveIdentityProviderUnknown {
+ get {
+ return ResourceManager.GetString("ArtifactResolveIdentityProviderUnknown", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Could not verify SAML SOAP binding message signature.
+ ///
+ public static string ArtifactResolveSignatureInvalid {
+ get {
+ return ResourceManager.GetString("ArtifactResolveSignatureInvalid", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to ArtifactResponse did not contain an assertion.
+ ///
+ public static string ArtifactResponseMissingAssertion {
+ get {
+ return ResourceManager.GetString("ArtifactResponseMissingAssertion", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Unsupported payload message in ArtifactResponse.
+ ///
+ public static string ArtifactResponseMissingResponse {
+ get {
+ return ResourceManager.GetString("ArtifactResponseMissingResponse", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Could not verify artifact response message signature.
+ ///
+ public static string ArtifactResponseSignatureInvalid {
+ get {
+ return ResourceManager.GetString("ArtifactResponseSignatureInvalid", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to ArtifactResponse status code was invalid, expected {0}.
+ ///
+ public static string ArtifactResponseStatusCodeInvalid {
+ get {
+ return ResourceManager.GetString("ArtifactResponseStatusCodeInvalid", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Assertion expiration has been exceeded.
+ ///
+ public static string AssertionExpired {
+ get {
+ return ResourceManager.GetString("AssertionExpired", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Could not process assertion with an unknown identity provider.
+ ///
+ public static string AssertionIdentityProviderUnknown {
+ get {
+ return ResourceManager.GetString("AssertionIdentityProviderUnknown", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Assertion not found.
+ ///
+ public static string AssertionNotFound {
+ get {
+ return ResourceManager.GetString("AssertionNotFound", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Assertion with OneTimeUse condition detected more than once.
+ ///
+ public static string AssertionOneTimeUseExceeded {
+ get {
+ return ResourceManager.GetString("AssertionOneTimeUseExceeded", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Assertion signature is invalid.
+ ///
+ public static string AssertionSignatureInvalid {
+ get {
+ return ResourceManager.GetString("AssertionSignatureInvalid", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Attribute query can not be performed when user is not logged in with an identity provider.
+ ///
+ public static string AttrQueryNoLogin {
+ get {
+ return ResourceManager.GetString("AttrQueryNoLogin", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to AttrQuery response with status code "{0}" received when "Success" was expected.
+ ///
+ public static string AttrQueryStatusNotSuccessful {
+ get {
+ return ResourceManager.GetString("AttrQueryStatusNotSuccessful", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Certificate with DN "{0}" and thumbprint "{1}" is not valid according to RFC3280.
+ ///
+ public static string CertificateIsNotRFC3280Valid {
+ get {
+ return ResourceManager.GetString("CertificateIsNotRFC3280Valid", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Certificate {0} was not found.
+ ///
+ public static string CertificateNotFound {
+ get {
+ return ResourceManager.GetString("CertificateNotFound", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Found more than one certificate matching {0}.
+ ///
+ public static string CertificateNotUnique {
+ get {
+ return ResourceManager.GetString("CertificateNotUnique", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Common Domain Cookie identity provider not found in list of known identity providers: {0}.
+ ///
+ public static string CommonDomainCookieIdentityProviderInvalid {
+ get {
+ return ResourceManager.GetString("CommonDomainCookieIdentityProviderInvalid", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Configuration element <saml2> does not contain an <identityProviders> element.
+ ///
+ public static string ConfigMissingIdentityProvidersElement {
+ get {
+ return ResourceManager.GetString("ConfigMissingIdentityProvidersElement", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Configuration for <identityProviders> does not contain a "metadata" attribute.
+ ///
+ public static string ConfigMissingMetadataLocation {
+ get {
+ return ResourceManager.GetString("ConfigMissingMetadataLocation", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Configuration does not contain <saml2> element.
+ ///
+ public static string ConfigMissingSaml2Element {
+ get {
+ return ResourceManager.GetString("ConfigMissingSaml2Element", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Configuration element <saml2> does not contain a <serviceProvider> element.
+ ///
+ public static string ConfigMissingServiceProviderElement {
+ get {
+ return ResourceManager.GetString("ConfigMissingServiceProviderElement", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Configuration for <serviceProvider> does not contain an "id" attribute.
+ ///
+ public static string ConfigMissingServiceProviderIdAttribute {
+ get {
+ return ResourceManager.GetString("ConfigMissingServiceProviderIdAttribute", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Configuration for <serviceProvider> does not contain a <signingCertificate> element.
+ ///
+ public static string ConfigMissingSigningCertificateElement {
+ get {
+ return ResourceManager.GetString("ConfigMissingSigningCertificateElement", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Configuration for <serviceProvider> does not contain a SignOn endpoint.
+ ///
+ public static string ConfigServiceProviderMissingSignOnEndpoint {
+ get {
+ return ResourceManager.GetString("ConfigServiceProviderMissingSignOnEndpoint", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Specified <signingCertificate> does not have a private key.
+ ///
+ public static string ConfigSigningCertificateMissingPrivateKey {
+ get {
+ return ResourceManager.GetString("ConfigSigningCertificateMissingPrivateKey", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to The endpoint binding must be one of POST, Redirect, or Artifact.
+ ///
+ public static string EndpointBindingInvalid {
+ get {
+ return ResourceManager.GetString("EndpointBindingInvalid", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Empty protocol message id is not allowed.
+ ///
+ public static string ExpectedInResponseToEmpty {
+ get {
+ return ResourceManager.GetString("ExpectedInResponseToEmpty", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Session ExpectedInResponseTo missing.
+ ///
+ public static string ExpectedInResponseToMissing {
+ get {
+ return ResourceManager.GetString("ExpectedInResponseToMissing", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to An error occurred.
+ ///
+ public static string GenericError {
+ get {
+ return ResourceManager.GetString("GenericError", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to The specified metadata directory "{0}" could not be located.
+ ///
+ public static string MetadataLocationNotFound {
+ get {
+ return ResourceManager.GetString("MetadataLocationNotFound", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to The "sign"query string parameter could not be parsed.
+ ///
+ public static string MetadataSignQueryParameterInvalid {
+ get {
+ return ResourceManager.GetString("MetadataSignQueryParameterInvalid", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Possible replay attack detected, unexpected value {0} for InResponseTo, expected {1}.
+ ///
+ public static string ReplayAttack {
+ get {
+ return ResourceManager.GetString("ReplayAttack", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Request signature is invalid.
+ ///
+ public static string RequestSignatureInvalid {
+ get {
+ return ResourceManager.GetString("RequestSignatureInvalid", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Request is not signed.
+ ///
+ public static string RequestSignatureMissing {
+ get {
+ return ResourceManager.GetString("RequestSignatureMissing", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Received a response message that did not contain an InResponseTo attribute.
+ ///
+ public static string ResponseMissingInResponseToAttribute {
+ get {
+ return ResourceManager.GetString("ResponseMissingInResponseToAttribute", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Response signature is invalid.
+ ///
+ public static string ResponseSignatureInvalid {
+ get {
+ return ResourceManager.GetString("ResponseSignatureInvalid", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Response is not signed.
+ ///
+ public static string ResponseSignatureMissing {
+ get {
+ return ResourceManager.GetString("ResponseSignatureMissing", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Response with status code NoPassive received. A user cannot be signed in with the IsPassiveFlag set when the user does not have a session with the identity provider.
+ ///
+ public static string ResponseStatusIsNoPassive {
+ get {
+ return ResourceManager.GetString("ResponseStatusIsNoPassive", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Response with status code "{0}" received when "Success"was expected.
+ ///
+ public static string ResponseStatusNotSuccessful {
+ get {
+ return ResourceManager.GetString("ResponseStatusNotSuccessful", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to SOAP message did not contain a supported SamlMessage element.
+ ///
+ public static string SOAPMessageUnsupportedSamlMessage {
+ get {
+ return ResourceManager.GetString("SOAPMessageUnsupportedSamlMessage", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to User accessing resource "{0}" without authentication.
+ ///
+ public static string UnauthenticatedAccess {
+ get {
+ return ResourceManager.GetString("UnauthenticatedAccess", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Encoding "{0}" is not supported.
+ ///
+ public static string UnknownEncoding {
+ get {
+ return ResourceManager.GetString("UnknownEncoding", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Unknown identity provider "{0}".
+ ///
+ public static string UnknownIdentityProvider {
+ get {
+ return ResourceManager.GetString("UnknownIdentityProvider", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to RequestType "{0}" is not supported..
+ ///
+ public static string UnsupportedRequestType {
+ get {
+ return ResourceManager.GetString("UnsupportedRequestType", resourceCulture);
+ }
+ }
+ }
+}
diff --git a/src/SAML2.Core/ErrorMessages.resx b/src/SAML2.Core/ErrorMessages.resx
index 9f5b052..a7bad7d 100644
--- a/src/SAML2.Core/ErrorMessages.resx
+++ b/src/SAML2.Core/ErrorMessages.resx
@@ -1,252 +1,252 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- text/microsoft-resx
-
-
- 2.0
-
-
- System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- Artifact is not from a known identity provider
-
-
- Could not verify SAML SOAP binding message signature
-
-
- ArtifactResponse did not contain an assertion
-
-
- Unsupported payload message in ArtifactResponse
-
-
- Could not verify artifact response message signature
-
-
- ArtifactResponse status code was invalid, expected {0}
-
-
- Assertion expiration has been exceeded
-
-
- Could not process assertion with an unknown identity provider
-
-
- Assertion not found
-
-
- Assertion with OneTimeUse condition detected more than once
-
-
- Assertion signature is invalid
-
-
- Attribute query can not be performed when user is not logged in with an identity provider
-
-
- AttrQuery response with status code "{0}" received when "Success" was expected
-
-
- Certificate with DN "{0}" and thumbprint "{1}" is not valid according to RFC3280
-
-
- Certificate {0} was not found
-
-
- Found more than one certificate matching {0}
-
-
- Common Domain Cookie identity provider not found in list of known identity providers: {0}
-
-
- Configuration element <saml2> does not contain an <identityProviders> element
-
-
- Configuration for <identityProviders> does not contain a "metadata" attribute
-
-
- Configuration does not contain <saml2> element
-
-
- Configuration element <saml2> does not contain a <serviceProvider> element
-
-
- Configuration for <serviceProvider> does not contain an "id" attribute
-
-
- Configuration for <serviceProvider> does not contain a <signingCertificate> element
-
-
- Configuration for <serviceProvider> does not contain a SignOn endpoint
-
-
- Specified <signingCertificate> does not have a private key
-
-
- The endpoint binding must be one of POST, Redirect, or Artifact
-
-
- Empty protocol message id is not allowed
-
-
- Session ExpectedInResponseTo missing
-
-
- An error occurred
-
-
- The specified metadata directory "{0}" could not be located
-
-
- The "sign"query string parameter could not be parsed
-
-
- Possible replay attack detected, unexpected value {0} for InResponseTo, expected {1}
-
-
- Request signature is invalid
-
-
- Request is not signed
-
-
- Received a response message that did not contain an InResponseTo attribute
-
-
- Response signature is invalid
-
-
- Response is not signed
-
-
- Response with status code NoPassive received. A user cannot be signed in with the IsPassiveFlag set when the user does not have a session with the identity provider
-
-
- Response with status code "{0}" received when "Success"was expected
-
-
- SOAP message did not contain a supported SamlMessage element
-
-
- User accessing resource "{0}" without authentication
-
-
- Encoding "{0}" is not supported
-
-
- Unknown identity provider "{0}"
-
-
- RequestType "{0}" is not supported.
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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
+
+
+ Artifact is not from a known identity provider
+
+
+ Could not verify SAML SOAP binding message signature
+
+
+ ArtifactResponse did not contain an assertion
+
+
+ Unsupported payload message in ArtifactResponse
+
+
+ Could not verify artifact response message signature
+
+
+ ArtifactResponse status code was invalid, expected {0}
+
+
+ Assertion expiration has been exceeded
+
+
+ Could not process assertion with an unknown identity provider
+
+
+ Assertion not found
+
+
+ Assertion with OneTimeUse condition detected more than once
+
+
+ Assertion signature is invalid
+
+
+ Attribute query can not be performed when user is not logged in with an identity provider
+
+
+ AttrQuery response with status code "{0}" received when "Success" was expected
+
+
+ Certificate with DN "{0}" and thumbprint "{1}" is not valid according to RFC3280
+
+
+ Certificate {0} was not found
+
+
+ Found more than one certificate matching {0}
+
+
+ Common Domain Cookie identity provider not found in list of known identity providers: {0}
+
+
+ Configuration element <saml2> does not contain an <identityProviders> element
+
+
+ Configuration for <identityProviders> does not contain a "metadata" attribute
+
+
+ Configuration does not contain <saml2> element
+
+
+ Configuration element <saml2> does not contain a <serviceProvider> element
+
+
+ Configuration for <serviceProvider> does not contain an "id" attribute
+
+
+ Configuration for <serviceProvider> does not contain a <signingCertificate> element
+
+
+ Configuration for <serviceProvider> does not contain a SignOn endpoint
+
+
+ Specified <signingCertificate> does not have a private key
+
+
+ The endpoint binding must be one of POST, Redirect, or Artifact
+
+
+ Empty protocol message id is not allowed
+
+
+ Session ExpectedInResponseTo missing
+
+
+ An error occurred
+
+
+ The specified metadata directory "{0}" could not be located
+
+
+ The "sign"query string parameter could not be parsed
+
+
+ Possible replay attack detected, unexpected value {0} for InResponseTo, expected {1}
+
+
+ Request signature is invalid
+
+
+ Request is not signed
+
+
+ Received a response message that did not contain an InResponseTo attribute
+
+
+ Response signature is invalid
+
+
+ Response is not signed
+
+
+ Response with status code NoPassive received. A user cannot be signed in with the IsPassiveFlag set when the user does not have a session with the identity provider
+
+
+ Response with status code "{0}" received when "Success"was expected
+
+
+ SOAP message did not contain a supported SamlMessage element
+
+
+ User accessing resource "{0}" without authentication
+
+
+ Encoding "{0}" is not supported
+
+
+ Unknown identity provider "{0}"
+
+
+ RequestType "{0}" is not supported.
+
\ No newline at end of file
diff --git a/src/SAML2.Core/Protocol/Utility.cs b/src/SAML2.Core/Protocol/Utility.cs
index f863c46..bafa353 100644
--- a/src/SAML2.Core/Protocol/Utility.cs
+++ b/src/SAML2.Core/Protocol/Utility.cs
@@ -166,14 +166,15 @@ public static XmlDocument GetDecodedSamlResponse(string samlResponse, Encoding e
logger.DebugFormat(TraceMessages.SamlResponseDecoded, samlResponse);
return doc;
- }
-
- ///
- /// Gets the decrypted assertion.
- ///
- /// The elem.
- /// The decrypted .
- public static Saml20EncryptedAssertion GetDecryptedAssertion(XmlElement elem, Saml2Configuration config)
+ }
+
+ ///
+ /// Gets the decrypted assertion.
+ ///
+ /// The elem.
+ ///
+ /// The decrypted .
+ public static Saml20EncryptedAssertion GetDecryptedAssertion(XmlElement elem, Saml2Configuration config)
{
logger.Debug(TraceMessages.EncryptedAssertionDecrypting);
@@ -195,14 +196,15 @@ public static Status GetStatusElement(XmlElement element)
{
var statElem = element.GetElementsByTagName(Status.ElementName, Saml20Constants.Protocol)[0];
return Serialization.DeserializeFromXmlString(statElem.OuterXml);
- }
-
- ///
- /// Checks for replay attack.
- ///
- /// The context.
- /// The element.
- public static void CheckReplayAttack(XmlElement element, bool requireInResponseTo, IDictionary session)
+ }
+
+ ///
+ /// Checks for replay attack.
+ ///
+ /// The element.
+ ///
+ ///
+ public static void CheckReplayAttack(XmlElement element, bool requireInResponseTo, IDictionary session)
{
logger.Debug(TraceMessages.ReplayAttackCheck);
@@ -246,14 +248,16 @@ public static void AddExpectedResponse(Saml20AuthnRequest request, IDictionary
- /// Deserializes an assertion, verifies its signature and logs in the user if the assertion is valid.
- ///
- /// The context.
- /// The elem.
- public static Saml20Assertion HandleAssertion(XmlElement elem, Saml2Configuration config, Func getFromCache, Action setInCache)
+ }
+
+ ///
+ /// Deserializes an assertion, verifies its signature and logs in the user if the assertion is valid.
+ ///
+ /// The elem.
+ ///
+ ///
+ ///
+ public static Saml20Assertion HandleAssertion(XmlElement elem, Saml2Configuration config, Func getFromCache, Action setInCache)
{
logger.DebugFormat(TraceMessages.AssertionProcessing, elem.OuterXml);
@@ -296,24 +300,31 @@ public static Saml20Assertion HandleAssertion(XmlElement elem, Saml2Configuratio
logger.DebugFormat(TraceMessages.AssertionParsed, assertion.Id);
return assertion;
- }
-
- ///
- /// Decrypts an encrypted assertion, and sends the result to the HandleAssertion method.
- ///
- /// The context.
- /// The elem.
- public static Saml20Assertion HandleEncryptedAssertion(XmlElement elem, Saml2Configuration config, Func getFromCache, Action setInCache)
+ }
+
+ ///
+ /// Decrypts an encrypted assertion, and sends the result to the HandleAssertion method.
+ ///
+ /// The elem.
+ ///
+ ///
+ ///
+ public static Saml20Assertion HandleEncryptedAssertion(XmlElement elem, Saml2Configuration config, Func getFromCache, Action setInCache)
{
return HandleAssertion(GetDecryptedAssertion(elem, config).Assertion.DocumentElement, config, getFromCache, setInCache);
- }
-
- ///
- /// Handles the SOAP.
- ///
- /// The context.
- /// The input stream.
- public static void HandleSoap(HttpArtifactBindingBuilder builder, Stream inputStream, Saml2Configuration config, Action signonCallback, Func getFromCache, Action setInCache, IDictionary session)
+ }
+
+ ///
+ /// Handles the SOAP.
+ ///
+ ///
+ /// The input stream.
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static void HandleSoap(HttpArtifactBindingBuilder builder, Stream inputStream, Saml2Configuration config, Action signonCallback, Func getFromCache, Action setInCache, IDictionary session)
{
var parser = new HttpArtifactBindingParser(inputStream);
logger.DebugFormat(TraceMessages.SOAPMessageParse, parser.SamlMessage.OuterXml);
@@ -371,14 +382,18 @@ public static void HandleSoap(HttpArtifactBindingBuilder builder, Stream inputSt
logger.ErrorFormat(ErrorMessages.SOAPMessageUnsupportedSamlMessage);
throw new Saml20Exception(ErrorMessages.SOAPMessageUnsupportedSamlMessage);
}
- }
-
-
- ///
- /// Handle the authentication response from the IDP.
- ///
- /// The context.
- public static Saml20Assertion HandleResponse(Saml2Configuration config, string samlResponse, IDictionary session, Func getFromCache, Action setInCache)
+ }
+
+
+ ///
+ /// Handle the authentication response from the IDP.
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static Saml20Assertion HandleResponse(Saml2Configuration config, string samlResponse, IDictionary session, Func getFromCache, Action setInCache)
{
var defaultEncoding = Encoding.UTF8;
var doc = Utility.GetDecodedSamlResponse(samlResponse, defaultEncoding);
diff --git a/src/SAML2.Core/SAML2.Core.csproj b/src/SAML2.Core/SAML2.Core.csproj
index 92e6661..c1791a2 100644
--- a/src/SAML2.Core/SAML2.Core.csproj
+++ b/src/SAML2.Core/SAML2.Core.csproj
@@ -1,303 +1,303 @@
-
-
-
- Debug
- AnyCPU
- 8.0.30703
- 2.0
- {75E5BAD2-A20C-43CC-B5C8-38004CEDBDFD}
- Library
- Properties
- SAML2
- SAML2.Core
- v4.5
- 512
-
- ..\
- true
-
-
- true
- full
- false
- bin\Debug\
- DEBUG;TRACE
- prompt
- 4
- false
- true
-
-
- pdbonly
- true
- bin\Release\
- TRACE
- prompt
- 4
- false
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- True
- True
- ErrorMessages.resx
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- True
- True
- Resources.resx
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- True
- True
- TraceMessages.resx
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- PublicResXFileCodeGenerator
- ErrorMessages.Designer.cs
- Designer
-
-
- PublicResXFileCodeGenerator
- Resources.Designer.cs
-
-
- PublicResXFileCodeGenerator
- TraceMessages.Designer.cs
-
-
-
-
+
+
+
+ Debug
+ AnyCPU
+ 8.0.30703
+ 2.0
+ {75E5BAD2-A20C-43CC-B5C8-38004CEDBDFD}
+ Library
+ Properties
+ SAML2
+ SAML2.Core
+ v4.5
+ 512
+
+ ..\
+ true
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+ false
+ true
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ True
+ True
+ ErrorMessages.resx
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ True
+ True
+ Resources.resx
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ True
+ True
+ TraceMessages.resx
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ PublicResXFileCodeGenerator
+ ErrorMessages.Designer.cs
+ Designer
+
+
+ PublicResXFileCodeGenerator
+ Resources.Designer.cs
+
+
+ PublicResXFileCodeGenerator
+ TraceMessages.Designer.cs
+
+
+
+
-
+ -->
+
\ No newline at end of file
diff --git a/src/SAML2.Core/Saml20MetadataDocument.cs b/src/SAML2.Core/Saml20MetadataDocument.cs
index 7b7d9c4..1cf3dc4 100644
--- a/src/SAML2.Core/Saml20MetadataDocument.cs
+++ b/src/SAML2.Core/Saml20MetadataDocument.cs
@@ -160,8 +160,8 @@ private void InitializeDocument(XmlDocument doc)
}
// TODO Decide how to handle several entities in one metadata file.
- if (child.LocalName == EntitiesDescriptor.ElementName) {
- throw new NotImplementedException();
+ if (child.LocalName == EntitiesDescriptor.ElementName) {
+ throw new NotImplementedException( "Decide how to handle several entities in one metadata file" );
}
}
@@ -192,14 +192,16 @@ private static XmlDocument LoadFileAsXmlDocument(string filename, IEnumerable
- /// Loads a file into an XmlDocument. If the loading or the signature check fails, the method will retry using another encoding.
- ///
- /// The filename.
- /// The XML document.
- private static XmlDocument LoadAsXmlDocument(IEnumerable encodings, Action docLoad, Action quirksModeDocLoad)
+ }
+
+ ///
+ /// Loads a file into an XmlDocument. If the loading or the signature check fails, the method will retry using another encoding.
+ ///
+ ///
+ ///
+ ///
+ /// The XML document.
+ private static XmlDocument LoadAsXmlDocument(IEnumerable encodings, Action docLoad, Action quirksModeDocLoad)
{
var doc = new XmlDocument { PreserveWhitespace = true };
@@ -515,13 +517,14 @@ private static EntityDescriptor GetDefaultEntityInstance()
};
return result;
- }
-
- ///
- /// Signs the document.
- ///
- /// The doc.
- private static void SignDocument(XmlDocument doc, X509Certificate2 certificate)
+ }
+
+ ///
+ /// Signs the document.
+ ///
+ /// The doc.
+ ///
+ private static void SignDocument(XmlDocument doc, X509Certificate2 certificate)
{
if (!certificate.HasPrivateKey)
{
@@ -560,8 +563,10 @@ private static void SignDocument(XmlDocument doc, X509Certificate2 certificate)
private void ConvertToMetadata(Saml2Configuration config, KeyInfo keyInfo)
{
var entity = CreateDefaultEntity();
- entity.EntityID = config.ServiceProvider.Id;
- entity.ValidUntil = DateTime.Now.AddDays(7);
+ entity.EntityID = config.ServiceProvider.Id;
+
+ if( config.Metadata.ValidForDays.HasValue )
+ entity.ValidUntil = DateTime.Now.AddDays(config.Metadata.ValidForDays.Value);
var serviceProviderDescriptor = new SpSsoDescriptor
{
diff --git a/src/SAML2.Core/TraceMessages.Designer.cs b/src/SAML2.Core/TraceMessages.Designer.cs
new file mode 100644
index 0000000..5af14ff
--- /dev/null
+++ b/src/SAML2.Core/TraceMessages.Designer.cs
@@ -0,0 +1,531 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by a tool.
+// Runtime Version:4.0.30319.34209
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+namespace SAML2 {
+ using System;
+
+
+ ///
+ /// A strongly-typed resource class, for looking up localized strings, etc.
+ ///
+ // This class was auto-generated by the StronglyTypedResourceBuilder
+ // class via a tool like ResGen or Visual Studio.
+ // To add or remove a member, edit your .ResX file then rerun ResGen
+ // with the /str option, or rebuild your VS project.
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ public class TraceMessages {
+
+ private static global::System.Resources.ResourceManager resourceMan;
+
+ private static global::System.Globalization.CultureInfo resourceCulture;
+
+ [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+ internal TraceMessages() {
+ }
+
+ ///
+ /// Returns the cached ResourceManager instance used by this class.
+ ///
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ public static global::System.Resources.ResourceManager ResourceManager {
+ get {
+ if (object.ReferenceEquals(resourceMan, null)) {
+ global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("SAML2.TraceMessages", typeof(TraceMessages).Assembly);
+ resourceMan = temp;
+ }
+ return resourceMan;
+ }
+ }
+
+ ///
+ /// Overrides the current thread's CurrentUICulture property for all
+ /// resource lookups using this strongly typed resource class.
+ ///
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ public static global::System.Globalization.CultureInfo Culture {
+ get {
+ return resourceCulture;
+ }
+ set {
+ resourceCulture = value;
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Artifact created: {0}.
+ ///
+ public static string ArtifactCreated {
+ get {
+ return ResourceManager.GetString("ArtifactCreated", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Artifact redirect received: {0}.
+ ///
+ public static string ArtifactRedirectReceived {
+ get {
+ return ResourceManager.GetString("ArtifactRedirectReceived", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Artifact resolved: {0}.
+ ///
+ public static string ArtifactResolved {
+ get {
+ return ResourceManager.GetString("ArtifactResolved", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Resolving artifact "{0}" from identity provider "{1}" endpoint "{2}".
+ ///
+ public static string ArtifactResolveForKnownIdentityProvider {
+ get {
+ return ResourceManager.GetString("ArtifactResolveForKnownIdentityProvider", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Artifact resolve received: {0}.
+ ///
+ public static string ArtifactResolveReceived {
+ get {
+ return ResourceManager.GetString("ArtifactResolveReceived", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Sending response to artifact resolve request "{0}": {1}.
+ ///
+ public static string ArtifactResolveResponseSent {
+ get {
+ return ResourceManager.GetString("ArtifactResolveResponseSent", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Artifact response received: {0}.
+ ///
+ public static string ArtifactResponseReceived {
+ get {
+ return ResourceManager.GetString("ArtifactResponseReceived", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Assertion found: {0}.
+ ///
+ public static string AssertionFound {
+ get {
+ return ResourceManager.GetString("AssertionFound", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Assertion being parsed.
+ ///
+ public static string AssertionParse {
+ get {
+ return ResourceManager.GetString("AssertionParse", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Successfully parsed Assertion: {0}.
+ ///
+ public static string AssertionParsed {
+ get {
+ return ResourceManager.GetString("AssertionParsed", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Assertion prehandler called.
+ ///
+ public static string AssertionPrehandlerCalled {
+ get {
+ return ResourceManager.GetString("AssertionPrehandlerCalled", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Processing assertion: {0}.
+ ///
+ public static string AssertionProcessing {
+ get {
+ return ResourceManager.GetString("AssertionProcessing", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to AttrQuery assertion received: {0}.
+ ///
+ public static string AttrQueryAssertionReceived {
+ get {
+ return ResourceManager.GetString("AttrQueryAssertionReceived", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to AttrQuery sent to "{0}": {1}.
+ ///
+ public static string AttrQuerySent {
+ get {
+ return ResourceManager.GetString("AttrQuerySent", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Audience restriction validated for intended URIs {0} against allowed URIs {1}.
+ ///
+ public static string AudienceRestrictionValidated {
+ get {
+ return ResourceManager.GetString("AudienceRestrictionValidated", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to AuthRequest sent for identity provider "{0}" using binding "{1}".
+ ///
+ public static string AuthnRequestPrepared {
+ get {
+ return ResourceManager.GetString("AuthnRequestPrepared", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to AuthnRequest sent: {0}.
+ ///
+ public static string AuthnRequestSent {
+ get {
+ return ResourceManager.GetString("AuthnRequestSent", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Common domain cookie received: {0}.
+ ///
+ public static string CommonDomainCookieReceived {
+ get {
+ return ResourceManager.GetString("CommonDomainCookieReceived", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Redirect to SignOn endpoint found in Common Domain Cookie.
+ ///
+ public static string CommonDomainCookieRedirect {
+ get {
+ return ResourceManager.GetString("CommonDomainCookieRedirect", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Redirecting to Common Domain for identity provider discovery.
+ ///
+ public static string CommonDomainCookieRedirectForDiscovery {
+ get {
+ return ResourceManager.GetString("CommonDomainCookieRedirectForDiscovery", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Redirect to SignOn endpoint "{0}".
+ ///
+ public static string CommonDomainCookieRedirectNotFound {
+ get {
+ return ResourceManager.GetString("CommonDomainCookieRedirectNotFound", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to EncryptedAssertion Decrypted: {0}.
+ ///
+ public static string EncryptedAssertionDecrypted {
+ get {
+ return ResourceManager.GetString("EncryptedAssertionDecrypted", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Decrypting EncryptedAssertion.
+ ///
+ public static string EncryptedAssertionDecrypting {
+ get {
+ return ResourceManager.GetString("EncryptedAssertionDecrypting", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to EncryptedAssertion found: {0}.
+ ///
+ public static string EncryptedAssertionFound {
+ get {
+ return ResourceManager.GetString("EncryptedAssertionFound", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Identity provider not found. Redirecting for identity provider selection.
+ ///
+ public static string IdentityProviderRedirect {
+ get {
+ return ResourceManager.GetString("IdentityProviderRedirect", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Identity provider retreived from Common Domain Cookie: {0}.
+ ///
+ public static string IdentityProviderRetreivedFromCommonDomainCookie {
+ get {
+ return ResourceManager.GetString("IdentityProviderRetreivedFromCommonDomainCookie", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Identity provider retreived from known providers: {0}.
+ ///
+ public static string IdentityProviderRetreivedFromDefault {
+ get {
+ return ResourceManager.GetString("IdentityProviderRetreivedFromDefault", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Identity provider retreived from IDPChoiceParamater: {0}.
+ ///
+ public static string IdentityProviderRetreivedFromQueryString {
+ get {
+ return ResourceManager.GetString("IdentityProviderRetreivedFromQueryString", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Redirecting to idpSelectionUrl for selection of identity provider: {0}.
+ ///
+ public static string IdentityProviderRetreivedFromSelection {
+ get {
+ return ResourceManager.GetString("IdentityProviderRetreivedFromSelection", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Executing Logout Actions.
+ ///
+ public static string LogoutActionsExecuting {
+ get {
+ return ResourceManager.GetString("LogoutActionsExecuting", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Logout handler called.
+ ///
+ public static string LogoutHandlerCalled {
+ get {
+ return ResourceManager.GetString("LogoutHandlerCalled", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Successfully parsed Logout request: {0}.
+ ///
+ public static string LogoutRequestParsed {
+ get {
+ return ResourceManager.GetString("LogoutRequestParsed", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Parsing Logout request POST binding message: {0}.
+ ///
+ public static string LogoutRequestPostBindingParse {
+ get {
+ return ResourceManager.GetString("LogoutRequestPostBindingParse", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Logout request received: {0}.
+ ///
+ public static string LogoutRequestReceived {
+ get {
+ return ResourceManager.GetString("LogoutRequestReceived", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Parsing Logout request Redirect binding message with signature algorithm {1} and signature {2}: {0}.
+ ///
+ public static string LogoutRequestRedirectBindingParse {
+ get {
+ return ResourceManager.GetString("LogoutRequestRedirectBindingParse", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Logout request sent for identity provider "{0}" using "{1}" binding: {2}.
+ ///
+ public static string LogoutRequestSent {
+ get {
+ return ResourceManager.GetString("LogoutRequestSent", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Successfully parsed Logout response: {0}.
+ ///
+ public static string LogoutResponseParsed {
+ get {
+ return ResourceManager.GetString("LogoutResponseParsed", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Parsing Logout response POST binding message: {0}.
+ ///
+ public static string LogoutResponsePostBindingParse {
+ get {
+ return ResourceManager.GetString("LogoutResponsePostBindingParse", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Logout response received.
+ ///
+ public static string LogoutResponseReceived {
+ get {
+ return ResourceManager.GetString("LogoutResponseReceived", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Parsing Logout response Redirect binding message with signature algorithm {1} and signature {2}: {0}.
+ ///
+ public static string LogoutResponseRedirectBindingParse {
+ get {
+ return ResourceManager.GetString("LogoutResponseRedirectBindingParse", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Logout response sent: {0}.
+ ///
+ public static string LogoutResponseSent {
+ get {
+ return ResourceManager.GetString("LogoutResponseSent", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Metadata document being created.
+ ///
+ public static string MetadataDocumentBeingCreated {
+ get {
+ return ResourceManager.GetString("MetadataDocumentBeingCreated", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Metadata document successfully created.
+ ///
+ public static string MetadataDocumentCreated {
+ get {
+ return ResourceManager.GetString("MetadataDocumentCreated", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to No replay attack detected.
+ ///
+ public static string ReplaceAttackCheckCleared {
+ get {
+ return ResourceManager.GetString("ReplaceAttackCheckCleared", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Checking for replay attack.
+ ///
+ public static string ReplayAttackCheck {
+ get {
+ return ResourceManager.GetString("ReplayAttackCheck", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Successfully decoded SamlResponse: {0}.
+ ///
+ public static string SamlResponseDecoded {
+ get {
+ return ResourceManager.GetString("SamlResponseDecoded", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to SamlResponse decoding.
+ ///
+ public static string SamlResponseDecoding {
+ get {
+ return ResourceManager.GetString("SamlResponseDecoding", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to SamlResponse received: {0}.
+ ///
+ public static string SamlResponseReceived {
+ get {
+ return ResourceManager.GetString("SamlResponseReceived", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Executing SignOn Actions.
+ ///
+ public static string SignOnActionsExecuting {
+ get {
+ return ResourceManager.GetString("SignOnActionsExecuting", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to SignOn handler called.
+ ///
+ public static string SignOnHandlerCalled {
+ get {
+ return ResourceManager.GetString("SignOnHandlerCalled", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Successfully processed signon request for "{1}" using NameIdFormat "{2}" for session "{0}".
+ ///
+ public static string SignOnProcessed {
+ get {
+ return ResourceManager.GetString("SignOnProcessed", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Parsing SOAP message: {0}.
+ ///
+ public static string SOAPMessageParse {
+ get {
+ return ResourceManager.GetString("SOAPMessageParse", resourceCulture);
+ }
+ }
+ }
+}
diff --git a/src/SAML2.Core/TraceMessages.resx b/src/SAML2.Core/TraceMessages.resx
index 1f40883..6339bb0 100644
--- a/src/SAML2.Core/TraceMessages.resx
+++ b/src/SAML2.Core/TraceMessages.resx
@@ -1,276 +1,276 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- text/microsoft-resx
-
-
- 2.0
-
-
- System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- Artifact created: {0}
-
-
- Artifact redirect received: {0}
-
-
- Artifact resolved: {0}
-
-
- Resolving artifact "{0}" from identity provider "{1}" endpoint "{2}"
-
-
- Artifact resolve received: {0}
-
-
- Sending response to artifact resolve request "{0}": {1}
-
-
- Artifact response received: {0}
-
-
- AttrQuery assertion received: {0}
-
-
- AttrQuery sent to "{0}": {1}
-
-
- AuthRequest sent for identity provider "{0}" using binding "{1}"
-
-
- Common domain cookie received: {0}
-
-
- Redirect to SignOn endpoint found in Common Domain Cookie
-
-
- Redirect to SignOn endpoint "{0}"
-
-
- Executing Logout Actions
-
-
- Logout request received: {0}
-
-
- Logout request sent for identity provider "{0}" using "{1}" binding: {2}
-
-
- Executing SignOn Actions
-
-
- Successfully processed signon request for "{1}" using NameIdFormat "{2}" for session "{0}"
-
-
- Parsing SOAP message: {0}
-
-
- Assertion found: {0}
-
-
- Assertion being parsed
-
-
- Successfully parsed Assertion: {0}
-
-
- Assertion prehandler called
-
-
- Processing assertion: {0}
-
-
- Audience restriction validated for intended URIs {0} against allowed URIs {1}
-
-
- AuthnRequest sent: {0}
-
-
- Redirecting to Common Domain for identity provider discovery
-
-
- EncryptedAssertion Decrypted: {0}
-
-
- Decrypting EncryptedAssertion
-
-
- EncryptedAssertion found: {0}
-
-
- Identity provider not found. Redirecting for identity provider selection
-
-
- Identity provider retreived from Common Domain Cookie: {0}
-
-
- Identity provider retreived from known providers: {0}
-
-
- Identity provider retreived from IDPChoiceParamater: {0}
-
-
- Redirecting to idpSelectionUrl for selection of identity provider: {0}
-
-
- Logout handler called
-
-
- Successfully parsed Logout request: {0}
-
-
- Parsing Logout request POST binding message: {0}
-
-
- Parsing Logout request Redirect binding message with signature algorithm {1} and signature {2}: {0}
-
-
- Successfully parsed Logout response: {0}
-
-
- Parsing Logout response POST binding message: {0}
-
-
- Logout response received
-
-
- Parsing Logout response Redirect binding message with signature algorithm {1} and signature {2}: {0}
-
-
- Logout response sent: {0}
-
-
- Metadata document being created
-
-
- Metadata document successfully created
-
-
- No replay attack detected
-
-
- Checking for replay attack
-
-
- Successfully decoded SamlResponse: {0}
-
-
- SamlResponse decoding
-
-
- SamlResponse received: {0}
-
-
- SignOn handler called
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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
+
+
+ Artifact created: {0}
+
+
+ Artifact redirect received: {0}
+
+
+ Artifact resolved: {0}
+
+
+ Resolving artifact "{0}" from identity provider "{1}" endpoint "{2}"
+
+
+ Artifact resolve received: {0}
+
+
+ Sending response to artifact resolve request "{0}": {1}
+
+
+ Artifact response received: {0}
+
+
+ AttrQuery assertion received: {0}
+
+
+ AttrQuery sent to "{0}": {1}
+
+
+ AuthRequest sent for identity provider "{0}" using binding "{1}"
+
+
+ Common domain cookie received: {0}
+
+
+ Redirect to SignOn endpoint found in Common Domain Cookie
+
+
+ Redirect to SignOn endpoint "{0}"
+
+
+ Executing Logout Actions
+
+
+ Logout request received: {0}
+
+
+ Logout request sent for identity provider "{0}" using "{1}" binding: {2}
+
+
+ Executing SignOn Actions
+
+
+ Successfully processed signon request for "{1}" using NameIdFormat "{2}" for session "{0}"
+
+
+ Parsing SOAP message: {0}
+
+
+ Assertion found: {0}
+
+
+ Assertion being parsed
+
+
+ Successfully parsed Assertion: {0}
+
+
+ Assertion prehandler called
+
+
+ Processing assertion: {0}
+
+
+ Audience restriction validated for intended URIs {0} against allowed URIs {1}
+
+
+ AuthnRequest sent: {0}
+
+
+ Redirecting to Common Domain for identity provider discovery
+
+
+ EncryptedAssertion Decrypted: {0}
+
+
+ Decrypting EncryptedAssertion
+
+
+ EncryptedAssertion found: {0}
+
+
+ Identity provider not found. Redirecting for identity provider selection
+
+
+ Identity provider retreived from Common Domain Cookie: {0}
+
+
+ Identity provider retreived from known providers: {0}
+
+
+ Identity provider retreived from IDPChoiceParamater: {0}
+
+
+ Redirecting to idpSelectionUrl for selection of identity provider: {0}
+
+
+ Logout handler called
+
+
+ Successfully parsed Logout request: {0}
+
+
+ Parsing Logout request POST binding message: {0}
+
+
+ Parsing Logout request Redirect binding message with signature algorithm {1} and signature {2}: {0}
+
+
+ Successfully parsed Logout response: {0}
+
+
+ Parsing Logout response POST binding message: {0}
+
+
+ Logout response received
+
+
+ Parsing Logout response Redirect binding message with signature algorithm {1} and signature {2}: {0}
+
+
+ Logout response sent: {0}
+
+
+ Metadata document being created
+
+
+ Metadata document successfully created
+
+
+ No replay attack detected
+
+
+ Checking for replay attack
+
+
+ Successfully decoded SamlResponse: {0}
+
+
+ SamlResponse decoding
+
+
+ SamlResponse received: {0}
+
+
+ SignOn handler called
+
\ No newline at end of file
diff --git a/src/SAML2.Tests/Certificates/SafewhereTest_SFS.pfx b/src/SAML2.Tests/Certificates/SafewhereTest_SFS.pfx
new file mode 100644
index 0000000..604649c
Binary files /dev/null and b/src/SAML2.Tests/Certificates/SafewhereTest_SFS.pfx differ
diff --git a/src/SAML2.Tests/Certificates/sts_dev_certificate.pfx b/src/SAML2.Tests/Certificates/sts_dev_certificate.pfx
new file mode 100644
index 0000000..c78d2fb
Binary files /dev/null and b/src/SAML2.Tests/Certificates/sts_dev_certificate.pfx differ
diff --git a/src/SAML2.sln b/src/SAML2.sln
index 72ae66d..20f69ee 100644
--- a/src/SAML2.sln
+++ b/src/SAML2.sln
@@ -1,46 +1,53 @@
-
-Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio 14
-VisualStudioVersion = 14.0.22310.1
-MinimumVisualStudioVersion = 10.0.40219.1
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SAML2.Core", "SAML2.Core\SAML2.Core.csproj", "{75E5BAD2-A20C-43CC-B5C8-38004CEDBDFD}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SAML2.Tests", "SAML2.Tests\SAML2.Tests.csproj", "{39FE8EA4-860C-4A15-A09C-B5B9EEF8CFA2}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Owin.Security.Saml", "Owin.Security.Saml\Owin.Security.Saml.csproj", "{0054DAFD-1A69-4807-B24E-A6A6B71927C7}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SAML2.AspNet", "SAML2.AspNet\SAML2.AspNet.csproj", "{D2136BFD-D2DA-4105-920B-8E05C090C597}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SelfHostOwinSPExample", "SelfHostOwinSPExample\SelfHostOwinSPExample.csproj", "{6A489386-AFB0-4172-ACF4-61F79DC340DC}"
-EndProject
-Global
- GlobalSection(SolutionConfigurationPlatforms) = preSolution
- Debug|Any CPU = Debug|Any CPU
- Release|Any CPU = Release|Any CPU
- EndGlobalSection
- GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {75E5BAD2-A20C-43CC-B5C8-38004CEDBDFD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {75E5BAD2-A20C-43CC-B5C8-38004CEDBDFD}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {75E5BAD2-A20C-43CC-B5C8-38004CEDBDFD}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {75E5BAD2-A20C-43CC-B5C8-38004CEDBDFD}.Release|Any CPU.Build.0 = Release|Any CPU
- {39FE8EA4-860C-4A15-A09C-B5B9EEF8CFA2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {39FE8EA4-860C-4A15-A09C-B5B9EEF8CFA2}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {39FE8EA4-860C-4A15-A09C-B5B9EEF8CFA2}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {39FE8EA4-860C-4A15-A09C-B5B9EEF8CFA2}.Release|Any CPU.Build.0 = Release|Any CPU
- {0054DAFD-1A69-4807-B24E-A6A6B71927C7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {0054DAFD-1A69-4807-B24E-A6A6B71927C7}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {0054DAFD-1A69-4807-B24E-A6A6B71927C7}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {0054DAFD-1A69-4807-B24E-A6A6B71927C7}.Release|Any CPU.Build.0 = Release|Any CPU
- {D2136BFD-D2DA-4105-920B-8E05C090C597}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {D2136BFD-D2DA-4105-920B-8E05C090C597}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {D2136BFD-D2DA-4105-920B-8E05C090C597}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {D2136BFD-D2DA-4105-920B-8E05C090C597}.Release|Any CPU.Build.0 = Release|Any CPU
- {6A489386-AFB0-4172-ACF4-61F79DC340DC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {6A489386-AFB0-4172-ACF4-61F79DC340DC}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {6A489386-AFB0-4172-ACF4-61F79DC340DC}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {6A489386-AFB0-4172-ACF4-61F79DC340DC}.Release|Any CPU.Build.0 = Release|Any CPU
- EndGlobalSection
- GlobalSection(SolutionProperties) = preSolution
- HideSolutionNode = FALSE
- EndGlobalSection
-EndGlobal
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 2013
+VisualStudioVersion = 12.0.40629.0
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SAML2.Core", "SAML2.Core\SAML2.Core.csproj", "{75E5BAD2-A20C-43CC-B5C8-38004CEDBDFD}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SAML2.Tests", "SAML2.Tests\SAML2.Tests.csproj", "{39FE8EA4-860C-4A15-A09C-B5B9EEF8CFA2}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Owin.Security.Saml", "Owin.Security.Saml\Owin.Security.Saml.csproj", "{0054DAFD-1A69-4807-B24E-A6A6B71927C7}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SAML2.AspNet", "SAML2.AspNet\SAML2.AspNet.csproj", "{D2136BFD-D2DA-4105-920B-8E05C090C597}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SelfHostOwinSPExample", "SelfHostOwinSPExample\SelfHostOwinSPExample.csproj", "{6A489386-AFB0-4172-ACF4-61F79DC340DC}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{3042234F-B95F-44EB-A228-C6EAE64F01B1}"
+ ProjectSection(SolutionItems) = preProject
+ .nuget\NuGet.Config = .nuget\NuGet.Config
+ .nuget\NuGet.exe = .nuget\NuGet.exe
+ .nuget\NuGet.targets = .nuget\NuGet.targets
+ EndProjectSection
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {75E5BAD2-A20C-43CC-B5C8-38004CEDBDFD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {75E5BAD2-A20C-43CC-B5C8-38004CEDBDFD}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {75E5BAD2-A20C-43CC-B5C8-38004CEDBDFD}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {75E5BAD2-A20C-43CC-B5C8-38004CEDBDFD}.Release|Any CPU.Build.0 = Release|Any CPU
+ {39FE8EA4-860C-4A15-A09C-B5B9EEF8CFA2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {39FE8EA4-860C-4A15-A09C-B5B9EEF8CFA2}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {39FE8EA4-860C-4A15-A09C-B5B9EEF8CFA2}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {39FE8EA4-860C-4A15-A09C-B5B9EEF8CFA2}.Release|Any CPU.Build.0 = Release|Any CPU
+ {0054DAFD-1A69-4807-B24E-A6A6B71927C7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {0054DAFD-1A69-4807-B24E-A6A6B71927C7}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {0054DAFD-1A69-4807-B24E-A6A6B71927C7}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {0054DAFD-1A69-4807-B24E-A6A6B71927C7}.Release|Any CPU.Build.0 = Release|Any CPU
+ {D2136BFD-D2DA-4105-920B-8E05C090C597}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {D2136BFD-D2DA-4105-920B-8E05C090C597}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {D2136BFD-D2DA-4105-920B-8E05C090C597}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {D2136BFD-D2DA-4105-920B-8E05C090C597}.Release|Any CPU.Build.0 = Release|Any CPU
+ {6A489386-AFB0-4172-ACF4-61F79DC340DC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {6A489386-AFB0-4172-ACF4-61F79DC340DC}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {6A489386-AFB0-4172-ACF4-61F79DC340DC}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {6A489386-AFB0-4172-ACF4-61F79DC340DC}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/src/SAML2.v12.suo b/src/SAML2.v12.suo
new file mode 100644
index 0000000..3f2f14f
Binary files /dev/null and b/src/SAML2.v12.suo differ
diff --git a/src/SelfHostOwinSPExample/SeekableRequestBodyMiddleware.cs b/src/SelfHostOwinSPExample/SeekableRequestBodyMiddleware.cs
new file mode 100644
index 0000000..7227d5f
--- /dev/null
+++ b/src/SelfHostOwinSPExample/SeekableRequestBodyMiddleware.cs
@@ -0,0 +1,33 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Microsoft.Owin;
+
+namespace SelfHostOwinSPExample {
+ ///
+ /// Self-Host Owin Request Body stream is not seekable by default unlike its counter part on IIS
+ ///
+ public class SeekableRequestBodyMiddleware : OwinMiddleware {
+ public SeekableRequestBodyMiddleware( OwinMiddleware next ) : base( next ) { }
+
+ public async override Task Invoke( IOwinContext context ) {
+ ReplaceBodyWithMemoryStreamIfNotCanSeek( context.Request );
+ await Next.Invoke( context );
+ }
+ ///
+ /// In OWIN selfhost environment, Request.Body is using HttpRequestStream that is not rewindable, it is causing issues for other components in pipeline trying to access the body content.
+ ///
+ ///
+ private void ReplaceBodyWithMemoryStreamIfNotCanSeek( IOwinRequest request ) {
+ if( !request.Body.CanSeek ) {
+ var bodyStream = request.Body;
+ request.Body = new MemoryStream();
+ bodyStream.CopyTo( request.Body );
+ request.Body.Seek( 0, SeekOrigin.Begin );
+ }
+ }
+ }
+}
diff --git a/src/SelfHostOwinSPExample/SelfHostOwinSPExample.csproj b/src/SelfHostOwinSPExample/SelfHostOwinSPExample.csproj
index 4bcb46e..81f2ecc 100644
--- a/src/SelfHostOwinSPExample/SelfHostOwinSPExample.csproj
+++ b/src/SelfHostOwinSPExample/SelfHostOwinSPExample.csproj
@@ -1,96 +1,106 @@
-
-
-
-
- Debug
- AnyCPU
- {6A489386-AFB0-4172-ACF4-61F79DC340DC}
- Exe
- Properties
- SelfHostOwinSPExample
- SelfHostOwinSPExample
- v4.5
- 512
-
-
- AnyCPU
- true
- full
- false
- bin\Debug\
- TRACE;DEBUG
- prompt
- 4
-
-
- AnyCPU
- pdbonly
- true
- bin\Release\
- TRACE
- prompt
- 4
-
-
-
- ..\packages\Microsoft.Owin.3.0.0\lib\net45\Microsoft.Owin.dll
-
-
- ..\packages\Microsoft.Owin.Host.HttpListener.3.0.0\lib\net45\Microsoft.Owin.Host.HttpListener.dll
-
-
- ..\packages\Microsoft.Owin.Hosting.3.0.0\lib\net45\Microsoft.Owin.Hosting.dll
-
-
- ..\packages\Microsoft.Owin.Security.3.0.0\lib\net45\Microsoft.Owin.Security.dll
-
-
- ..\packages\Microsoft.Owin.Security.Cookies.3.0.0\lib\net45\Microsoft.Owin.Security.Cookies.dll
-
-
- ..\packages\Owin.1.0\lib\net40\Owin.dll
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Always
-
-
-
-
- {0054dafd-1a69-4807-b24e-a6a6b71927c7}
- Owin.Security.Saml
-
-
- {75e5bad2-a20c-43cc-b5c8-38004cedbdfd}
- SAML2.Core
-
-
-
-
-
-
-
+
+
+
+
+ Debug
+ AnyCPU
+ {6A489386-AFB0-4172-ACF4-61F79DC340DC}
+ Exe
+ Properties
+ SelfHostOwinSPExample
+ SelfHostOwinSPExample
+ v4.5
+ 512
+ ..\
+ true
+
+
+ AnyCPU
+ true
+ full
+ false
+ bin\Debug\
+ TRACE;DEBUG
+ prompt
+ 4
+
+
+ AnyCPU
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+ ..\packages\Microsoft.Owin.3.0.0\lib\net45\Microsoft.Owin.dll
+
+
+ ..\packages\Microsoft.Owin.Host.HttpListener.3.0.0\lib\net45\Microsoft.Owin.Host.HttpListener.dll
+
+
+ ..\packages\Microsoft.Owin.Hosting.3.0.0\lib\net45\Microsoft.Owin.Hosting.dll
+
+
+ ..\packages\Microsoft.Owin.Security.3.0.0\lib\net45\Microsoft.Owin.Security.dll
+
+
+ ..\packages\Microsoft.Owin.Security.Cookies.3.0.0\lib\net45\Microsoft.Owin.Security.Cookies.dll
+
+
+ ..\packages\Owin.1.0\lib\net40\Owin.dll
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Always
+
+
+
+
+ {0054dafd-1a69-4807-b24e-a6a6b71927c7}
+ Owin.Security.Saml
+
+
+ {75e5bad2-a20c-43cc-b5c8-38004cedbdfd}
+ SAML2.Core
+
+
+
+
+
+
+
+
+
+
+ This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
+
+
+
+ -->
\ No newline at end of file
diff --git a/src/SelfHostOwinSPExample/Startup.cs b/src/SelfHostOwinSPExample/Startup.cs
index ba667dc..880724a 100644
--- a/src/SelfHostOwinSPExample/Startup.cs
+++ b/src/SelfHostOwinSPExample/Startup.cs
@@ -1,83 +1,83 @@
-using System;
-using System.Linq;
-using Owin;
-using SAML2.Config;
-using System.IO;
-
-namespace SelfHostOwinSPExample
-{
- internal partial class Startup
- {
- public void Configuration(IAppBuilder appBuilder)
- {
- var config = GetSamlConfiguration();
-#if TEST
- config = TestEnvironmentConfiguration();
-#endif
-
- appBuilder.UseCookieAuthentication(new Microsoft.Owin.Security.Cookies.CookieAuthenticationOptions
- {
- AuthenticationType = "SAML2",
- AuthenticationMode = Microsoft.Owin.Security.AuthenticationMode.Active
- });
- appBuilder.UseSamlAuthentication(new Owin.Security.Saml.SamlAuthenticationOptions
- {
- Configuration = config,
- RedirectAfterLogin = "/core",
- });
- appBuilder.Run(async c => {
- if (c.Authentication.User != null &&
- c.Authentication.User.Identity != null &&
- c.Authentication.User.Identity.IsAuthenticated) {
- await c.Response.WriteAsync(c.Authentication.User.Identity.Name + "\r\n");
- await c.Response.WriteAsync(c.Authentication.User.Identity.AuthenticationType + "\r\n");
- foreach (var claim in c.Authentication.User.Identities.SelectMany(i => i.Claims))
- await c.Response.WriteAsync(claim.Value + "\r\n");
- await c.Response.WriteAsync("authenticated");
- } else {
- // trigger authentication
- c.Authentication.Challenge(c.Authentication.GetAuthenticationTypes().Select(d => d.AuthenticationType).ToArray());
- }
- return;
- });
- }
-
- private Saml2Configuration GetSamlConfiguration()
- {
- var myconfig = new Saml2Configuration
- {
- ServiceProvider = new ServiceProvider
- {
- SigningCertificate = new System.Security.Cryptography.X509Certificates.X509Certificate2(FileEmbeddedResource("SelfHostOwinSPExample.sts_dev_certificate.pfx"), "test1234", System.Security.Cryptography.X509Certificates.X509KeyStorageFlags.MachineKeySet),
- Server = "https://localhost:44333/core",
- Id = "https://localhost:44333/core"
- },
- AllowedAudienceUris = new System.Collections.Generic.List(new[] { new Uri("https://localhost:44333/core") })
- };
- myconfig.ServiceProvider.Endpoints.AddRange(new[] {
- new ServiceProviderEndpoint(EndpointType.SignOn, "/core/saml2/login", "/core"),
- new ServiceProviderEndpoint(EndpointType.Logout, "/core/saml2/logout", "/core"),
- new ServiceProviderEndpoint(EndpointType.Metadata, "/core/saml2/metadata")
- });
- myconfig.IdentityProviders.AddByMetadataDirectory("..\\..\\Metadata");
- //myconfig.IdentityProviders.AddByMetadataUrl(new Uri("https://tas.fhict.nl/identity/saml2/metadata"));
- myconfig.IdentityProviders.First().OmitAssertionSignatureCheck = true;
- myconfig.LoggingFactoryType = "SAML2.Logging.DebugLoggerFactory";
- return myconfig;
- }
-
- private byte[] FileEmbeddedResource(string path)
- {
- var assembly = System.Reflection.Assembly.GetExecutingAssembly();
- var resourceName = path;
-
- byte[] result = null;
- using (Stream stream = assembly.GetManifestResourceStream(resourceName))
- using (var memoryStream = new MemoryStream()) {
- stream.CopyTo(memoryStream);
- result = memoryStream.ToArray();
- }
- return result;
- }
- }
+using System;
+using System.Linq;
+using Owin;
+using SAML2.Config;
+using System.IO;
+
+namespace SelfHostOwinSPExample
+{
+ internal partial class Startup
+ {
+ public void Configuration(IAppBuilder appBuilder)
+ {
+ var config = GetSamlConfiguration();
+#if TEST
+ config = TestEnvironmentConfiguration();
+#endif
+ appBuilder.Use();
+ appBuilder.UseCookieAuthentication(new Microsoft.Owin.Security.Cookies.CookieAuthenticationOptions
+ {
+ AuthenticationType = "SAML2",
+ AuthenticationMode = Microsoft.Owin.Security.AuthenticationMode.Active
+ });
+ appBuilder.UseSamlAuthentication(new Owin.Security.Saml.SamlAuthenticationOptions
+ {
+ Configuration = config,
+ RedirectAfterLogin = "/core",
+ });
+ appBuilder.Run(async c => {
+ if (c.Authentication.User != null &&
+ c.Authentication.User.Identity != null &&
+ c.Authentication.User.Identity.IsAuthenticated) {
+ await c.Response.WriteAsync(c.Authentication.User.Identity.Name + "\r\n");
+ await c.Response.WriteAsync(c.Authentication.User.Identity.AuthenticationType + "\r\n");
+ foreach (var claim in c.Authentication.User.Identities.SelectMany(i => i.Claims))
+ await c.Response.WriteAsync(claim.Value + "\r\n");
+ await c.Response.WriteAsync("authenticated");
+ } else {
+ // trigger authentication
+ c.Authentication.Challenge(c.Authentication.GetAuthenticationTypes().Select(d => d.AuthenticationType).ToArray());
+ }
+ return;
+ });
+ }
+
+ private Saml2Configuration GetSamlConfiguration()
+ {
+ var myconfig = new Saml2Configuration
+ {
+ ServiceProvider = new ServiceProvider
+ {
+ SigningCertificate = new System.Security.Cryptography.X509Certificates.X509Certificate2(FileEmbeddedResource("SelfHostOwinSPExample.sts_dev_certificate.pfx"), "test1234", System.Security.Cryptography.X509Certificates.X509KeyStorageFlags.MachineKeySet),
+ Server = "https://localhost:44333/core",
+ Id = "https://www.testsamlgithub.com"
+ },
+ AllowedAudienceUris = new System.Collections.Generic.List( new[] { new Uri( "https://www.testsamlgithub.com" ) } )
+ };
+ myconfig.ServiceProvider.Endpoints.AddRange(new[] {
+ new ServiceProviderEndpoint(EndpointType.SignOn, "/core/saml2/login", "/core"),
+ new ServiceProviderEndpoint(EndpointType.Logout, "/core/saml2/logout", "/core"),
+ new ServiceProviderEndpoint(EndpointType.Metadata, "/core/saml2/metadata")
+ });
+ myconfig.IdentityProviders.AddByMetadataDirectory("..\\..\\Metadata");
+ //myconfig.IdentityProviders.AddByMetadataUrl(new Uri("https://tas.fhict.nl/identity/saml2/metadata"));
+ myconfig.IdentityProviders.First().OmitAssertionSignatureCheck = true;
+ myconfig.LoggingFactoryType = "SAML2.Logging.DebugLoggerFactory";
+ return myconfig;
+ }
+
+ private byte[] FileEmbeddedResource(string path)
+ {
+ var assembly = System.Reflection.Assembly.GetExecutingAssembly();
+ var resourceName = path;
+
+ byte[] result = null;
+ using (Stream stream = assembly.GetManifestResourceStream(resourceName))
+ using (var memoryStream = new MemoryStream()) {
+ stream.CopyTo(memoryStream);
+ result = memoryStream.ToArray();
+ }
+ return result;
+ }
+ }
}
\ No newline at end of file
diff --git a/src/SelfHostOwinSPExample/sts_dev_certificate.pfx b/src/SelfHostOwinSPExample/sts_dev_certificate.pfx
new file mode 100644
index 0000000..c78d2fb
Binary files /dev/null and b/src/SelfHostOwinSPExample/sts_dev_certificate.pfx differ
diff --git a/src/packages/repositories.config b/src/packages/repositories.config
new file mode 100644
index 0000000..4eb7a7c
--- /dev/null
+++ b/src/packages/repositories.config
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file