diff --git a/.gitignore b/.gitignore index 640d818a9..35810803f 100644 --- a/.gitignore +++ b/.gitignore @@ -114,7 +114,7 @@ nuget/*nupkg *.nuspec !/nuget/*.nuspec -Kentor.AuthServices.StubIdp/App_Data/*.json +Sustainsys.Saml2.StubIdp/App_Data/*.json #Ndepend Stuff *.ndproj diff --git a/README.md b/README.md index eaddd65c4..37d2b6d53 100644 --- a/README.md +++ b/README.md @@ -63,7 +63,7 @@ for keeping application specific user and role information. See the ## Stub Idp The solution also contains a stub (i.e. dummy) identity provider that can be used for testing. -Download the solution, or use the instance that's provided for free at http://stubidp.Sustainsys.se. +Download the solution, or use the instance that's provided for free at http://stubidp.Kentor.se. ## Protocol Classes The protocol handling classes are available as a public API as well, making it possible to diff --git a/Samples/SampleHttpModuleApplication/App_Data/Kentor.AuthServices.Tests.pfx b/Samples/SampleHttpModuleApplication/App_Data/Kentor.AuthServices.Tests.pfx deleted file mode 100644 index 12422cf4f..000000000 Binary files a/Samples/SampleHttpModuleApplication/App_Data/Kentor.AuthServices.Tests.pfx and /dev/null differ diff --git a/Samples/SampleHttpModuleApplication/App_Data/Sustainsys.Saml2.Tests.pfx b/Samples/SampleHttpModuleApplication/App_Data/Sustainsys.Saml2.Tests.pfx new file mode 100644 index 000000000..76893a679 Binary files /dev/null and b/Samples/SampleHttpModuleApplication/App_Data/Sustainsys.Saml2.Tests.pfx differ diff --git a/Samples/SampleHttpModuleApplication/SampleHttpModuleApplication.csproj b/Samples/SampleHttpModuleApplication/SampleHttpModuleApplication.csproj index 2fdb0a2ec..dc6628f6d 100644 --- a/Samples/SampleHttpModuleApplication/SampleHttpModuleApplication.csproj +++ b/Samples/SampleHttpModuleApplication/SampleHttpModuleApplication.csproj @@ -128,20 +128,20 @@ - + {86a588e8-2e2d-4394-9545-24d8ea939cf2} - Kentor.AuthServices.HttpModule + Sustainsys.Saml2.HttpModule - + {93ba675e-a159-4701-b68b-c4b81015c556} - Kentor.AuthServices + Sustainsys.Saml2 - + - + PreserveNewest diff --git a/Samples/SampleHttpModuleApplication/Web.config b/Samples/SampleHttpModuleApplication/Web.config index a01580a4c..a7802e144 100644 --- a/Samples/SampleHttpModuleApplication/Web.config +++ b/Samples/SampleHttpModuleApplication/Web.config @@ -46,8 +46,8 @@ - - + + diff --git a/Samples/SampleIdentityServer3/App_Data/Kentor.AuthServices.Tests.pfx b/Samples/SampleIdentityServer3/App_Data/Kentor.AuthServices.Tests.pfx deleted file mode 100644 index 12422cf4f..000000000 Binary files a/Samples/SampleIdentityServer3/App_Data/Kentor.AuthServices.Tests.pfx and /dev/null differ diff --git a/Samples/SampleIdentityServer3/App_Data/Kentor.AuthServices.SampleIdentityServer3.pfx b/Samples/SampleIdentityServer3/App_Data/Sustainsys.Saml2.SampleIdentityServer3.pfx similarity index 100% rename from Samples/SampleIdentityServer3/App_Data/Kentor.AuthServices.SampleIdentityServer3.pfx rename to Samples/SampleIdentityServer3/App_Data/Sustainsys.Saml2.SampleIdentityServer3.pfx diff --git a/Samples/SampleIdentityServer3/App_Data/Sustainsys.Saml2.Tests.pfx b/Samples/SampleIdentityServer3/App_Data/Sustainsys.Saml2.Tests.pfx new file mode 100644 index 000000000..76893a679 Binary files /dev/null and b/Samples/SampleIdentityServer3/App_Data/Sustainsys.Saml2.Tests.pfx differ diff --git a/Samples/SampleIdentityServer3/SampleIdentityServer3.csproj b/Samples/SampleIdentityServer3/SampleIdentityServer3.csproj index 75fb96a76..e7c107017 100644 --- a/Samples/SampleIdentityServer3/SampleIdentityServer3.csproj +++ b/Samples/SampleIdentityServer3/SampleIdentityServer3.csproj @@ -133,12 +133,12 @@ - + - + PreserveNewest @@ -161,13 +161,13 @@ - + {fa1e7723-124c-4d2d-a731-e16400b0073b} - Kentor.AuthServices.Owin + Sustainsys.Saml2.Owin - + {93ba675e-a159-4701-b68b-c4b81015c556} - Kentor.AuthServices + Sustainsys.Saml2 diff --git a/Samples/SampleMvcApplication/App_Data/Kentor.AuthServices.Tests.pfx b/Samples/SampleMvcApplication/App_Data/Kentor.AuthServices.Tests.pfx deleted file mode 100644 index 12422cf4f..000000000 Binary files a/Samples/SampleMvcApplication/App_Data/Kentor.AuthServices.Tests.pfx and /dev/null differ diff --git a/Samples/SampleMvcApplication/App_Data/Sustainsys.Saml2.Tests.pfx b/Samples/SampleMvcApplication/App_Data/Sustainsys.Saml2.Tests.pfx new file mode 100644 index 000000000..76893a679 Binary files /dev/null and b/Samples/SampleMvcApplication/App_Data/Sustainsys.Saml2.Tests.pfx differ diff --git a/Samples/SampleMvcApplication/SampleMvcApplication.csproj b/Samples/SampleMvcApplication/SampleMvcApplication.csproj index 68cd7be89..841c0e65e 100644 --- a/Samples/SampleMvcApplication/SampleMvcApplication.csproj +++ b/Samples/SampleMvcApplication/SampleMvcApplication.csproj @@ -131,8 +131,8 @@ - - + + @@ -156,9 +156,9 @@ - + {7d32f0a3-cec8-4dc6-a096-5905ea9c3770} - Kentor.AuthServices.Mvc + Sustainsys.Saml2.Mvc diff --git a/Samples/SampleMvcApplication/Web.config b/Samples/SampleMvcApplication/Web.config index d271e5998..68ee3c596 100644 --- a/Samples/SampleMvcApplication/Web.config +++ b/Samples/SampleMvcApplication/Web.config @@ -33,10 +33,10 @@ - - + diff --git a/Samples/SampleOwinApplication/App_Data/Kentor.AuthServices.Tests.pfx b/Samples/SampleOwinApplication/App_Data/Kentor.AuthServices.Tests.pfx deleted file mode 100644 index 12422cf4f..000000000 Binary files a/Samples/SampleOwinApplication/App_Data/Kentor.AuthServices.Tests.pfx and /dev/null differ diff --git a/Samples/SampleOwinApplication/App_Data/Sustainsys.Saml2.Tests.pfx b/Samples/SampleOwinApplication/App_Data/Sustainsys.Saml2.Tests.pfx new file mode 100644 index 000000000..76893a679 Binary files /dev/null and b/Samples/SampleOwinApplication/App_Data/Sustainsys.Saml2.Tests.pfx differ diff --git a/Samples/SampleOwinApplication/App_Start/Startup.Auth.cs b/Samples/SampleOwinApplication/App_Start/Startup.Auth.cs index 08828b635..da7956a8b 100644 --- a/Samples/SampleOwinApplication/App_Start/Startup.Auth.cs +++ b/Samples/SampleOwinApplication/App_Start/Startup.Auth.cs @@ -59,17 +59,17 @@ private static SustainsysSaml2AuthenticationOptions CreateSaml2Options() SPOptions = spOptions }; - var idp = new IdentityProvider(new EntityId("http://stubidp.Sustainsys.se/Metadata"), spOptions) + var idp = new IdentityProvider(new EntityId("http://stubidp.Kentor.se/Metadata"), spOptions) { AllowUnsolicitedAuthnResponse = true, Binding = Saml2BindingType.HttpRedirect, - SingleSignOnServiceUrl = new Uri("http://stubidp.Sustainsys.se") + SingleSignOnServiceUrl = new Uri("http://stubidp.Kentor.se") }; idp.SigningKeys.AddConfiguredKey( new X509Certificate2( HostingEnvironment.MapPath( - "~/App_Data/Sustainsys.Saml2.StubIdp.cer"))); + "~/App_Data/Kentor.AuthServices.StubIdp.cer"))); Saml2Options.IdentityProviders.Add(idp); diff --git a/Samples/SampleOwinApplication/SampleOwinApplication.csproj b/Samples/SampleOwinApplication/SampleOwinApplication.csproj index ab0e53625..7e5973f73 100644 --- a/Samples/SampleOwinApplication/SampleOwinApplication.csproj +++ b/Samples/SampleOwinApplication/SampleOwinApplication.csproj @@ -215,8 +215,8 @@ - - + + @@ -278,13 +278,13 @@ - + {fa1e7723-124c-4d2d-a731-e16400b0073b} - Kentor.AuthServices.Owin + Sustainsys.Saml2.Owin - + {93ba675e-a159-4701-b68b-c4b81015c556} - Kentor.AuthServices + Sustainsys.Saml2 diff --git a/Sustainsys.Saml2.AspNetCore2/Sustainsys.Saml2.AspNetCore2.csproj b/Sustainsys.Saml2.AspNetCore2/Sustainsys.Saml2.AspNetCore2.csproj index c65247a02..0e16a0c44 100644 --- a/Sustainsys.Saml2.AspNetCore2/Sustainsys.Saml2.AspNetCore2.csproj +++ b/Sustainsys.Saml2.AspNetCore2/Sustainsys.Saml2.AspNetCore2.csproj @@ -152,7 +152,7 @@ - + {93BA675E-A159-4701-B68B-C4B81015C556} Kentor.AuthServices diff --git a/Kentor.AuthServices.HttpModule/CommandResultHttpExtensions.cs b/Sustainsys.Saml2.HttpModule/CommandResultHttpExtensions.cs similarity index 100% rename from Kentor.AuthServices.HttpModule/CommandResultHttpExtensions.cs rename to Sustainsys.Saml2.HttpModule/CommandResultHttpExtensions.cs diff --git a/Kentor.AuthServices.HttpModule/CommandResultHttpExtensionsShared.cs b/Sustainsys.Saml2.HttpModule/CommandResultHttpExtensionsShared.cs similarity index 100% rename from Kentor.AuthServices.HttpModule/CommandResultHttpExtensionsShared.cs rename to Sustainsys.Saml2.HttpModule/CommandResultHttpExtensionsShared.cs diff --git a/Kentor.AuthServices.HttpModule/HttpRequestBaseExtensions.cs b/Sustainsys.Saml2.HttpModule/HttpRequestBaseExtensions.cs similarity index 100% rename from Kentor.AuthServices.HttpModule/HttpRequestBaseExtensions.cs rename to Sustainsys.Saml2.HttpModule/HttpRequestBaseExtensions.cs diff --git a/Kentor.AuthServices.HttpModule/Saml2AuthenticationModule.cs b/Sustainsys.Saml2.HttpModule/Saml2AuthenticationModule.cs similarity index 97% rename from Kentor.AuthServices.HttpModule/Saml2AuthenticationModule.cs rename to Sustainsys.Saml2.HttpModule/Saml2AuthenticationModule.cs index c478eb21d..6e8e7eaca 100644 --- a/Kentor.AuthServices.HttpModule/Saml2AuthenticationModule.cs +++ b/Sustainsys.Saml2.HttpModule/Saml2AuthenticationModule.cs @@ -1,88 +1,88 @@ -using Sustainsys.Saml2.Configuration; -using Sustainsys.Saml2.WebSso; -using System; -using System.Diagnostics.CodeAnalysis; -using System.Net; -using System.Web; - -namespace Sustainsys.Saml2.HttpModule -{ - /// - /// Http Module for SAML2 authentication. The module hijacks the - /// ~/Saml2AuthenticationModule/ path of the http application to provide - /// authentication services. - /// - // Not included in code coverage as the http module is tightly dependent on IIS. - [ExcludeFromCodeCoverage] - public class Saml2AuthenticationModule : IHttpModule - { - /// - /// The one and only options instance used by the - /// . It is instantiated by - /// loading the web.config, but after that it can be modified or even - /// replaced from code. - /// - public static IOptions Options { get; set; } = Configuration.Options.FromConfiguration; - - /// - /// Init the module and subscribe to events. - /// - /// - public void Init(HttpApplication context) - { - if (context == null) - { - throw new ArgumentNullException(nameof(context)); - } - - // Run our code post authentication to allow any session authentication - // to be done first (required by logout) but still execute as close - // as possible to the normal authentication step. - context.AuthenticateRequest += OnAuthenticateRequest; - } - - /// - /// Begin request handler that captures all traffic to configured module - /// path. - /// - /// The http application. - /// Ignored - protected void OnAuthenticateRequest(object sender, EventArgs e) - { - var application = (HttpApplication)sender; - - // Strip the leading ~ from the AppRelative path. - var appRelativePath = application.Request.AppRelativeCurrentExecutionFilePath; - appRelativePath = (!string.IsNullOrEmpty(appRelativePath)) - ? appRelativePath.Substring(1) - : string.Empty; - - var modulePath = Options.SPOptions.ModulePath; - - if (appRelativePath.StartsWith(modulePath, StringComparison.OrdinalIgnoreCase)) - { - var commandName = appRelativePath.Substring(modulePath.Length); - - var command = CommandFactory.GetCommand(commandName); - var commandResult = command.Run( - new HttpRequestWrapper(application.Request).ToHttpRequestData(), - Options); - - if (!commandResult.HandledResult) - { - commandResult.SignInOrOutSessionAuthenticationModule(); - commandResult.Apply(new HttpResponseWrapper(application.Response)); - } - } - } - - /// - /// IDisposable implementation. - /// - public virtual void Dispose() - { - // Deliberately do nothing, unsubscribing from events is not - // needed by the IIS model. Trying to do so throws exceptions. - } - } -} +using Sustainsys.Saml2.Configuration; +using Sustainsys.Saml2.WebSso; +using System; +using System.Diagnostics.CodeAnalysis; +using System.Net; +using System.Web; + +namespace Sustainsys.Saml2.HttpModule +{ + /// + /// Http Module for SAML2 authentication. The module hijacks the + /// ~/Saml2AuthenticationModule/ path of the http application to provide + /// authentication services. + /// + // Not included in code coverage as the http module is tightly dependent on IIS. + [ExcludeFromCodeCoverage] + public class Saml2AuthenticationModule : IHttpModule + { + /// + /// The one and only options instance used by the + /// . It is instantiated by + /// loading the web.config, but after that it can be modified or even + /// replaced from code. + /// + public static IOptions Options { get; set; } = Configuration.Options.FromConfiguration; + + /// + /// Init the module and subscribe to events. + /// + /// + public void Init(HttpApplication context) + { + if (context == null) + { + throw new ArgumentNullException(nameof(context)); + } + + // Run our code post authentication to allow any session authentication + // to be done first (required by logout) but still execute as close + // as possible to the normal authentication step. + context.AuthenticateRequest += OnAuthenticateRequest; + } + + /// + /// Begin request handler that captures all traffic to configured module + /// path. + /// + /// The http application. + /// Ignored + protected void OnAuthenticateRequest(object sender, EventArgs e) + { + var application = (HttpApplication)sender; + + // Strip the leading ~ from the AppRelative path. + var appRelativePath = application.Request.AppRelativeCurrentExecutionFilePath; + appRelativePath = (!string.IsNullOrEmpty(appRelativePath)) + ? appRelativePath.Substring(1) + : string.Empty; + + var modulePath = Options.SPOptions.ModulePath; + + if (appRelativePath.StartsWith(modulePath, StringComparison.OrdinalIgnoreCase)) + { + var commandName = appRelativePath.Substring(modulePath.Length); + + var command = CommandFactory.GetCommand(commandName); + var commandResult = command.Run( + new HttpRequestWrapper(application.Request).ToHttpRequestData(), + Options); + + if (!commandResult.HandledResult) + { + commandResult.SignInOrOutSessionAuthenticationModule(); + commandResult.Apply(new HttpResponseWrapper(application.Response)); + } + } + } + + /// + /// IDisposable implementation. + /// + public virtual void Dispose() + { + // Deliberately do nothing, unsubscribing from events is not + // needed by the IIS model. Trying to do so throws exceptions. + } + } +} diff --git a/Kentor.AuthServices.HttpModule/Kentor.AuthServices.HttpModule.csproj b/Sustainsys.Saml2.HttpModule/Sustainsys.Saml2.HttpModule.csproj similarity index 85% rename from Kentor.AuthServices.HttpModule/Kentor.AuthServices.HttpModule.csproj rename to Sustainsys.Saml2.HttpModule/Sustainsys.Saml2.HttpModule.csproj index 07fdd169f..2d3930f76 100644 --- a/Kentor.AuthServices.HttpModule/Kentor.AuthServices.HttpModule.csproj +++ b/Sustainsys.Saml2.HttpModule/Sustainsys.Saml2.HttpModule.csproj @@ -7,8 +7,8 @@ {86A588E8-2E2D-4394-9545-24D8EA939CF2} Library Properties - Kentor.AuthServices.HttpModule - Kentor.AuthServices.HttpModule + Sustainsys.Saml2.HttpModule + Sustainsys.Saml2.HttpModule v4.5 512 @@ -21,8 +21,8 @@ prompt 4 true - ..\Kentor.AuthServices.ruleset - bin\Debug\Kentor.AuthServices.HttpModule.XML + ..\Sustainsys.Saml2.ruleset + bin\Debug\Sustainsys.Saml2.HttpModule.XML pdbonly @@ -31,7 +31,7 @@ TRACE prompt 4 - bin\Release\Kentor.AuthServices.HttpModule.XML + bin\Release\Sustainsys.Saml2.HttpModule.XML @@ -56,9 +56,9 @@ - + {93ba675e-a159-4701-b68b-c4b81015c556} - Kentor.AuthServices + Sustainsys.Saml2 diff --git a/Kentor.AuthServices.HttpModule/properties/AssemblyInfo.cs b/Sustainsys.Saml2.HttpModule/properties/AssemblyInfo.cs similarity index 100% rename from Kentor.AuthServices.HttpModule/properties/AssemblyInfo.cs rename to Sustainsys.Saml2.HttpModule/properties/AssemblyInfo.cs diff --git a/Kentor.AuthServices.Mvc/CommandResultExtensions.cs b/Sustainsys.Saml2.Mvc/CommandResultExtensions.cs similarity index 97% rename from Kentor.AuthServices.Mvc/CommandResultExtensions.cs rename to Sustainsys.Saml2.Mvc/CommandResultExtensions.cs index 44568a52d..a1973d357 100644 --- a/Kentor.AuthServices.Mvc/CommandResultExtensions.cs +++ b/Sustainsys.Saml2.Mvc/CommandResultExtensions.cs @@ -1,58 +1,58 @@ -using Sustainsys.Saml2.WebSso; -using System; -using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; -using System.IdentityModel.Services; -using System.IdentityModel.Tokens; -using System.Linq; -using System.Net; -using System.Text; -using System.Threading.Tasks; -using System.Web; -using System.Web.Mvc; - -namespace Sustainsys.Saml2.Mvc -{ - /// - /// Extension methods for CommandResult for integrating CommandResults in - /// the MVC architecture. - /// - public static class CommandResultExtensions - { - /// - /// Converts a command result to an action result. - /// - /// The source command result. - /// Action result - /// The reason to use a separate command result at all, instead - /// of simply using ActionResult is that the core library should not - /// be Mvc dependant. - public static ActionResult ToActionResult(this CommandResult commandResult) - { - if (commandResult == null) - { - throw new ArgumentNullException(nameof(commandResult)); - } - - switch (commandResult.HttpStatusCode) - { - case HttpStatusCode.SeeOther: - return new RedirectResult(commandResult.Location.OriginalString); - case HttpStatusCode.OK: - var result = new ContentResult() - { - Content = commandResult.Content - }; - - if(!string.IsNullOrEmpty(commandResult.ContentType)) - { - result.ContentType = commandResult.ContentType; - } - - return result; - default: - throw new NotImplementedException(); - } - } - } -} +using Sustainsys.Saml2.WebSso; +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.IdentityModel.Services; +using System.IdentityModel.Tokens; +using System.Linq; +using System.Net; +using System.Text; +using System.Threading.Tasks; +using System.Web; +using System.Web.Mvc; + +namespace Sustainsys.Saml2.Mvc +{ + /// + /// Extension methods for CommandResult for integrating CommandResults in + /// the MVC architecture. + /// + public static class CommandResultExtensions + { + /// + /// Converts a command result to an action result. + /// + /// The source command result. + /// Action result + /// The reason to use a separate command result at all, instead + /// of simply using ActionResult is that the core library should not + /// be Mvc dependant. + public static ActionResult ToActionResult(this CommandResult commandResult) + { + if (commandResult == null) + { + throw new ArgumentNullException(nameof(commandResult)); + } + + switch (commandResult.HttpStatusCode) + { + case HttpStatusCode.SeeOther: + return new RedirectResult(commandResult.Location.OriginalString); + case HttpStatusCode.OK: + var result = new ContentResult() + { + Content = commandResult.Content + }; + + if(!string.IsNullOrEmpty(commandResult.ContentType)) + { + result.ContentType = commandResult.ContentType; + } + + return result; + default: + throw new NotImplementedException(); + } + } + } +} diff --git a/Kentor.AuthServices.Mvc/Properties/AssemblyInfo.cs b/Sustainsys.Saml2.Mvc/Properties/AssemblyInfo.cs similarity index 97% rename from Kentor.AuthServices.Mvc/Properties/AssemblyInfo.cs rename to Sustainsys.Saml2.Mvc/Properties/AssemblyInfo.cs index 11a310eee..084d63c47 100644 --- a/Kentor.AuthServices.Mvc/Properties/AssemblyInfo.cs +++ b/Sustainsys.Saml2.Mvc/Properties/AssemblyInfo.cs @@ -1,23 +1,23 @@ -using System; -using System.Reflection; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("Sustainsys.Saml2.Mvc")] -[assembly: AssemblyDescription("SAML2 Authentication for ASP.NET MVC")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyProduct("Sustainsys.Saml2.Mvc")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("31667812-08d4-4ca1-ab40-9a063e180155")] - +using System; +using System.Reflection; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("Sustainsys.Saml2.Mvc")] +[assembly: AssemblyDescription("SAML2 Authentication for ASP.NET MVC")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyProduct("Sustainsys.Saml2.Mvc")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("31667812-08d4-4ca1-ab40-9a063e180155")] + [assembly: CLSCompliant(true)] \ No newline at end of file diff --git a/Kentor.AuthServices.Mvc/AuthServicesController.cs b/Sustainsys.Saml2.Mvc/Saml2Controller.cs similarity index 97% rename from Kentor.AuthServices.Mvc/AuthServicesController.cs rename to Sustainsys.Saml2.Mvc/Saml2Controller.cs index c81279ed3..52cfa77d9 100644 --- a/Kentor.AuthServices.Mvc/AuthServicesController.cs +++ b/Sustainsys.Saml2.Mvc/Saml2Controller.cs @@ -1,127 +1,127 @@ -using System; -using System.Net; -using System.Web.Mvc; -using System.IdentityModel.Services; -using Sustainsys.Saml2.HttpModule; -using Sustainsys.Saml2.Configuration; -using Sustainsys.Saml2.WebSso; -using System.Diagnostics.CodeAnalysis; - -namespace Sustainsys.Saml2.Mvc -{ - /// - /// Mvc Controller that provides the authentication functionality. - /// - [AllowAnonymous] - public class Saml2Controller : Controller - { - private static IOptions options = null; - - /// - /// The options used by the controller. By default read from config, - /// but can be set. - /// - public static IOptions Options { - get - { - if(options == null) - { - options = Configuration.Options.FromConfiguration; - } - return options; - } - set - { - options = value; - } - } - - /// - /// SignIn action that sends the AuthnRequest to the Idp. - /// - /// Redirect with sign in request - [SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "HandledResult")] - [SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "CommandResult")] - public ActionResult SignIn() - { - var result = CommandFactory.GetCommand(CommandFactory.SignInCommandName).Run( - Request.ToHttpRequestData(), - Options); - - if(result.HandledResult) - { - throw new NotSupportedException("The MVC controller doesn't support setting CommandResult.HandledResult."); - } - - result.ApplyCookies(Response); - return result.ToActionResult(); - } - - /// - /// Assertion consumer Url that accepts the incoming Saml response. - /// - /// Redirect to start page on success. - /// The action effectively accepts the SAMLResponse, but - /// due to using common infrastructure it is read for the current - /// http request. - [SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "HandledResult")] - [SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "CommandResult")] - public ActionResult Acs() - { - var result = CommandFactory.GetCommand(CommandFactory.AcsCommandName).Run( - Request.ToHttpRequestData(), - Options); - - if(result.HandledResult) - { - throw new NotSupportedException("The MVC controller doesn't support setting CommandResult.HandledResult."); - } - - result.SignInOrOutSessionAuthenticationModule(); - result.ApplyCookies(Response); - return result.ToActionResult(); - } - - /// - /// Metadata of the service provider. - /// - /// ActionResult with Metadata - [SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "HandledResult")] - [SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "CommandResult")] - public ActionResult Index() - { - var result = CommandFactory.GetCommand(CommandFactory.MetadataCommand).Run( - Request.ToHttpRequestData(), - Options); - - if (result.HandledResult) - { - throw new NotSupportedException("The MVC controller doesn't support setting CommandResult.HandledResult."); - } - - return result.ToActionResult(); - } - - /// - /// Logout locally and if Idp supports it, perform a federated logout - /// - /// ActionResult - [SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "HandledResult")] - [SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "CommandResult")] - [SuppressMessage("Microsoft.Naming", "CA1726:UsePreferredTerms", MessageId = "Logout")] - public ActionResult Logout() - { - var result = CommandFactory.GetCommand(CommandFactory.LogoutCommandName) - .Run(Request.ToHttpRequestData(), Options); - - if (result.HandledResult) - { - throw new NotSupportedException("The MVC controller doesn't support setting CommandResult.HandledResult."); - } - - result.SignInOrOutSessionAuthenticationModule(); - result.ApplyCookies(Response); - return result.ToActionResult(); - } - } -} +using System; +using System.Net; +using System.Web.Mvc; +using System.IdentityModel.Services; +using Sustainsys.Saml2.HttpModule; +using Sustainsys.Saml2.Configuration; +using Sustainsys.Saml2.WebSso; +using System.Diagnostics.CodeAnalysis; + +namespace Sustainsys.Saml2.Mvc +{ + /// + /// Mvc Controller that provides the authentication functionality. + /// + [AllowAnonymous] + public class Saml2Controller : Controller + { + private static IOptions options = null; + + /// + /// The options used by the controller. By default read from config, + /// but can be set. + /// + public static IOptions Options { + get + { + if(options == null) + { + options = Configuration.Options.FromConfiguration; + } + return options; + } + set + { + options = value; + } + } + + /// + /// SignIn action that sends the AuthnRequest to the Idp. + /// + /// Redirect with sign in request + [SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "HandledResult")] + [SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "CommandResult")] + public ActionResult SignIn() + { + var result = CommandFactory.GetCommand(CommandFactory.SignInCommandName).Run( + Request.ToHttpRequestData(), + Options); + + if(result.HandledResult) + { + throw new NotSupportedException("The MVC controller doesn't support setting CommandResult.HandledResult."); + } + + result.ApplyCookies(Response); + return result.ToActionResult(); + } + + /// + /// Assertion consumer Url that accepts the incoming Saml response. + /// + /// Redirect to start page on success. + /// The action effectively accepts the SAMLResponse, but + /// due to using common infrastructure it is read for the current + /// http request. + [SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "HandledResult")] + [SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "CommandResult")] + public ActionResult Acs() + { + var result = CommandFactory.GetCommand(CommandFactory.AcsCommandName).Run( + Request.ToHttpRequestData(), + Options); + + if(result.HandledResult) + { + throw new NotSupportedException("The MVC controller doesn't support setting CommandResult.HandledResult."); + } + + result.SignInOrOutSessionAuthenticationModule(); + result.ApplyCookies(Response); + return result.ToActionResult(); + } + + /// + /// Metadata of the service provider. + /// + /// ActionResult with Metadata + [SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "HandledResult")] + [SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "CommandResult")] + public ActionResult Index() + { + var result = CommandFactory.GetCommand(CommandFactory.MetadataCommand).Run( + Request.ToHttpRequestData(), + Options); + + if (result.HandledResult) + { + throw new NotSupportedException("The MVC controller doesn't support setting CommandResult.HandledResult."); + } + + return result.ToActionResult(); + } + + /// + /// Logout locally and if Idp supports it, perform a federated logout + /// + /// ActionResult + [SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "HandledResult")] + [SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "CommandResult")] + [SuppressMessage("Microsoft.Naming", "CA1726:UsePreferredTerms", MessageId = "Logout")] + public ActionResult Logout() + { + var result = CommandFactory.GetCommand(CommandFactory.LogoutCommandName) + .Run(Request.ToHttpRequestData(), Options); + + if (result.HandledResult) + { + throw new NotSupportedException("The MVC controller doesn't support setting CommandResult.HandledResult."); + } + + result.SignInOrOutSessionAuthenticationModule(); + result.ApplyCookies(Response); + return result.ToActionResult(); + } + } +} diff --git a/Kentor.AuthServices.Mvc/Kentor.AuthServices.Mvc.csproj b/Sustainsys.Saml2.Mvc/Sustainsys.Saml2.Mvc.csproj similarity index 86% rename from Kentor.AuthServices.Mvc/Kentor.AuthServices.Mvc.csproj rename to Sustainsys.Saml2.Mvc/Sustainsys.Saml2.Mvc.csproj index b88891f6d..2ce6328f2 100644 --- a/Kentor.AuthServices.Mvc/Kentor.AuthServices.Mvc.csproj +++ b/Sustainsys.Saml2.Mvc/Sustainsys.Saml2.Mvc.csproj @@ -1,113 +1,113 @@ - - - - - Release - AnyCPU - {7D32F0A3-CEC8-4DC6-A096-5905EA9C3770} - Library - Properties - Kentor.AuthServices.Mvc - Kentor.AuthServices.Mvc - v4.5 - 512 - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - ..\Kentor.AuthServices.ruleset - true - bin\Debug\Kentor.AuthServices.Mvc.XML - - - full - true - bin\Release\ - TRACE - prompt - 4 - true - bin\Release\Kentor.AuthServices.Mvc.XML - - - - ..\packages\Microsoft.Web.Infrastructure.1.0.0.0\lib\net40\Microsoft.Web.Infrastructure.dll - True - - - - - - - - ..\packages\Microsoft.AspNet.WebPages.2.0.20710.0\lib\net40\System.Web.Helpers.dll - True - - - ..\packages\Microsoft.AspNet.Mvc.4.0.20710.0\lib\net40\System.Web.Mvc.dll - True - - - ..\packages\Microsoft.AspNet.Razor.2.0.20710.0\lib\net40\System.Web.Razor.dll - True - - - ..\packages\Microsoft.AspNet.WebPages.2.0.20710.0\lib\net40\System.Web.WebPages.dll - True - - - ..\packages\Microsoft.AspNet.WebPages.2.0.20710.0\lib\net40\System.Web.WebPages.Deployment.dll - True - - - ..\packages\Microsoft.AspNet.WebPages.2.0.20710.0\lib\net40\System.Web.WebPages.Razor.dll - True - - - - - - - - - - CommandResultHttpExtensionsShared.cs - - - HttpRequestBaseExtensions.cs - - - VersionInfo.cs - - - - - - - - {93ba675e-a159-4701-b68b-c4b81015c556} - Kentor.AuthServices - - - - - CustomDictionary.xml - - - - - - - + + + + + Release + AnyCPU + {7D32F0A3-CEC8-4DC6-A096-5905EA9C3770} + Library + Properties + Sustainsys.Saml2.Mvc + Sustainsys.Saml2.Mvc + v4.5 + 512 + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + ..\Sustainsys.Saml2.ruleset + true + bin\Debug\Sustainsys.Saml2.Mvc.XML + + + full + true + bin\Release\ + TRACE + prompt + 4 + true + bin\Release\Sustainsys.Saml2.Mvc.XML + + + + ..\packages\Microsoft.Web.Infrastructure.1.0.0.0\lib\net40\Microsoft.Web.Infrastructure.dll + True + + + + + + + + ..\packages\Microsoft.AspNet.WebPages.2.0.20710.0\lib\net40\System.Web.Helpers.dll + True + + + ..\packages\Microsoft.AspNet.Mvc.4.0.20710.0\lib\net40\System.Web.Mvc.dll + True + + + ..\packages\Microsoft.AspNet.Razor.2.0.20710.0\lib\net40\System.Web.Razor.dll + True + + + ..\packages\Microsoft.AspNet.WebPages.2.0.20710.0\lib\net40\System.Web.WebPages.dll + True + + + ..\packages\Microsoft.AspNet.WebPages.2.0.20710.0\lib\net40\System.Web.WebPages.Deployment.dll + True + + + ..\packages\Microsoft.AspNet.WebPages.2.0.20710.0\lib\net40\System.Web.WebPages.Razor.dll + True + + + + + + + + + + CommandResultHttpExtensionsShared.cs + + + HttpRequestBaseExtensions.cs + + + VersionInfo.cs + + + + + + + + {93ba675e-a159-4701-b68b-c4b81015c556} + Sustainsys.Saml2 + + + + + CustomDictionary.xml + + + + + + + \ No newline at end of file diff --git a/Kentor.AuthServices.Mvc/packages.config b/Sustainsys.Saml2.Mvc/packages.config similarity index 98% rename from Kentor.AuthServices.Mvc/packages.config rename to Sustainsys.Saml2.Mvc/packages.config index 282f19288..a6ff6a0c7 100644 --- a/Kentor.AuthServices.Mvc/packages.config +++ b/Sustainsys.Saml2.Mvc/packages.config @@ -1,7 +1,7 @@ - - - - - - + + + + + + \ No newline at end of file diff --git a/Kentor.AuthServices.Owin/CommandResultExtensions.cs b/Sustainsys.Saml2.Owin/CommandResultExtensions.cs similarity index 100% rename from Kentor.AuthServices.Owin/CommandResultExtensions.cs rename to Sustainsys.Saml2.Owin/CommandResultExtensions.cs diff --git a/Kentor.AuthServices.Owin/Constants.cs b/Sustainsys.Saml2.Owin/Constants.cs similarity index 100% rename from Kentor.AuthServices.Owin/Constants.cs rename to Sustainsys.Saml2.Owin/Constants.cs diff --git a/Kentor.AuthServices.Owin/GlobalSuppressions.cs b/Sustainsys.Saml2.Owin/GlobalSuppressions.cs similarity index 100% rename from Kentor.AuthServices.Owin/GlobalSuppressions.cs rename to Sustainsys.Saml2.Owin/GlobalSuppressions.cs diff --git a/Kentor.AuthServices.Owin/MultipleIdentityAuthenticationTicket.cs b/Sustainsys.Saml2.Owin/MultipleIdentityAuthenticationTicket.cs similarity index 100% rename from Kentor.AuthServices.Owin/MultipleIdentityAuthenticationTicket.cs rename to Sustainsys.Saml2.Owin/MultipleIdentityAuthenticationTicket.cs diff --git a/Kentor.AuthServices.Owin/OwinContextExtensions.cs b/Sustainsys.Saml2.Owin/OwinContextExtensions.cs similarity index 100% rename from Kentor.AuthServices.Owin/OwinContextExtensions.cs rename to Sustainsys.Saml2.Owin/OwinContextExtensions.cs diff --git a/Kentor.AuthServices.Owin/OwinLoggerAdapter.cs b/Sustainsys.Saml2.Owin/OwinLoggerAdapter.cs similarity index 100% rename from Kentor.AuthServices.Owin/OwinLoggerAdapter.cs rename to Sustainsys.Saml2.Owin/OwinLoggerAdapter.cs diff --git a/Kentor.AuthServices.Owin/Properties/AssemblyInfo.cs b/Sustainsys.Saml2.Owin/Properties/AssemblyInfo.cs similarity index 100% rename from Kentor.AuthServices.Owin/Properties/AssemblyInfo.cs rename to Sustainsys.Saml2.Owin/Properties/AssemblyInfo.cs diff --git a/Kentor.AuthServices.Owin/KentorAuthServicesAuthenticationExtensions.cs b/Sustainsys.Saml2.Owin/Saml2AuthenticationExtensions.cs similarity index 100% rename from Kentor.AuthServices.Owin/KentorAuthServicesAuthenticationExtensions.cs rename to Sustainsys.Saml2.Owin/Saml2AuthenticationExtensions.cs diff --git a/Kentor.AuthServices.Owin/KentorAuthServicesAuthenticationHandler.cs b/Sustainsys.Saml2.Owin/Saml2AuthenticationHandler.cs similarity index 100% rename from Kentor.AuthServices.Owin/KentorAuthServicesAuthenticationHandler.cs rename to Sustainsys.Saml2.Owin/Saml2AuthenticationHandler.cs diff --git a/Kentor.AuthServices.Owin/KentorAuthServicesAuthenticationMiddleware.cs b/Sustainsys.Saml2.Owin/Saml2AuthenticationMiddleware.cs similarity index 100% rename from Kentor.AuthServices.Owin/KentorAuthServicesAuthenticationMiddleware.cs rename to Sustainsys.Saml2.Owin/Saml2AuthenticationMiddleware.cs diff --git a/Kentor.AuthServices.Owin/KentorAuthServicesAuthenticationOptions.cs b/Sustainsys.Saml2.Owin/Saml2AuthenticationOptions.cs similarity index 100% rename from Kentor.AuthServices.Owin/KentorAuthServicesAuthenticationOptions.cs rename to Sustainsys.Saml2.Owin/Saml2AuthenticationOptions.cs diff --git a/Kentor.AuthServices.Owin/Kentor.AuthServices.Owin.csproj b/Sustainsys.Saml2.Owin/Sustainsys.Saml2.Owin.csproj similarity index 83% rename from Kentor.AuthServices.Owin/Kentor.AuthServices.Owin.csproj rename to Sustainsys.Saml2.Owin/Sustainsys.Saml2.Owin.csproj index 3fc84fc84..45b35d88e 100644 --- a/Kentor.AuthServices.Owin/Kentor.AuthServices.Owin.csproj +++ b/Sustainsys.Saml2.Owin/Sustainsys.Saml2.Owin.csproj @@ -7,8 +7,8 @@ {FA1E7723-124C-4D2D-A731-E16400B0073B} Library Properties - Kentor.AuthServices.Owin - Kentor.AuthServices.Owin + Sustainsys.Saml2.Owin + Sustainsys.Saml2.Owin v4.5 512 @@ -20,9 +20,9 @@ DEBUG;TRACE prompt 4 - bin\Debug\Kentor.AuthServices.Owin.XML + bin\Debug\Sustainsys.Saml2.Owin.XML true - ..\Kentor.AuthServices.ruleset + ..\Sustainsys.Saml2.ruleset full @@ -32,7 +32,7 @@ prompt 4 true - bin\Release\Kentor.AuthServices.Owin.XML + bin\Release\Sustainsys.Saml2.Owin.XML @@ -64,10 +64,10 @@ - - - - + + + + @@ -82,9 +82,9 @@ - + {93ba675e-a159-4701-b68b-c4b81015c556} - Kentor.AuthServices + Sustainsys.Saml2 diff --git a/Kentor.AuthServices.Owin/packages.config b/Sustainsys.Saml2.Owin/packages.config similarity index 100% rename from Kentor.AuthServices.Owin/packages.config rename to Sustainsys.Saml2.Owin/packages.config diff --git a/Sustainsys.Saml2.StubIdp/CertificateHelper.cs b/Sustainsys.Saml2.StubIdp/CertificateHelper.cs index 098c8e987..a92f2e09d 100644 --- a/Sustainsys.Saml2.StubIdp/CertificateHelper.cs +++ b/Sustainsys.Saml2.StubIdp/CertificateHelper.cs @@ -15,9 +15,9 @@ public static X509Certificate2 SigningCertificate { get { - // If accessing on the legacy stubidp.Sustainsys.se host name, use old certificate + // If accessing on the legacy stubidp.Kentor.se host name, use old certificate // to not break existing configured clients. - if(HttpContext.Current.Request.Url.Host == "stubidp.Sustainsys.se") + if(HttpContext.Current.Request.Url.Host == "stubidp.Kentor.se") { return signingCertificateSustainsys; } @@ -30,7 +30,7 @@ public static X509Certificate2 SigningCertificate private static readonly X509Certificate2 signingCertificateSustainsys = new X509Certificate2( HttpContext.Current.Server.MapPath( - "~\\App_Data\\Sustainsys.Saml2.StubIdp.pfx"), "", + "~\\App_Data\\Kentor.AuthServices.StubIdp.pfx"), "", X509KeyStorageFlags.MachineKeySet); private static readonly X509Certificate2 signingCertificate @@ -43,9 +43,9 @@ public static KeyDescriptor SigningKey { get { - // If accessing on the legacy stubidp.Sustainsys.se host name, use old certificate + // If accessing on the legacy stubidp.Kentor.se host name, use old certificate // to not break existing configured clients. - if (HttpContext.Current.Request.Url.Host == "stubidp.Sustainsys.se") + if (HttpContext.Current.Request.Url.Host == "stubidp.Kentor.se") { return signingKeySustainsys; } diff --git a/Sustainsys.Saml2.StubIdp/Controllers/CertificateController.cs b/Sustainsys.Saml2.StubIdp/Controllers/CertificateController.cs index 5a83726fc..9719d7e19 100644 --- a/Sustainsys.Saml2.StubIdp/Controllers/CertificateController.cs +++ b/Sustainsys.Saml2.StubIdp/Controllers/CertificateController.cs @@ -8,8 +8,8 @@ public class CertificateController : Controller { public ActionResult Index() { - var path = Request.Url.Host == "stubidp.Sustainsys.se" - ? HttpContext.Server.MapPath("~\\App_Data\\Sustainsys.Saml2.StubIdp.cer") + var path = Request.Url.Host == "stubidp.Kentor.se" + ? HttpContext.Server.MapPath("~\\App_Data\\Kentor.AuthServices.StubIdp.cer") : HttpContext.Server.MapPath("~\\App_Data\\stubidp.sustainsys.com.cer"); var disposition = new ContentDisposition { Inline = false, FileName = Path.GetFileName(path) }; diff --git a/Sustainsys.Saml2.StubIdp/Sustainsys.Saml2.StubIdp.csproj b/Sustainsys.Saml2.StubIdp/Sustainsys.Saml2.StubIdp.csproj index b3a69bd8d..86afc08c7 100644 --- a/Sustainsys.Saml2.StubIdp/Sustainsys.Saml2.StubIdp.csproj +++ b/Sustainsys.Saml2.StubIdp/Sustainsys.Saml2.StubIdp.csproj @@ -11,8 +11,8 @@ {349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc} Library Properties - Kentor.AuthServices.StubIdp - Kentor.AuthServices.StubIdp + Sustainsys.Saml2.StubIdp + Sustainsys.Saml2.StubIdp v4.6.2 true @@ -118,8 +118,6 @@ - - @@ -127,6 +125,9 @@ + + + @@ -197,13 +198,13 @@ - + {7d32f0a3-cec8-4dc6-a096-5905ea9c3770} - Kentor.AuthServices.Mvc + Sustainsys.Saml2.Mvc - + {93ba675e-a159-4701-b68b-c4b81015c556} - Kentor.AuthServices + Sustainsys.Saml2 diff --git a/Sustainsys.Saml2.StubIdp/Views/Home/Index.cshtml b/Sustainsys.Saml2.StubIdp/Views/Home/Index.cshtml index ec280b3e0..9c94657e2 100644 --- a/Sustainsys.Saml2.StubIdp/Views/Home/Index.cshtml +++ b/Sustainsys.Saml2.StubIdp/Views/Home/Index.cshtml @@ -18,7 +18,7 @@ } -@if (Request.Url.Host == "stubidp.Sustainsys.se") +@if (Request.Url.Host == "stubidp.Kentor.se") {
@@ -28,7 +28,7 @@
This service has moved to https://stubidp.sustainsys.com. The - stubidp.Sustainsys.se host name will be removed, please update your configuration. All custom tenant information + stubidp.Kentor.se host name will be removed, please update your configuration. All custom tenant information is the same accross the domain names.
diff --git a/Kentor.AuthServices.ruleset b/Sustainsys.Saml2.ruleset similarity index 97% rename from Kentor.AuthServices.ruleset rename to Sustainsys.Saml2.ruleset index 21388883d..f52a6b49d 100644 --- a/Kentor.AuthServices.ruleset +++ b/Sustainsys.Saml2.ruleset @@ -1,588 +1,588 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Sustainsys.Saml2.sln b/Sustainsys.Saml2.sln index a14de5136..cfa6e85ec 100644 --- a/Sustainsys.Saml2.sln +++ b/Sustainsys.Saml2.sln @@ -1,18 +1,18 @@  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 15 -VisualStudioVersion = 15.0.27130.2010 +VisualStudioVersion = 15.0.27130.2020 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kentor.AuthServices", "Kentor.AuthServices\Kentor.AuthServices.csproj", "{93BA675E-A159-4701-B68B-C4B81015C556}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sustainsys.Saml2", "Sustainsys.Saml2\Sustainsys.Saml2.csproj", "{93BA675E-A159-4701-B68B-C4B81015C556}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{E0C4834E-A7A9-476F-8F46-B2D533190872}" ProjectSection(SolutionItems) = preProject CodeCoverage.runsettings = CodeCoverage.runsettings CONTRIBUTING.md = CONTRIBUTING.md CONTRIBUTORS.txt = CONTRIBUTORS.txt - Kentor.AuthServices.ruleset = Kentor.AuthServices.ruleset LICENSE = LICENSE README.md = README.md + Sustainsys.Saml2.ruleset = Sustainsys.Saml2.ruleset VersionInfo.cs = VersionInfo.cs EndProjectSection EndProject @@ -27,23 +27,24 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "doc", "doc", "{DB9690FA-251 EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "nuget", "nuget", "{8EE1C45E-A81F-4D3F-A645-4C20528E327F}" ProjectSection(SolutionItems) = preProject - nuget\Kentor.AuthServices.HttpModule.nuspec = nuget\Kentor.AuthServices.HttpModule.nuspec - nuget\Kentor.AuthServices.Mvc.nuspec = nuget\Kentor.AuthServices.Mvc.nuspec - nuget\Kentor.AuthServices.nuspec = nuget\Kentor.AuthServices.nuspec - nuget\Kentor.AuthServices.Owin.nuspec = nuget\Kentor.AuthServices.Owin.nuspec nuget\kentor.png = nuget\kentor.png nuget\MakePackage.ps1 = nuget\MakePackage.ps1 nuget\ReleaseNotes.txt = nuget\ReleaseNotes.txt + nuget\Sustainsys.png = nuget\Sustainsys.png nuget\Sustainsys.Saml2.AspNetCore2.nuspec = nuget\Sustainsys.Saml2.AspNetCore2.nuspec + nuget\Sustainsys.Saml2.HttpModule.nuspec = nuget\Sustainsys.Saml2.HttpModule.nuspec + nuget\Sustainsys.Saml2.Mvc.nuspec = nuget\Sustainsys.Saml2.Mvc.nuspec + nuget\Sustainsys.Saml2.nuspec = nuget\Sustainsys.Saml2.nuspec + nuget\Sustainsys.Saml2.Owin.nuspec = nuget\Sustainsys.Saml2.Owin.nuspec EndProjectSection EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kentor.AuthServices.Mvc", "Kentor.AuthServices.Mvc\Kentor.AuthServices.Mvc.csproj", "{7D32F0A3-CEC8-4DC6-A096-5905EA9C3770}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sustainsys.Saml2.Mvc", "Sustainsys.Saml2.Mvc\Sustainsys.Saml2.Mvc.csproj", "{7D32F0A3-CEC8-4DC6-A096-5905EA9C3770}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sustainsys.Saml2.StubIdp", "Sustainsys.Saml2.StubIdp\Sustainsys.Saml2.StubIdp.csproj", "{7B60747D-6337-4424-ACB5-7D580EC1E1A1}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kentor.AuthServices.Owin", "Kentor.AuthServices.Owin\Kentor.AuthServices.Owin.csproj", "{FA1E7723-124C-4D2D-A731-E16400B0073B}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sustainsys.Saml2.Owin", "Sustainsys.Saml2.Owin\Sustainsys.Saml2.Owin.csproj", "{FA1E7723-124C-4D2D-A731-E16400B0073B}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kentor.AuthServices.HttpModule", "Kentor.AuthServices.HttpModule\Kentor.AuthServices.HttpModule.csproj", "{86A588E8-2E2D-4394-9545-24D8EA939CF2}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sustainsys.Saml2.HttpModule", "Sustainsys.Saml2.HttpModule\Sustainsys.Saml2.HttpModule.csproj", "{86A588E8-2E2D-4394-9545-24D8EA939CF2}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Samples", "Samples", "{09639770-8C2B-4D30-BBFC-4F6DD1A92C89}" EndProject diff --git a/Kentor.AuthServices/CertificateStatus.cs b/Sustainsys.Saml2/CertificateStatus.cs similarity index 100% rename from Kentor.AuthServices/CertificateStatus.cs rename to Sustainsys.Saml2/CertificateStatus.cs diff --git a/Kentor.AuthServices/CertificateUse.cs b/Sustainsys.Saml2/CertificateUse.cs similarity index 100% rename from Kentor.AuthServices/CertificateUse.cs rename to Sustainsys.Saml2/CertificateUse.cs diff --git a/Kentor.AuthServices/ClaimsExtensions.cs b/Sustainsys.Saml2/ClaimsExtensions.cs similarity index 100% rename from Kentor.AuthServices/ClaimsExtensions.cs rename to Sustainsys.Saml2/ClaimsExtensions.cs diff --git a/Kentor.AuthServices/ClaimsIdentityExtensions.cs b/Sustainsys.Saml2/ClaimsIdentityExtensions.cs similarity index 97% rename from Kentor.AuthServices/ClaimsIdentityExtensions.cs rename to Sustainsys.Saml2/ClaimsIdentityExtensions.cs index d12d25b81..59282ad39 100644 --- a/Kentor.AuthServices/ClaimsIdentityExtensions.cs +++ b/Sustainsys.Saml2/ClaimsIdentityExtensions.cs @@ -1,138 +1,138 @@ -using System; -using System.IdentityModel.Tokens; -using System.Security.Claims; -using System.Linq; -using System.IdentityModel.Metadata; - -namespace Sustainsys.Saml2 -{ - /// - /// Extension methods for Claims Identities - /// - public static class ClaimsIdentityExtensions - { - /// - /// Creates a Saml2Assertion from a ClaimsIdentity. - /// - /// Claims to include in Assertion. - /// Issuer to include in assertion. - /// Saml2Assertion - public static Saml2Assertion ToSaml2Assertion(this ClaimsIdentity identity, EntityId issuer) - { - return ToSaml2Assertion(identity, issuer, null); - } - - /// - /// Creates a Saml2Assertion from a ClaimsIdentity. - /// - /// Claims to include in Assertion. - /// Issuer to include in assertion. - /// Audience to set as audience restriction. - /// Saml2Assertion - public static Saml2Assertion ToSaml2Assertion( - this ClaimsIdentity identity, - EntityId issuer, - Uri audience) - { - return ToSaml2Assertion(identity, issuer, audience, null, null); - } - - /// - /// Creates a Saml2Assertion from a ClaimsIdentity. - /// - /// Claims to include in Assertion. - /// Issuer to include in assertion. - /// Audience to set as audience restriction. - /// In response to id - /// The destination Uri for the message - /// Saml2Assertion - /// - public static Saml2Assertion ToSaml2Assertion( - this ClaimsIdentity identity, - EntityId issuer, - Uri audience, - Saml2Id inResponseTo, - Uri destinationUri) - { - if (identity == null) - { - throw new ArgumentNullException(nameof(identity)); - } - - if (issuer == null) - { - throw new ArgumentNullException(nameof(issuer)); - } - - var assertion = new Saml2Assertion(new Saml2NameIdentifier(issuer.Id)); - - assertion.Statements.Add( - new Saml2AuthenticationStatement( - new Saml2AuthenticationContext( - new Uri("urn:oasis:names:tc:SAML:2.0:ac:classes:unspecified"))) - { - SessionIndex = identity.Claims.SingleOrDefault( - c => c.Type == Saml2ClaimTypes.SessionIndex)?.Value - }); - - var attributeClaims = identity.Claims.Where( - c => c.Type != ClaimTypes.NameIdentifier - && c.Type != Saml2ClaimTypes.SessionIndex).GroupBy(c => c.Type) - .ToArray(); - - if (attributeClaims.Any()) - { - assertion.Statements.Add( - new Saml2AttributeStatement( - attributeClaims.Select( - ac => new Saml2Attribute(ac.Key, ac.Select(c => c.Value))))); - } - - var notOnOrAfter = DateTime.UtcNow.AddMinutes(2); - - assertion.Subject = new Saml2Subject(identity.ToSaml2NameIdentifier()) - { - SubjectConfirmations = - { - new Saml2SubjectConfirmation( - new Uri("urn:oasis:names:tc:SAML:2.0:cm:bearer"), - new Saml2SubjectConfirmationData - { - NotOnOrAfter = notOnOrAfter, - InResponseTo = inResponseTo, - Recipient = destinationUri - }) - } - }; - - assertion.Conditions = new Saml2Conditions() - { - NotOnOrAfter = notOnOrAfter - }; - - if (audience != null) - { - assertion.Conditions.AudienceRestrictions.Add( - new Saml2AudienceRestriction(audience)); - } - - return assertion; - } - - /// - /// Create a Saml2NameIdentifier from the identity. - /// - /// Identity to get NameIdentifier claim from. - /// Saml2NameIdentifier - public static Saml2NameIdentifier ToSaml2NameIdentifier(this ClaimsIdentity identity) - { - if(identity == null) - { - throw new ArgumentNullException(nameof(identity)); - } - - return identity.Claims.Single(c => c.Type == ClaimTypes.NameIdentifier) - .ToSaml2NameIdentifier(); - } - } -} +using System; +using System.IdentityModel.Tokens; +using System.Security.Claims; +using System.Linq; +using System.IdentityModel.Metadata; + +namespace Sustainsys.Saml2 +{ + /// + /// Extension methods for Claims Identities + /// + public static class ClaimsIdentityExtensions + { + /// + /// Creates a Saml2Assertion from a ClaimsIdentity. + /// + /// Claims to include in Assertion. + /// Issuer to include in assertion. + /// Saml2Assertion + public static Saml2Assertion ToSaml2Assertion(this ClaimsIdentity identity, EntityId issuer) + { + return ToSaml2Assertion(identity, issuer, null); + } + + /// + /// Creates a Saml2Assertion from a ClaimsIdentity. + /// + /// Claims to include in Assertion. + /// Issuer to include in assertion. + /// Audience to set as audience restriction. + /// Saml2Assertion + public static Saml2Assertion ToSaml2Assertion( + this ClaimsIdentity identity, + EntityId issuer, + Uri audience) + { + return ToSaml2Assertion(identity, issuer, audience, null, null); + } + + /// + /// Creates a Saml2Assertion from a ClaimsIdentity. + /// + /// Claims to include in Assertion. + /// Issuer to include in assertion. + /// Audience to set as audience restriction. + /// In response to id + /// The destination Uri for the message + /// Saml2Assertion + /// + public static Saml2Assertion ToSaml2Assertion( + this ClaimsIdentity identity, + EntityId issuer, + Uri audience, + Saml2Id inResponseTo, + Uri destinationUri) + { + if (identity == null) + { + throw new ArgumentNullException(nameof(identity)); + } + + if (issuer == null) + { + throw new ArgumentNullException(nameof(issuer)); + } + + var assertion = new Saml2Assertion(new Saml2NameIdentifier(issuer.Id)); + + assertion.Statements.Add( + new Saml2AuthenticationStatement( + new Saml2AuthenticationContext( + new Uri("urn:oasis:names:tc:SAML:2.0:ac:classes:unspecified"))) + { + SessionIndex = identity.Claims.SingleOrDefault( + c => c.Type == Saml2ClaimTypes.SessionIndex)?.Value + }); + + var attributeClaims = identity.Claims.Where( + c => c.Type != ClaimTypes.NameIdentifier + && c.Type != Saml2ClaimTypes.SessionIndex).GroupBy(c => c.Type) + .ToArray(); + + if (attributeClaims.Any()) + { + assertion.Statements.Add( + new Saml2AttributeStatement( + attributeClaims.Select( + ac => new Saml2Attribute(ac.Key, ac.Select(c => c.Value))))); + } + + var notOnOrAfter = DateTime.UtcNow.AddMinutes(2); + + assertion.Subject = new Saml2Subject(identity.ToSaml2NameIdentifier()) + { + SubjectConfirmations = + { + new Saml2SubjectConfirmation( + new Uri("urn:oasis:names:tc:SAML:2.0:cm:bearer"), + new Saml2SubjectConfirmationData + { + NotOnOrAfter = notOnOrAfter, + InResponseTo = inResponseTo, + Recipient = destinationUri + }) + } + }; + + assertion.Conditions = new Saml2Conditions() + { + NotOnOrAfter = notOnOrAfter + }; + + if (audience != null) + { + assertion.Conditions.AudienceRestrictions.Add( + new Saml2AudienceRestriction(audience)); + } + + return assertion; + } + + /// + /// Create a Saml2NameIdentifier from the identity. + /// + /// Identity to get NameIdentifier claim from. + /// Saml2NameIdentifier + public static Saml2NameIdentifier ToSaml2NameIdentifier(this ClaimsIdentity identity) + { + if(identity == null) + { + throw new ArgumentNullException(nameof(identity)); + } + + return identity.Claims.Single(c => c.Type == ClaimTypes.NameIdentifier) + .ToSaml2NameIdentifier(); + } + } +} diff --git a/Kentor.AuthServices/Configuration/ArtifactResolutionServiceCollection.cs b/Sustainsys.Saml2/Configuration/ArtifactResolutionServiceCollection.cs similarity index 100% rename from Kentor.AuthServices/Configuration/ArtifactResolutionServiceCollection.cs rename to Sustainsys.Saml2/Configuration/ArtifactResolutionServiceCollection.cs diff --git a/Kentor.AuthServices/Configuration/ArtifactResolutionServiceElement.cs b/Sustainsys.Saml2/Configuration/ArtifactResolutionServiceElement.cs similarity index 100% rename from Kentor.AuthServices/Configuration/ArtifactResolutionServiceElement.cs rename to Sustainsys.Saml2/Configuration/ArtifactResolutionServiceElement.cs diff --git a/Kentor.AuthServices/Configuration/CertificateCollection.cs b/Sustainsys.Saml2/Configuration/CertificateCollection.cs similarity index 100% rename from Kentor.AuthServices/Configuration/CertificateCollection.cs rename to Sustainsys.Saml2/Configuration/CertificateCollection.cs diff --git a/Kentor.AuthServices/Configuration/CertificateElement.cs b/Sustainsys.Saml2/Configuration/CertificateElement.cs similarity index 96% rename from Kentor.AuthServices/Configuration/CertificateElement.cs rename to Sustainsys.Saml2/Configuration/CertificateElement.cs index 330c82d45..40a1e5e5f 100644 --- a/Kentor.AuthServices/Configuration/CertificateElement.cs +++ b/Sustainsys.Saml2/Configuration/CertificateElement.cs @@ -1,149 +1,149 @@ -using Sustainsys.Saml2.Internal; -using System; -using System.Configuration; -using System.Diagnostics.CodeAnalysis; -using System.Globalization; -using System.Linq; -using System.Security.Cryptography.X509Certificates; -using System.Web; - -namespace Sustainsys.Saml2.Configuration -{ - /// - /// Config element for the signing certificate. - /// - public class CertificateElement : ConfigurationElement - { - private bool isReadOnly = true; - - internal void AllowConfigEdit(bool allow) - { - isReadOnly = !allow; - } - - /// - /// Allows local modification of the configuration for testing purposes - /// - /// - public override bool IsReadOnly() - { - return isReadOnly; - } - - /// - /// File name of cert stored in file. - /// - [ConfigurationProperty("fileName")] - public string FileName - { - get - { - return (string)this["fileName"]; - } - internal set - { - base["fileName"] = value; - } - } - - /// - /// Store name to search. - /// - [ConfigurationProperty("storeName")] - [ExcludeFromCodeCoverage] - public StoreName StoreName - { - get - { - return (StoreName)this["storeName"]; - } - } - - /// - /// Store location to search. - /// - [ConfigurationProperty("storeLocation")] - [ExcludeFromCodeCoverage] - public StoreLocation StoreLocation - { - get - { - return (StoreLocation)this["storeLocation"]; - } - } - - /// - /// The search term used for searching the certificate store. - /// - [ConfigurationProperty("findValue")] - [ExcludeFromCodeCoverage] - public string FindValue - { - get - { - return (string)this["findValue"]; - } - } - - /// - /// Find type, what field to search. - /// - [ConfigurationProperty("x509FindType")] - [ExcludeFromCodeCoverage] - public X509FindType X509FindType - { - get - { - return (X509FindType)this["x509FindType"]; - } - } - - /// - /// Load the certificate pointed to by this configuration. - /// - /// Certificate - [ExcludeFromCodeCoverage] - public X509Certificate2 LoadCertificate() - { - if (!string.IsNullOrEmpty(FileName)) - { - string fileName = FileName; - fileName = PathHelper.MapPath(fileName); - - return new X509Certificate2(fileName, "", X509KeyStorageFlags.MachineKeySet); - } - else - { - // A 0 store location indicates that attributes to load from store are not present - // in the config. - if (StoreLocation != 0) - { - var store = new X509Store(StoreName, StoreLocation); - store.Open(OpenFlags.ReadOnly); - try - { - var certs = store.Certificates.Find(X509FindType, FindValue, false); - - if (certs.Count != 1) - { - throw new InvalidOperationException( - string.Format(CultureInfo.InvariantCulture, - "Finding cert through {0} in {1}:{2} with value {3} matched {4} certificates. A unique match is required.", - X509FindType, StoreLocation, StoreName, FindValue, certs.Count)); - } - - return certs[0]; - } - finally - { - store.Close(); - } - } - else - { - return null; - } - } - } - } -} +using Sustainsys.Saml2.Internal; +using System; +using System.Configuration; +using System.Diagnostics.CodeAnalysis; +using System.Globalization; +using System.Linq; +using System.Security.Cryptography.X509Certificates; +using System.Web; + +namespace Sustainsys.Saml2.Configuration +{ + /// + /// Config element for the signing certificate. + /// + public class CertificateElement : ConfigurationElement + { + private bool isReadOnly = true; + + internal void AllowConfigEdit(bool allow) + { + isReadOnly = !allow; + } + + /// + /// Allows local modification of the configuration for testing purposes + /// + /// + public override bool IsReadOnly() + { + return isReadOnly; + } + + /// + /// File name of cert stored in file. + /// + [ConfigurationProperty("fileName")] + public string FileName + { + get + { + return (string)this["fileName"]; + } + internal set + { + base["fileName"] = value; + } + } + + /// + /// Store name to search. + /// + [ConfigurationProperty("storeName")] + [ExcludeFromCodeCoverage] + public StoreName StoreName + { + get + { + return (StoreName)this["storeName"]; + } + } + + /// + /// Store location to search. + /// + [ConfigurationProperty("storeLocation")] + [ExcludeFromCodeCoverage] + public StoreLocation StoreLocation + { + get + { + return (StoreLocation)this["storeLocation"]; + } + } + + /// + /// The search term used for searching the certificate store. + /// + [ConfigurationProperty("findValue")] + [ExcludeFromCodeCoverage] + public string FindValue + { + get + { + return (string)this["findValue"]; + } + } + + /// + /// Find type, what field to search. + /// + [ConfigurationProperty("x509FindType")] + [ExcludeFromCodeCoverage] + public X509FindType X509FindType + { + get + { + return (X509FindType)this["x509FindType"]; + } + } + + /// + /// Load the certificate pointed to by this configuration. + /// + /// Certificate + [ExcludeFromCodeCoverage] + public X509Certificate2 LoadCertificate() + { + if (!string.IsNullOrEmpty(FileName)) + { + string fileName = FileName; + fileName = PathHelper.MapPath(fileName); + + return new X509Certificate2(fileName, "", X509KeyStorageFlags.MachineKeySet); + } + else + { + // A 0 store location indicates that attributes to load from store are not present + // in the config. + if (StoreLocation != 0) + { + var store = new X509Store(StoreName, StoreLocation); + store.Open(OpenFlags.ReadOnly); + try + { + var certs = store.Certificates.Find(X509FindType, FindValue, false); + + if (certs.Count != 1) + { + throw new InvalidOperationException( + string.Format(CultureInfo.InvariantCulture, + "Finding cert through {0} in {1}:{2} with value {3} matched {4} certificates. A unique match is required.", + X509FindType, StoreLocation, StoreName, FindValue, certs.Count)); + } + + return certs[0]; + } + finally + { + store.Close(); + } + } + else + { + return null; + } + } + } + } +} diff --git a/Kentor.AuthServices/Configuration/Compatibility.cs b/Sustainsys.Saml2/Configuration/Compatibility.cs similarity index 100% rename from Kentor.AuthServices/Configuration/Compatibility.cs rename to Sustainsys.Saml2/Configuration/Compatibility.cs diff --git a/Kentor.AuthServices/Configuration/CompatibilityElement.cs b/Sustainsys.Saml2/Configuration/CompatibilityElement.cs similarity index 100% rename from Kentor.AuthServices/Configuration/CompatibilityElement.cs rename to Sustainsys.Saml2/Configuration/CompatibilityElement.cs diff --git a/Kentor.AuthServices/Configuration/ConfiguredAndLoadedSigningKeysCollection.cs b/Sustainsys.Saml2/Configuration/ConfiguredAndLoadedSigningKeysCollection.cs similarity index 100% rename from Kentor.AuthServices/Configuration/ConfiguredAndLoadedSigningKeysCollection.cs rename to Sustainsys.Saml2/Configuration/ConfiguredAndLoadedSigningKeysCollection.cs diff --git a/Kentor.AuthServices/Configuration/ContactPersonElement.cs b/Sustainsys.Saml2/Configuration/ContactPersonElement.cs similarity index 100% rename from Kentor.AuthServices/Configuration/ContactPersonElement.cs rename to Sustainsys.Saml2/Configuration/ContactPersonElement.cs diff --git a/Kentor.AuthServices/Configuration/ContactPersonsCollection.cs b/Sustainsys.Saml2/Configuration/ContactPersonsCollection.cs similarity index 100% rename from Kentor.AuthServices/Configuration/ContactPersonsCollection.cs rename to Sustainsys.Saml2/Configuration/ContactPersonsCollection.cs diff --git a/Kentor.AuthServices/Configuration/EntityIdConverter.cs b/Sustainsys.Saml2/Configuration/EntityIdConverter.cs similarity index 100% rename from Kentor.AuthServices/Configuration/EntityIdConverter.cs rename to Sustainsys.Saml2/Configuration/EntityIdConverter.cs diff --git a/Kentor.AuthServices/Configuration/FederationCollection.cs b/Sustainsys.Saml2/Configuration/FederationCollection.cs similarity index 100% rename from Kentor.AuthServices/Configuration/FederationCollection.cs rename to Sustainsys.Saml2/Configuration/FederationCollection.cs diff --git a/Kentor.AuthServices/Configuration/FederationElement.cs b/Sustainsys.Saml2/Configuration/FederationElement.cs similarity index 100% rename from Kentor.AuthServices/Configuration/FederationElement.cs rename to Sustainsys.Saml2/Configuration/FederationElement.cs diff --git a/Kentor.AuthServices/Configuration/IOptions.cs b/Sustainsys.Saml2/Configuration/IOptions.cs similarity index 100% rename from Kentor.AuthServices/Configuration/IOptions.cs rename to Sustainsys.Saml2/Configuration/IOptions.cs diff --git a/Kentor.AuthServices/Configuration/IdentityProviderCollection.cs b/Sustainsys.Saml2/Configuration/IdentityProviderCollection.cs similarity index 97% rename from Kentor.AuthServices/Configuration/IdentityProviderCollection.cs rename to Sustainsys.Saml2/Configuration/IdentityProviderCollection.cs index 31f80bcc3..932d6e2b2 100644 --- a/Kentor.AuthServices/Configuration/IdentityProviderCollection.cs +++ b/Sustainsys.Saml2/Configuration/IdentityProviderCollection.cs @@ -1,64 +1,64 @@ -using System; -using System.Collections.Generic; -using System.Configuration; -using System.IdentityModel.Metadata; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Sustainsys.Saml2.Internal; - -namespace Sustainsys.Saml2.Configuration -{ - /// - /// Config collection of IdentityProviderElements. - /// - public class IdentityProviderCollection : ConfigurationElementCollection, IEnumerable - { - /// - /// Create new element of right type. - /// - /// IdentityProviderElement - protected override ConfigurationElement CreateNewElement() - { - return new IdentityProviderElement(); - } - - /// - /// Get the name of an element. - /// - /// IdentityProviderElement - /// element.Name - protected override object GetElementKey(ConfigurationElement element) - { - return ((IdentityProviderElement)element).EntityId; - } - - /// - /// Get a strongly typed enumerator. - /// - /// Strongly typed enumerator. - public new IEnumerator GetEnumerator() - { - return base.GetEnumerator().AsGeneric(); - } - - /// - /// Register the configured identity providers in the dictionary of active idps. - /// - /// Current options. - public void RegisterIdentityProviders(IOptions options) - { - if(options == null) - { - throw new ArgumentNullException(nameof(options)); - } - - foreach(var idpEntry in this) - { - var idp = new IdentityProvider(idpEntry, options.SPOptions); - - options.IdentityProviders[idp.EntityId] = idp; - } - } - } -} +using System; +using System.Collections.Generic; +using System.Configuration; +using System.IdentityModel.Metadata; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Sustainsys.Saml2.Internal; + +namespace Sustainsys.Saml2.Configuration +{ + /// + /// Config collection of IdentityProviderElements. + /// + public class IdentityProviderCollection : ConfigurationElementCollection, IEnumerable + { + /// + /// Create new element of right type. + /// + /// IdentityProviderElement + protected override ConfigurationElement CreateNewElement() + { + return new IdentityProviderElement(); + } + + /// + /// Get the name of an element. + /// + /// IdentityProviderElement + /// element.Name + protected override object GetElementKey(ConfigurationElement element) + { + return ((IdentityProviderElement)element).EntityId; + } + + /// + /// Get a strongly typed enumerator. + /// + /// Strongly typed enumerator. + public new IEnumerator GetEnumerator() + { + return base.GetEnumerator().AsGeneric(); + } + + /// + /// Register the configured identity providers in the dictionary of active idps. + /// + /// Current options. + public void RegisterIdentityProviders(IOptions options) + { + if(options == null) + { + throw new ArgumentNullException(nameof(options)); + } + + foreach(var idpEntry in this) + { + var idp = new IdentityProvider(idpEntry, options.SPOptions); + + options.IdentityProviders[idp.EntityId] = idp; + } + } + } +} diff --git a/Kentor.AuthServices/Configuration/IdentityProviderDictionary.cs b/Sustainsys.Saml2/Configuration/IdentityProviderDictionary.cs similarity index 100% rename from Kentor.AuthServices/Configuration/IdentityProviderDictionary.cs rename to Sustainsys.Saml2/Configuration/IdentityProviderDictionary.cs diff --git a/Kentor.AuthServices/Configuration/IdentityProviderElement.cs b/Sustainsys.Saml2/Configuration/IdentityProviderElement.cs similarity index 97% rename from Kentor.AuthServices/Configuration/IdentityProviderElement.cs rename to Sustainsys.Saml2/Configuration/IdentityProviderElement.cs index d3d355c03..0ef09c6b9 100644 --- a/Kentor.AuthServices/Configuration/IdentityProviderElement.cs +++ b/Sustainsys.Saml2/Configuration/IdentityProviderElement.cs @@ -1,223 +1,223 @@ -using Sustainsys.Saml2.WebSso; -using System; -using System.Configuration; -using System.Data.Odbc; -using Sustainsys.Saml2.Saml2P; - -namespace Sustainsys.Saml2.Configuration -{ - /// - /// Config element for the identity provider element. - /// - public class IdentityProviderElement : ConfigurationElement - { - private bool isReadOnly = true; - - internal void AllowConfigEdit(bool allow) - { - isReadOnly = !allow; - } - - /// - /// Allows local modification of the configuration for testing purposes - /// - /// - public override bool IsReadOnly() - { - return isReadOnly; - } - - /// - /// EntityId as presented by the idp. Used as key to configuration. - /// - [ConfigurationProperty("entityId", IsRequired = true)] - public string EntityId - { - get - { - return (string)base["entityId"]; - } - internal set - { - base["entityId"] = value; - } - } - - const string signOnUrl = nameof(signOnUrl); - /// - /// Destination url to send sign in requests to. - /// - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1726:UsePreferredTerms", MessageId = "SignOn")] - [ConfigurationProperty(signOnUrl)] - public Uri SignOnUrl - { - get - { - return (Uri)base[signOnUrl]; - } - internal set - { - base[signOnUrl] = value; - } - } - - const string logoutUrl = nameof(logoutUrl); - /// - /// Single logout url endpoint of Idp. - /// - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1726:UsePreferredTerms", MessageId = "Logout")] - [ConfigurationProperty(logoutUrl)] - public Uri LogoutUrl - { - get - { - return (Uri)base[logoutUrl]; - } - } - - /// - /// The binding to use when sending requests to the Idp. - /// - [ConfigurationProperty("binding")] - public Saml2BindingType Binding - { - get - { - return (Saml2BindingType)base["binding"]; - } - internal set - { - base["binding"] = value; - } - } - - /// - /// Certificate location for the certificate the Idp uses to sign its messages. - /// - [ConfigurationProperty("signingCertificate")] - public CertificateElement SigningCertificate - { - get - { - return (CertificateElement)base["signingCertificate"]; - } - internal set - { - base["signingCertificate"] = value; - } - } - - const string outboundSigningAlgorithm = nameof(outboundSigningAlgorithm); - /// - /// Signing algorithm for outbound messages to this Idp. Overrides the - /// main signature algorithm configured in . - /// - [ConfigurationProperty(outboundSigningAlgorithm, IsRequired = false)] - public string OutboundSigningAlgorithm - { - get - { - return (string)base[outboundSigningAlgorithm]; - } - } - - /// - /// Allow unsolicited responses. That is InResponseTo is missing in the AuthnRequest. - /// If true InResponseTo is not required. - /// If false InResponseTo is required. - /// Even though AllowUnsolicitedAuthnResponse is true the InResponseTo must be valid if existing. - /// - [ConfigurationProperty("allowUnsolicitedAuthnResponse", IsRequired = true)] - public bool AllowUnsolicitedAuthnResponse - { - get - { - return (bool)base["allowUnsolicitedAuthnResponse"]; - } - } - - /// - /// Enable automatic downloading of metadata form the well-known uri (i.e. interpret - /// the EntityID as an uri and download metadata from it). - /// - [ConfigurationProperty("loadMetadata", IsRequired = false, DefaultValue = false)] - public bool LoadMetadata - { - get - { - return (bool)base["loadMetadata"]; - } - set - { - base["loadMetadata"] = value; - } - } - - const string metadataLocation = nameof(metadataLocation); - - /// - /// Metadata location url to be used for automatic downloading of metadata. - /// - [ConfigurationProperty(metadataLocation)] - public string MetadataLocation - { - get - { - return (string)base[metadataLocation]; - } - internal set - { - base[metadataLocation] = value; - } - } - - const string artifactResolutionServices = nameof(artifactResolutionServices); - /// - /// Artifact Resolution endpoints for the identity provider. - /// - [ConfigurationProperty(artifactResolutionServices)] - [ConfigurationCollection(typeof(ArtifactResolutionServiceCollection))] - public ArtifactResolutionServiceCollection ArtifactResolutionServices - { - get - { - return (ArtifactResolutionServiceCollection)base[artifactResolutionServices]; - } - } - - const string wantAuthnRequestsSigned = nameof(wantAuthnRequestsSigned); - /// - /// Does this Idp want the AuthnRequests to be signed? - /// - [ConfigurationProperty(wantAuthnRequestsSigned, IsRequired = false, DefaultValue = false)] - public bool WantAuthnRequestsSigned - { - get - { - return (bool)base[wantAuthnRequestsSigned]; - } - } - - const string disableOutboundLogoutRequests = nameof(disableOutboundLogoutRequests); - - /// - /// Disable outbound logout requests to this idp, even though - /// Saml2 is configured for single logout and the idp supports - /// it. This setting might be usable when adding SLO to an existing - /// setup, to ensure that everyone is ready for SLO before activating. - /// - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1726:UsePreferredTerms", MessageId = "Logout")] - [ConfigurationProperty(disableOutboundLogoutRequests, IsRequired = false, DefaultValue = false)] - public bool DisableOutboundLogoutRequests - { - get - { - return (bool)base[disableOutboundLogoutRequests]; - } - set - { - base[disableOutboundLogoutRequests] = value; - } - } - } -} +using Sustainsys.Saml2.WebSso; +using System; +using System.Configuration; +using System.Data.Odbc; +using Sustainsys.Saml2.Saml2P; + +namespace Sustainsys.Saml2.Configuration +{ + /// + /// Config element for the identity provider element. + /// + public class IdentityProviderElement : ConfigurationElement + { + private bool isReadOnly = true; + + internal void AllowConfigEdit(bool allow) + { + isReadOnly = !allow; + } + + /// + /// Allows local modification of the configuration for testing purposes + /// + /// + public override bool IsReadOnly() + { + return isReadOnly; + } + + /// + /// EntityId as presented by the idp. Used as key to configuration. + /// + [ConfigurationProperty("entityId", IsRequired = true)] + public string EntityId + { + get + { + return (string)base["entityId"]; + } + internal set + { + base["entityId"] = value; + } + } + + const string signOnUrl = nameof(signOnUrl); + /// + /// Destination url to send sign in requests to. + /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1726:UsePreferredTerms", MessageId = "SignOn")] + [ConfigurationProperty(signOnUrl)] + public Uri SignOnUrl + { + get + { + return (Uri)base[signOnUrl]; + } + internal set + { + base[signOnUrl] = value; + } + } + + const string logoutUrl = nameof(logoutUrl); + /// + /// Single logout url endpoint of Idp. + /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1726:UsePreferredTerms", MessageId = "Logout")] + [ConfigurationProperty(logoutUrl)] + public Uri LogoutUrl + { + get + { + return (Uri)base[logoutUrl]; + } + } + + /// + /// The binding to use when sending requests to the Idp. + /// + [ConfigurationProperty("binding")] + public Saml2BindingType Binding + { + get + { + return (Saml2BindingType)base["binding"]; + } + internal set + { + base["binding"] = value; + } + } + + /// + /// Certificate location for the certificate the Idp uses to sign its messages. + /// + [ConfigurationProperty("signingCertificate")] + public CertificateElement SigningCertificate + { + get + { + return (CertificateElement)base["signingCertificate"]; + } + internal set + { + base["signingCertificate"] = value; + } + } + + const string outboundSigningAlgorithm = nameof(outboundSigningAlgorithm); + /// + /// Signing algorithm for outbound messages to this Idp. Overrides the + /// main signature algorithm configured in . + /// + [ConfigurationProperty(outboundSigningAlgorithm, IsRequired = false)] + public string OutboundSigningAlgorithm + { + get + { + return (string)base[outboundSigningAlgorithm]; + } + } + + /// + /// Allow unsolicited responses. That is InResponseTo is missing in the AuthnRequest. + /// If true InResponseTo is not required. + /// If false InResponseTo is required. + /// Even though AllowUnsolicitedAuthnResponse is true the InResponseTo must be valid if existing. + /// + [ConfigurationProperty("allowUnsolicitedAuthnResponse", IsRequired = true)] + public bool AllowUnsolicitedAuthnResponse + { + get + { + return (bool)base["allowUnsolicitedAuthnResponse"]; + } + } + + /// + /// Enable automatic downloading of metadata form the well-known uri (i.e. interpret + /// the EntityID as an uri and download metadata from it). + /// + [ConfigurationProperty("loadMetadata", IsRequired = false, DefaultValue = false)] + public bool LoadMetadata + { + get + { + return (bool)base["loadMetadata"]; + } + set + { + base["loadMetadata"] = value; + } + } + + const string metadataLocation = nameof(metadataLocation); + + /// + /// Metadata location url to be used for automatic downloading of metadata. + /// + [ConfigurationProperty(metadataLocation)] + public string MetadataLocation + { + get + { + return (string)base[metadataLocation]; + } + internal set + { + base[metadataLocation] = value; + } + } + + const string artifactResolutionServices = nameof(artifactResolutionServices); + /// + /// Artifact Resolution endpoints for the identity provider. + /// + [ConfigurationProperty(artifactResolutionServices)] + [ConfigurationCollection(typeof(ArtifactResolutionServiceCollection))] + public ArtifactResolutionServiceCollection ArtifactResolutionServices + { + get + { + return (ArtifactResolutionServiceCollection)base[artifactResolutionServices]; + } + } + + const string wantAuthnRequestsSigned = nameof(wantAuthnRequestsSigned); + /// + /// Does this Idp want the AuthnRequests to be signed? + /// + [ConfigurationProperty(wantAuthnRequestsSigned, IsRequired = false, DefaultValue = false)] + public bool WantAuthnRequestsSigned + { + get + { + return (bool)base[wantAuthnRequestsSigned]; + } + } + + const string disableOutboundLogoutRequests = nameof(disableOutboundLogoutRequests); + + /// + /// Disable outbound logout requests to this idp, even though + /// Saml2 is configured for single logout and the idp supports + /// it. This setting might be usable when adding SLO to an existing + /// setup, to ensure that everyone is ready for SLO before activating. + /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1726:UsePreferredTerms", MessageId = "Logout")] + [ConfigurationProperty(disableOutboundLogoutRequests, IsRequired = false, DefaultValue = false)] + public bool DisableOutboundLogoutRequests + { + get + { + return (bool)base[disableOutboundLogoutRequests]; + } + set + { + base[disableOutboundLogoutRequests] = value; + } + } + } +} diff --git a/Kentor.AuthServices/Configuration/MetadataElement.cs b/Sustainsys.Saml2/Configuration/MetadataElement.cs similarity index 100% rename from Kentor.AuthServices/Configuration/MetadataElement.cs rename to Sustainsys.Saml2/Configuration/MetadataElement.cs diff --git a/Kentor.AuthServices/Configuration/NameIdPolicyElement.cs b/Sustainsys.Saml2/Configuration/NameIdPolicyElement.cs similarity index 100% rename from Kentor.AuthServices/Configuration/NameIdPolicyElement.cs rename to Sustainsys.Saml2/Configuration/NameIdPolicyElement.cs diff --git a/Kentor.AuthServices/Configuration/Options.cs b/Sustainsys.Saml2/Configuration/Options.cs similarity index 100% rename from Kentor.AuthServices/Configuration/Options.cs rename to Sustainsys.Saml2/Configuration/Options.cs diff --git a/Kentor.AuthServices/Configuration/OrganizationElement.cs b/Sustainsys.Saml2/Configuration/OrganizationElement.cs similarity index 100% rename from Kentor.AuthServices/Configuration/OrganizationElement.cs rename to Sustainsys.Saml2/Configuration/OrganizationElement.cs diff --git a/Kentor.AuthServices/Configuration/RequestedAttributeElement.cs b/Sustainsys.Saml2/Configuration/RequestedAttributeElement.cs similarity index 100% rename from Kentor.AuthServices/Configuration/RequestedAttributeElement.cs rename to Sustainsys.Saml2/Configuration/RequestedAttributeElement.cs diff --git a/Kentor.AuthServices/Configuration/RequestedAttributesCollection.cs b/Sustainsys.Saml2/Configuration/RequestedAttributesCollection.cs similarity index 100% rename from Kentor.AuthServices/Configuration/RequestedAttributesCollection.cs rename to Sustainsys.Saml2/Configuration/RequestedAttributesCollection.cs diff --git a/Kentor.AuthServices/Configuration/RequestedAuthnContextElement.cs b/Sustainsys.Saml2/Configuration/RequestedAuthnContextElement.cs similarity index 100% rename from Kentor.AuthServices/Configuration/RequestedAuthnContextElement.cs rename to Sustainsys.Saml2/Configuration/RequestedAuthnContextElement.cs diff --git a/Kentor.AuthServices/Configuration/SPOptions.cs b/Sustainsys.Saml2/Configuration/SPOptions.cs similarity index 100% rename from Kentor.AuthServices/Configuration/SPOptions.cs rename to Sustainsys.Saml2/Configuration/SPOptions.cs diff --git a/Kentor.AuthServices/Configuration/KentorAuthServicesNotifications.cs b/Sustainsys.Saml2/Configuration/Saml2Notifications.cs similarity index 100% rename from Kentor.AuthServices/Configuration/KentorAuthServicesNotifications.cs rename to Sustainsys.Saml2/Configuration/Saml2Notifications.cs diff --git a/Kentor.AuthServices/Configuration/ServiceCertificateCollection.cs b/Sustainsys.Saml2/Configuration/ServiceCertificateCollection.cs similarity index 100% rename from Kentor.AuthServices/Configuration/ServiceCertificateCollection.cs rename to Sustainsys.Saml2/Configuration/ServiceCertificateCollection.cs diff --git a/Kentor.AuthServices/Configuration/ServiceCertificateElement.cs b/Sustainsys.Saml2/Configuration/ServiceCertificateElement.cs similarity index 100% rename from Kentor.AuthServices/Configuration/ServiceCertificateElement.cs rename to Sustainsys.Saml2/Configuration/ServiceCertificateElement.cs diff --git a/Kentor.AuthServices/Configuration/ServiceCertificateElementCollection.cs b/Sustainsys.Saml2/Configuration/ServiceCertificateElementCollection.cs similarity index 100% rename from Kentor.AuthServices/Configuration/ServiceCertificateElementCollection.cs rename to Sustainsys.Saml2/Configuration/ServiceCertificateElementCollection.cs diff --git a/Kentor.AuthServices/Configuration/SigningBehavior.cs b/Sustainsys.Saml2/Configuration/SigningBehavior.cs similarity index 100% rename from Kentor.AuthServices/Configuration/SigningBehavior.cs rename to Sustainsys.Saml2/Configuration/SigningBehavior.cs diff --git a/Kentor.AuthServices/Configuration/KentorAuthServicesSection.cs b/Sustainsys.Saml2/Configuration/SustainsysSaml2Section.cs similarity index 97% rename from Kentor.AuthServices/Configuration/KentorAuthServicesSection.cs rename to Sustainsys.Saml2/Configuration/SustainsysSaml2Section.cs index 749b4f1c1..060de3254 100644 --- a/Kentor.AuthServices/Configuration/KentorAuthServicesSection.cs +++ b/Sustainsys.Saml2/Configuration/SustainsysSaml2Section.cs @@ -1,381 +1,381 @@ -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Configuration; -using System.Globalization; -using System.IdentityModel.Metadata; -using System.Linq; -using Sustainsys.Saml2.Internal; -using Sustainsys.Saml2.Metadata; -using Sustainsys.Saml2.Saml2P; -using System.Diagnostics.CodeAnalysis; -using System.Collections.ObjectModel; - -namespace Sustainsys.Saml2.Configuration -{ - /// - /// Config section for the module. - /// - public class SustainsysSaml2Section : ConfigurationSection - { - private static readonly SustainsysSaml2Section current = - (SustainsysSaml2Section)ConfigurationManager.GetSection("Sustainsys.Saml2"); - - internal bool AllowChange { get; set; } - - /// - /// Used for testing, always returns true in production. - /// - /// Returns true (unless during tests) - public override bool IsReadOnly() - { - return !AllowChange; - } - - /// - /// Current config as read from app/web.config. - /// - public static SustainsysSaml2Section Current - { - get - { - return current; - } - } - - /// - /// EntityId - The identity of the ServiceProvider to use when sending requests to Idp - /// and presenting the SP in metadata. - /// - [TypeConverter(typeof(EntityIdConverter))] - [ConfigurationProperty("entityId")] - public EntityId EntityId - { - get - { - return (EntityId)base["entityId"]; - } - } - - /// - /// The Url to redirect back to after successfull authentication. - /// - [ConfigurationProperty("returnUrl")] - public Uri ReturnUrl - { - get - { - return (Uri)base["returnUrl"]; - } - } - - /// - /// By default, the service provider uses the host, protocol, and port - /// from the HTTP request when creating links. This might not be - /// accurate in reverse proxy or load-balancing situations. You can - /// override the origin used for link generation using this property. - /// - [ConfigurationProperty("publicOrigin", IsRequired = false)] - public Uri PublicOrigin - { - get - { - return (Uri)base["publicOrigin"]; - } - } - - /// - /// Set of identity providers known to the service provider. - /// - [ConfigurationProperty("identityProviders")] - [ConfigurationCollection(typeof(IdentityProviderCollection))] - public IdentityProviderCollection IdentityProviders - { - get - { - return (IdentityProviderCollection)base["identityProviders"]; - } - } - - /// - /// Set of federations. The service provider will trust all the idps in these federations. - /// - [ConfigurationProperty("federations")] - [ConfigurationCollection(typeof(FederationCollection))] - public FederationCollection Federations - { - get - { - return (FederationCollection)base["federations"]; - } - } - - const string discoveryServiceUrl = "discoveryServiceUrl"; - /// - /// Url to discovery service to use if no idp is specified in the sign in call. - /// - [ConfigurationProperty(discoveryServiceUrl, IsRequired = false)] - public Uri DiscoveryServiceUrl - { - get - { - return (Uri)base[discoveryServiceUrl]; - } - } - - const string modulePath = "modulePath"; - /// - /// Application root relative path for Saml2 endpoints. The - /// default is "Saml2". - /// - [ConfigurationProperty(modulePath, IsRequired = false, DefaultValue = "/Saml2")] - [RegexStringValidator("/.*")] - public string ModulePath - { - get - { - return (string)base[modulePath]; - } - } - - const string nameIdPolicy = nameof(nameIdPolicy); - /// - /// NamedId policy element. - /// - [ConfigurationProperty(nameIdPolicy)] - public NameIdPolicyElement NameIdPolicyElement - { - get - { - return (NameIdPolicyElement)base[nameIdPolicy]; - } - } - - const string requestedAuthnContext = nameof(requestedAuthnContext); - /// - /// RequestedAuthnContext config. - /// - [ConfigurationProperty(requestedAuthnContext)] - public RequestedAuthnContextElement RequestedAuthnContext - { - get - { - return (RequestedAuthnContextElement)base[requestedAuthnContext]; - } - } - - // Reset by the tests. - internal Organization organization = null; - - /// - /// Metadata describing the organization responsible for the entity. - /// - public Organization Organization - { - get - { - // If the entire organization element is missing in the config file, - // Metadata.Organization will still be instantiated, but the Url will be null. - if (organization == null && Metadata.Organization.Url != null) - { - var culture = CultureInfo.InvariantCulture; - if (!string.IsNullOrEmpty(Metadata.Organization.Language)) - { - culture = CultureInfo.GetCultureInfo(Metadata.Organization.Language); - } - - var org = new Organization(); - org.Names.Add(new LocalizedName(Metadata.Organization.Name, culture)); - org.DisplayNames.Add(new LocalizedName(Metadata.Organization.DisplayName, culture)); - org.Urls.Add(new LocalizedUri(Metadata.Organization.Url, culture)); - - organization = org; - } - - return organization; - } - } - - const string metadata = "metadata"; - /// - /// Metadata of the service provider. - /// - [ConfigurationProperty(metadata)] - public MetadataElement Metadata - { - get - { - return (MetadataElement)base[metadata]; - } - internal set - { - base[metadata] = value; - } - } - - IEnumerable contacts; - - /// - /// Contacts for the SAML2 entity. - /// - public IEnumerable Contacts - { - get - { - if (contacts == null) - { - // Won't assign directly to avoid a race condition. - var temp = new List(); - - foreach (var configPerson in Metadata.Contacts) - { - var contactPerson = new ContactPerson(configPerson.ContactType) - { - Company = configPerson.Company.NullIfEmpty(), - GivenName = configPerson.GivenName.NullIfEmpty(), - Surname = configPerson.Surname.NullIfEmpty(), - }; - - if (!string.IsNullOrEmpty(configPerson.PhoneNumber)) - { - contactPerson.TelephoneNumbers.Add(configPerson.PhoneNumber); - } - - if (!string.IsNullOrEmpty(configPerson.Email)) - { - contactPerson.EmailAddresses.Add(configPerson.Email); - } - - temp.Add(contactPerson); - } - - contacts = temp; - } - - return contacts; - } - } - - /// - /// Attribute consuming services. - /// - public IEnumerable AttributeConsumingServices - { - get - { - if (Metadata.RequestedAttributes.Any()) - { - var acs = new AttributeConsumingService("SP") - { - IsDefault = true - }; - - foreach (var confAttribute in Metadata.RequestedAttributes) - { - acs.RequestedAttributes.Add(new RequestedAttribute(confAttribute.Name) - { - FriendlyName = confAttribute.FriendlyName, - IsRequired = confAttribute.IsRequired, - NameFormat = confAttribute.NameFormat - }); - } - - yield return acs; - } - } - } - - const string serviceCertificates = nameof(serviceCertificates); - /// - /// Certificates used by the service provider for signing and/or decryption. - /// - [ConfigurationProperty(serviceCertificates)] - [ConfigurationCollection(typeof(ServiceCertificateElementCollection))] - public ServiceCertificateElementCollection ServiceCertificates - { - get - { - return (ServiceCertificateElementCollection)base[serviceCertificates]; - } - } - - const string authenticateRequestSigningBehavior = nameof(authenticateRequestSigningBehavior); - /// - /// Signing behavior for created AuthnRequests. - /// - [ConfigurationProperty(authenticateRequestSigningBehavior)] - public SigningBehavior AuthenticateRequestSigningBehavior - { - get - { - return (SigningBehavior)base[authenticateRequestSigningBehavior]; - } - internal set - { - base[authenticateRequestSigningBehavior] = value; - } - } - - const string outboundSigningAlgorithm = nameof(outboundSigningAlgorithm); - /// - /// Signing algorithm for metadata and outbound messages. Can be - /// overriden for each . - /// - [ConfigurationProperty(outboundSigningAlgorithm, IsRequired = false)] - public string OutboundSigningAlgorithm - { - get - { - return (string)base[outboundSigningAlgorithm]; - } - } - - const string minIncomingSigningAlgorithm = nameof(minIncomingSigningAlgorithm); - /// - /// Weakest accepted signing algorithm for inbound messages. - /// - [ConfigurationProperty(minIncomingSigningAlgorithm, IsRequired = false)] - public string MinIncomingSigningAlgorithm - { - get - { - return (string)base[minIncomingSigningAlgorithm]; - } - } - - const string validateCertificates = nameof(validateCertificates); - /// - /// Validate certificates when validating signatures? Normally not a - /// good idea as SAML2 deployments typically exchange certificates - /// directly and instead of relying on the public certificate - /// infrastructure. - /// - [ConfigurationProperty(validateCertificates, IsRequired = false)] - public bool ValidateCertificates - { - get - { - return (bool)base[validateCertificates]; - } - internal set - { - base[validateCertificates] = value; - } - } - - const string compatibility = nameof(compatibility); - - /// - /// Compatibility settings. Can be used to make Saml2 accept - /// certain non-standard behaviour. - /// - [ConfigurationProperty(compatibility)] - public CompatibilityElement Compatibility - { - get - { - return (CompatibilityElement)base[compatibility]; - } - } - } -} +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Configuration; +using System.Globalization; +using System.IdentityModel.Metadata; +using System.Linq; +using Sustainsys.Saml2.Internal; +using Sustainsys.Saml2.Metadata; +using Sustainsys.Saml2.Saml2P; +using System.Diagnostics.CodeAnalysis; +using System.Collections.ObjectModel; + +namespace Sustainsys.Saml2.Configuration +{ + /// + /// Config section for the module. + /// + public class SustainsysSaml2Section : ConfigurationSection + { + private static readonly SustainsysSaml2Section current = + (SustainsysSaml2Section)ConfigurationManager.GetSection("Sustainsys.Saml2"); + + internal bool AllowChange { get; set; } + + /// + /// Used for testing, always returns true in production. + /// + /// Returns true (unless during tests) + public override bool IsReadOnly() + { + return !AllowChange; + } + + /// + /// Current config as read from app/web.config. + /// + public static SustainsysSaml2Section Current + { + get + { + return current; + } + } + + /// + /// EntityId - The identity of the ServiceProvider to use when sending requests to Idp + /// and presenting the SP in metadata. + /// + [TypeConverter(typeof(EntityIdConverter))] + [ConfigurationProperty("entityId")] + public EntityId EntityId + { + get + { + return (EntityId)base["entityId"]; + } + } + + /// + /// The Url to redirect back to after successfull authentication. + /// + [ConfigurationProperty("returnUrl")] + public Uri ReturnUrl + { + get + { + return (Uri)base["returnUrl"]; + } + } + + /// + /// By default, the service provider uses the host, protocol, and port + /// from the HTTP request when creating links. This might not be + /// accurate in reverse proxy or load-balancing situations. You can + /// override the origin used for link generation using this property. + /// + [ConfigurationProperty("publicOrigin", IsRequired = false)] + public Uri PublicOrigin + { + get + { + return (Uri)base["publicOrigin"]; + } + } + + /// + /// Set of identity providers known to the service provider. + /// + [ConfigurationProperty("identityProviders")] + [ConfigurationCollection(typeof(IdentityProviderCollection))] + public IdentityProviderCollection IdentityProviders + { + get + { + return (IdentityProviderCollection)base["identityProviders"]; + } + } + + /// + /// Set of federations. The service provider will trust all the idps in these federations. + /// + [ConfigurationProperty("federations")] + [ConfigurationCollection(typeof(FederationCollection))] + public FederationCollection Federations + { + get + { + return (FederationCollection)base["federations"]; + } + } + + const string discoveryServiceUrl = "discoveryServiceUrl"; + /// + /// Url to discovery service to use if no idp is specified in the sign in call. + /// + [ConfigurationProperty(discoveryServiceUrl, IsRequired = false)] + public Uri DiscoveryServiceUrl + { + get + { + return (Uri)base[discoveryServiceUrl]; + } + } + + const string modulePath = "modulePath"; + /// + /// Application root relative path for Saml2 endpoints. The + /// default is "Saml2". + /// + [ConfigurationProperty(modulePath, IsRequired = false, DefaultValue = "/Saml2")] + [RegexStringValidator("/.*")] + public string ModulePath + { + get + { + return (string)base[modulePath]; + } + } + + const string nameIdPolicy = nameof(nameIdPolicy); + /// + /// NamedId policy element. + /// + [ConfigurationProperty(nameIdPolicy)] + public NameIdPolicyElement NameIdPolicyElement + { + get + { + return (NameIdPolicyElement)base[nameIdPolicy]; + } + } + + const string requestedAuthnContext = nameof(requestedAuthnContext); + /// + /// RequestedAuthnContext config. + /// + [ConfigurationProperty(requestedAuthnContext)] + public RequestedAuthnContextElement RequestedAuthnContext + { + get + { + return (RequestedAuthnContextElement)base[requestedAuthnContext]; + } + } + + // Reset by the tests. + internal Organization organization = null; + + /// + /// Metadata describing the organization responsible for the entity. + /// + public Organization Organization + { + get + { + // If the entire organization element is missing in the config file, + // Metadata.Organization will still be instantiated, but the Url will be null. + if (organization == null && Metadata.Organization.Url != null) + { + var culture = CultureInfo.InvariantCulture; + if (!string.IsNullOrEmpty(Metadata.Organization.Language)) + { + culture = CultureInfo.GetCultureInfo(Metadata.Organization.Language); + } + + var org = new Organization(); + org.Names.Add(new LocalizedName(Metadata.Organization.Name, culture)); + org.DisplayNames.Add(new LocalizedName(Metadata.Organization.DisplayName, culture)); + org.Urls.Add(new LocalizedUri(Metadata.Organization.Url, culture)); + + organization = org; + } + + return organization; + } + } + + const string metadata = "metadata"; + /// + /// Metadata of the service provider. + /// + [ConfigurationProperty(metadata)] + public MetadataElement Metadata + { + get + { + return (MetadataElement)base[metadata]; + } + internal set + { + base[metadata] = value; + } + } + + IEnumerable contacts; + + /// + /// Contacts for the SAML2 entity. + /// + public IEnumerable Contacts + { + get + { + if (contacts == null) + { + // Won't assign directly to avoid a race condition. + var temp = new List(); + + foreach (var configPerson in Metadata.Contacts) + { + var contactPerson = new ContactPerson(configPerson.ContactType) + { + Company = configPerson.Company.NullIfEmpty(), + GivenName = configPerson.GivenName.NullIfEmpty(), + Surname = configPerson.Surname.NullIfEmpty(), + }; + + if (!string.IsNullOrEmpty(configPerson.PhoneNumber)) + { + contactPerson.TelephoneNumbers.Add(configPerson.PhoneNumber); + } + + if (!string.IsNullOrEmpty(configPerson.Email)) + { + contactPerson.EmailAddresses.Add(configPerson.Email); + } + + temp.Add(contactPerson); + } + + contacts = temp; + } + + return contacts; + } + } + + /// + /// Attribute consuming services. + /// + public IEnumerable AttributeConsumingServices + { + get + { + if (Metadata.RequestedAttributes.Any()) + { + var acs = new AttributeConsumingService("SP") + { + IsDefault = true + }; + + foreach (var confAttribute in Metadata.RequestedAttributes) + { + acs.RequestedAttributes.Add(new RequestedAttribute(confAttribute.Name) + { + FriendlyName = confAttribute.FriendlyName, + IsRequired = confAttribute.IsRequired, + NameFormat = confAttribute.NameFormat + }); + } + + yield return acs; + } + } + } + + const string serviceCertificates = nameof(serviceCertificates); + /// + /// Certificates used by the service provider for signing and/or decryption. + /// + [ConfigurationProperty(serviceCertificates)] + [ConfigurationCollection(typeof(ServiceCertificateElementCollection))] + public ServiceCertificateElementCollection ServiceCertificates + { + get + { + return (ServiceCertificateElementCollection)base[serviceCertificates]; + } + } + + const string authenticateRequestSigningBehavior = nameof(authenticateRequestSigningBehavior); + /// + /// Signing behavior for created AuthnRequests. + /// + [ConfigurationProperty(authenticateRequestSigningBehavior)] + public SigningBehavior AuthenticateRequestSigningBehavior + { + get + { + return (SigningBehavior)base[authenticateRequestSigningBehavior]; + } + internal set + { + base[authenticateRequestSigningBehavior] = value; + } + } + + const string outboundSigningAlgorithm = nameof(outboundSigningAlgorithm); + /// + /// Signing algorithm for metadata and outbound messages. Can be + /// overriden for each . + /// + [ConfigurationProperty(outboundSigningAlgorithm, IsRequired = false)] + public string OutboundSigningAlgorithm + { + get + { + return (string)base[outboundSigningAlgorithm]; + } + } + + const string minIncomingSigningAlgorithm = nameof(minIncomingSigningAlgorithm); + /// + /// Weakest accepted signing algorithm for inbound messages. + /// + [ConfigurationProperty(minIncomingSigningAlgorithm, IsRequired = false)] + public string MinIncomingSigningAlgorithm + { + get + { + return (string)base[minIncomingSigningAlgorithm]; + } + } + + const string validateCertificates = nameof(validateCertificates); + /// + /// Validate certificates when validating signatures? Normally not a + /// good idea as SAML2 deployments typically exchange certificates + /// directly and instead of relying on the public certificate + /// infrastructure. + /// + [ConfigurationProperty(validateCertificates, IsRequired = false)] + public bool ValidateCertificates + { + get + { + return (bool)base[validateCertificates]; + } + internal set + { + base[validateCertificates] = value; + } + } + + const string compatibility = nameof(compatibility); + + /// + /// Compatibility settings. Can be used to make Saml2 accept + /// certain non-standard behaviour. + /// + [ConfigurationProperty(compatibility)] + public CompatibilityElement Compatibility + { + get + { + return (CompatibilityElement)base[compatibility]; + } + } + } +} diff --git a/Kentor.AuthServices/DateTimeExtensions.cs b/Sustainsys.Saml2/DateTimeExtensions.cs similarity index 100% rename from Kentor.AuthServices/DateTimeExtensions.cs rename to Sustainsys.Saml2/DateTimeExtensions.cs diff --git a/Kentor.AuthServices/Exceptions/BadFormatSamlResponseException.cs b/Sustainsys.Saml2/Exceptions/BadFormatSamlResponseException.cs similarity index 100% rename from Kentor.AuthServices/Exceptions/BadFormatSamlResponseException.cs rename to Sustainsys.Saml2/Exceptions/BadFormatSamlResponseException.cs diff --git a/Kentor.AuthServices/Exceptions/InvalidSignatureException.cs b/Sustainsys.Saml2/Exceptions/InvalidSignatureException.cs similarity index 100% rename from Kentor.AuthServices/Exceptions/InvalidSignatureException.cs rename to Sustainsys.Saml2/Exceptions/InvalidSignatureException.cs diff --git a/Kentor.AuthServices/Exceptions/NoSamlResponseFoundException.cs b/Sustainsys.Saml2/Exceptions/NoSamlResponseFoundException.cs similarity index 100% rename from Kentor.AuthServices/Exceptions/NoSamlResponseFoundException.cs rename to Sustainsys.Saml2/Exceptions/NoSamlResponseFoundException.cs diff --git a/Kentor.AuthServices/Exceptions/AuthServicesException.cs b/Sustainsys.Saml2/Exceptions/Saml2Exception.cs similarity index 100% rename from Kentor.AuthServices/Exceptions/AuthServicesException.cs rename to Sustainsys.Saml2/Exceptions/Saml2Exception.cs diff --git a/Kentor.AuthServices/Exceptions/Saml2ResponseFailedValidationException.cs b/Sustainsys.Saml2/Exceptions/Saml2ResponseFailedValidationException.cs similarity index 100% rename from Kentor.AuthServices/Exceptions/Saml2ResponseFailedValidationException.cs rename to Sustainsys.Saml2/Exceptions/Saml2ResponseFailedValidationException.cs diff --git a/Kentor.AuthServices/Exceptions/UnexpectedInResponseToException.cs b/Sustainsys.Saml2/Exceptions/UnexpectedInResponseToException.cs similarity index 100% rename from Kentor.AuthServices/Exceptions/UnexpectedInResponseToException.cs rename to Sustainsys.Saml2/Exceptions/UnexpectedInResponseToException.cs diff --git a/Kentor.AuthServices/Exceptions/UnsuccessfulSAMLOperationException.cs b/Sustainsys.Saml2/Exceptions/UnsuccessfulSAMLOperationException.cs similarity index 100% rename from Kentor.AuthServices/Exceptions/UnsuccessfulSAMLOperationException.cs rename to Sustainsys.Saml2/Exceptions/UnsuccessfulSAMLOperationException.cs diff --git a/Kentor.AuthServices/Federation.cs b/Sustainsys.Saml2/Federation.cs similarity index 100% rename from Kentor.AuthServices/Federation.cs rename to Sustainsys.Saml2/Federation.cs diff --git a/Kentor.AuthServices/ICachedMetadata.cs b/Sustainsys.Saml2/ICachedMetadata.cs similarity index 100% rename from Kentor.AuthServices/ICachedMetadata.cs rename to Sustainsys.Saml2/ICachedMetadata.cs diff --git a/Kentor.AuthServices/ILoggerAdapter.cs b/Sustainsys.Saml2/ILoggerAdapter.cs similarity index 100% rename from Kentor.AuthServices/ILoggerAdapter.cs rename to Sustainsys.Saml2/ILoggerAdapter.cs diff --git a/Kentor.AuthServices/IdentityProvider.cs b/Sustainsys.Saml2/IdentityProvider.cs similarity index 97% rename from Kentor.AuthServices/IdentityProvider.cs rename to Sustainsys.Saml2/IdentityProvider.cs index 669de3680..b6685f799 100644 --- a/Kentor.AuthServices/IdentityProvider.cs +++ b/Sustainsys.Saml2/IdentityProvider.cs @@ -1,562 +1,562 @@ -using System.Collections.Generic; -using Sustainsys.Saml2.Configuration; -using System; -using System.Configuration; -using System.Globalization; -using System.IdentityModel.Metadata; -using System.IdentityModel.Tokens; -using System.Linq; -using System.Security.Cryptography; -using System.Security.Cryptography.Xml; -using Sustainsys.Saml2.Internal; -using Sustainsys.Saml2.Metadata; -using Sustainsys.Saml2.Saml2P; -using Sustainsys.Saml2.WebSso; -using System.Threading.Tasks; -using System.Net; -using System.Collections.Concurrent; -using System.Security.Claims; -using System.Diagnostics.CodeAnalysis; - -namespace Sustainsys.Saml2 -{ - /// - /// Represents a known identity provider that this service provider can communicate with. - /// - public class IdentityProvider - { - /// - /// Ctor - /// - /// Entity id of the identityprovider. - /// Service provider options to use when - /// creating AuthnRequests for this Idp. - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "sp")] - public IdentityProvider(EntityId entityId, SPOptions spOptions) - { - if (spOptions == null) - { - throw new ArgumentNullException(nameof(spOptions)); - } - - EntityId = entityId; - this.spOptions = spOptions; - OutboundSigningAlgorithm = spOptions.OutboundSigningAlgorithm; - } - - readonly SPOptions spOptions; - - internal IdentityProvider(IdentityProviderElement config, SPOptions spOptions) - { - singleSignOnServiceUrl = config.SignOnUrl; - SingleLogoutServiceUrl = config.LogoutUrl; - EntityId = new EntityId(config.EntityId); - binding = config.Binding; - AllowUnsolicitedAuthnResponse = config.AllowUnsolicitedAuthnResponse; - metadataLocation = string.IsNullOrEmpty(config.MetadataLocation) - ? null : config.MetadataLocation; - WantAuthnRequestsSigned = config.WantAuthnRequestsSigned; - DisableOutboundLogoutRequests = config.DisableOutboundLogoutRequests; - - var certificate = config.SigningCertificate.LoadCertificate(); - if (certificate != null) - { - signingKeys.AddConfiguredKey( - new X509RawDataKeyIdentifierClause(certificate)); - } - - OutboundSigningAlgorithm = string.IsNullOrEmpty(config.OutboundSigningAlgorithm) ? - spOptions.OutboundSigningAlgorithm : - XmlHelpers.GetFullSigningAlgorithmName(config.OutboundSigningAlgorithm); - - foreach (var ars in config.ArtifactResolutionServices) - { - ArtifactResolutionServiceUrls[ars.Index] = ars.Location; - } - - // If configured to load metadata, this will immediately do the load. - this.spOptions = spOptions; - LoadMetadata = config.LoadMetadata || !string.IsNullOrEmpty(config.MetadataLocation); - - // Validate if values are only from config. If metadata is loaded, validation - // is done on metadata load. - if (!LoadMetadata) - { - Validate(); - } - } - - private void Validate() - { - if (Binding == 0) - { - throw new ConfigurationErrorsException("Missing binding configuration on Idp " + EntityId.Id + "."); - } - - if (!SigningKeys.Any()) - { - throw new ConfigurationErrorsException("Missing signing certificate configuration on Idp " + EntityId.Id + "."); - } - - if (SingleSignOnServiceUrl == null) - { - throw new ConfigurationErrorsException("Missing assertion consumer service url configuration on Idp " + EntityId.Id + "."); - } - } - - private bool loadMetadata; - - /// - /// Should this idp load metadata? The metadata is loaded immediately - /// when the property is set to true, so the - /// must be correct before settingLoadMetadata to true. - public bool LoadMetadata - { - get - { - return loadMetadata; - } - set - { - loadMetadata = value; - try - { - DoLoadMetadata(); - Validate(); - } - catch (WebException) - { - // Ignore if metadata load failed, an automatic - // retry has been scheduled. - } - } - } - - private Saml2BindingType binding; - - /// - /// The binding used when sending AuthnRequests to the identity provider. - /// - public Saml2BindingType Binding - { - get - { - ReloadMetadataIfRequired(); - return binding; - } - set - { - binding = value; - } - } - - private Uri singleSignOnServiceUrl; - - /// - /// The Url of the single sign on service. This is where the browser is redirected or - /// where the post data is sent to when sending an AuthnRequest to the idp. - /// - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1726:UsePreferredTerms", MessageId = "SignOn")] - public Uri SingleSignOnServiceUrl - { - get - { - ReloadMetadataIfRequired(); - return singleSignOnServiceUrl; - } - set - { - singleSignOnServiceUrl = value; - } - } - - private IDictionary artifactResolutionServiceUrls - = new ConcurrentDictionary(); - - /// - /// Artifact resolution endpoints on the idp. - /// - public IDictionary ArtifactResolutionServiceUrls - { - get - { - ReloadMetadataIfRequired(); - return artifactResolutionServiceUrls; - } - } - - - Uri singleLogoutServiceUrl; - /// - /// The Url of the single sign out service. This is where the browser - /// is redirected or where the post data is sent to when sending a - /// LogoutRequest to the idp. - /// - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1726:UsePreferredTerms", MessageId = "Logout")] - public Uri SingleLogoutServiceUrl - { - get - { - ReloadMetadataIfRequired(); - return singleLogoutServiceUrl; - } - set - { - singleLogoutServiceUrl = value; - } - } - - Uri singleLogoutServiceResponseUrl; - /// - /// The Url to send single logout responses to. Defaults to - /// SingleLogoutServiceUrl. - /// - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1726:UsePreferredTerms", MessageId = "Logout")] - public Uri SingleLogoutServiceResponseUrl - { - get - { - ReloadMetadataIfRequired(); - return singleLogoutServiceResponseUrl ?? SingleLogoutServiceUrl; - } - set - { - singleLogoutServiceResponseUrl = value; - } - } - - private Saml2BindingType singleLogoutServiceBinding; - /// - /// Binding for the Single logout service. If not set, returns the - /// same as the main binding (used for AuthnRequests) - /// - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1726:UsePreferredTerms", MessageId = "Logout")] - public Saml2BindingType SingleLogoutServiceBinding - { - get - { - ReloadMetadataIfRequired(); - return singleLogoutServiceBinding == 0 - ? Binding - : singleLogoutServiceBinding; - } - set - { - singleLogoutServiceBinding = value; - } - } - - /// - /// The Entity Id of the identity provider. - /// - public EntityId EntityId { get; private set; } - - /// - /// Is this idp allowed to send unsolicited responses, i.e. idp initiated sign in? - /// - public bool AllowUnsolicitedAuthnResponse { get; set; } - - private string metadataLocation; - - /// - /// Location of metadata for the Identity Provider. Automatically enables - /// . The location can be a URL, an absolute - /// path to a local file or an app relative path - /// (e.g. ~/App_Data/IdpMetadata.xml). By default the entity id is - /// interpreted as the metadata location (which is a convention). - /// - public string MetadataLocation - { - get - { - return metadataLocation ?? EntityId.Id; - } - set - { - metadataLocation = value; - LoadMetadata = true; - } - } - - /// - /// Create an authenticate request aimed for this idp. - /// - /// Urls for Saml2, used to populate fields - /// in the created AuthnRequest - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "AuthenticateRequestSigningBehavior")] - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "ServiceCertificates")] - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "AuthenticateRequests")] - public Saml2AuthenticationRequest CreateAuthenticateRequest( - Saml2Urls saml2Urls) - { - if (saml2Urls == null) - { - throw new ArgumentNullException(nameof(saml2Urls)); - } - - var authnRequest = new Saml2AuthenticationRequest() - { - DestinationUrl = SingleSignOnServiceUrl, - AssertionConsumerServiceUrl = saml2Urls.AssertionConsumerServiceUrl, - Issuer = spOptions.EntityId, - // For now we only support one attribute consuming service. - AttributeConsumingServiceIndex = spOptions.AttributeConsumingServices.Any() ? 0 : (int?)null, - NameIdPolicy = spOptions.NameIdPolicy, - RequestedAuthnContext = spOptions.RequestedAuthnContext, - SigningAlgorithm = this.OutboundSigningAlgorithm - }; - - if (spOptions.AuthenticateRequestSigningBehavior == SigningBehavior.Always - || (spOptions.AuthenticateRequestSigningBehavior == SigningBehavior.IfIdpWantAuthnRequestsSigned - && WantAuthnRequestsSigned)) - { - if (spOptions.SigningServiceCertificate == null) - { - throw new ConfigurationErrorsException( - string.Format( - CultureInfo.InvariantCulture, - "Idp \"{0}\" is configured for signed AuthenticateRequests, but ServiceCertificates configuration contains no certificate with usage \"Signing\" or \"Both\". To resolve this issue you can a) add a service certificate with usage \"Signing\" or \"Both\" (default if not specified is \"Both\") or b) Set the AuthenticateRequestSigningBehavior configuration property to \"Never\".", - EntityId.Id)); - } - - authnRequest.SigningCertificate = spOptions.SigningServiceCertificate; - } - - return authnRequest; - } - - /// - /// Signing Algorithm to be used when signing oubound messages. - /// - public string OutboundSigningAlgorithm { get; set; } - - /// - /// Bind a Saml2AuthenticateRequest using the active binding of the idp, - /// producing a CommandResult with the result of the binding. - /// - /// The AuthnRequest to bind. - /// CommandResult with the bound request. - public CommandResult Bind(ISaml2Message request) - { - return Saml2Binding.Get(Binding).Bind(request); - } - - private ConfiguredAndLoadedSigningKeysCollection signingKeys = - new ConfiguredAndLoadedSigningKeysCollection(); - - /// - /// The public key of the idp that is used to verify signatures of responses/assertions. - /// - public ConfiguredAndLoadedSigningKeysCollection SigningKeys - { - get - { - ReloadMetadataIfRequired(); - return signingKeys; - } - } - - object metadataLoadLock = new object(); - - private void DoLoadMetadata() - { - if (LoadMetadata) - { - lock (metadataLoadLock) - { - try - { - spOptions.Logger?.WriteInformation("Loading metadata for idp " + EntityId.Id); - var metadata = MetadataLoader.LoadIdp( - MetadataLocation, - spOptions.Compatibility.UnpackEntitiesDescriptorInIdentityProviderMetadata); - - ReadMetadata(metadata); - } - catch (WebException ex) - { - spOptions.Logger?.WriteError("Failed to load metadata for idp " + EntityId.Id, ex); - MetadataValidUntil = DateTime.MinValue; - throw; - } - } - } - } - - /// - /// Reads the supplied metadata and sets all properties of the - /// IdentityProvider based on the metadata. - /// - /// Metadata to read. - public void ReadMetadata(ExtendedEntityDescriptor metadata) - { - if (metadata == null) - { - throw new ArgumentNullException(nameof(metadata)); - } - - lock (metadataLoadLock) - { - if (metadata.EntityId.Id != EntityId.Id) - { - var msg = string.Format(CultureInfo.InvariantCulture, - "Unexpected entity id \"{0}\" found when loading metadata for \"{1}\".", - metadata.EntityId.Id, EntityId.Id); - throw new ConfigurationErrorsException(msg); - } - - ReadMetadataIdpDescriptor(metadata); - - MetadataValidUntil = metadata.CalculateMetadataValidUntil(); - } - } - - private void ReadMetadataIdpDescriptor(ExtendedEntityDescriptor metadata) - { - var idpDescriptor = metadata.RoleDescriptors - .OfType().Single(); - - WantAuthnRequestsSigned = idpDescriptor.WantAuthenticationRequestsSigned; - - var ssoService = GetPreferredEndpoint(idpDescriptor.SingleSignOnServices); - if (ssoService != null) - { - binding = Saml2Binding.UriToSaml2BindingType(ssoService.Binding); - singleSignOnServiceUrl = ssoService.Location; - } - - var sloService = GetPreferredEndpoint(idpDescriptor.SingleLogoutServices); - if (sloService != null) - { - SingleLogoutServiceUrl = sloService.Location; - SingleLogoutServiceBinding = Saml2Binding.UriToSaml2BindingType(sloService.Binding); - singleLogoutServiceResponseUrl = sloService.ResponseLocation; - } - - foreach (var ars in idpDescriptor.ArtifactResolutionServices) - { - artifactResolutionServiceUrls[ars.Value.Index] = ars.Value.Location; - } - - foreach (var ars in artifactResolutionServiceUrls.Keys - .Where(k => !idpDescriptor.ArtifactResolutionServices.Keys.Contains(k))) - { - artifactResolutionServiceUrls.Remove(ars); - } - - var keys = idpDescriptor.Keys.Where(k => k.Use == KeyType.Unspecified || k.Use == KeyType.Signing); - - signingKeys.SetLoadedItems(keys.Select(k => k.KeyInfo.First(c => c.CanCreateKey)).ToList()); - } - - private static ProtocolEndpoint GetPreferredEndpoint(ICollection endpoints) - { - // Prefer an endpoint with a redirect binding, then check for POST which - // is the other supported by Saml2. - return endpoints.FirstOrDefault(s => s.Binding == Saml2Binding.HttpRedirectUri) ?? - endpoints.FirstOrDefault(s => s.Binding == Saml2Binding.HttpPostUri); - } - - private DateTime? metadataValidUntil; - - /// - /// Validity time of the metadata this idp was configured from. Null if - /// idp was not configured from metadata. - /// - public DateTime? MetadataValidUntil - { - get - { - return metadataValidUntil; - } - private set - { - metadataValidUntil = value; - - if (LoadMetadata) - { - ScheduleMetadataRefresh(); - } - } - } - - private void ScheduleMetadataRefresh() - { - // Use a weak reference to allow garbage collector to collect any - // non-referenced IdentityProvider objects without the timer being - // the thing that keeps it alive. - var weakThis = new WeakReference(this); - - Task.Delay(MetadataRefreshScheduler.GetDelay(MetadataValidUntil.Value)) - .ContinueWith((_) => DoLoadMetadataIfTargetAlive(weakThis)); - } - - // Exclude because we don't want to wait for a GC run during unit test run - // to trigger the case when the Idp has been garbaged collected. - [ExcludeFromCodeCoverage] - private static void DoLoadMetadataIfTargetAlive(WeakReference target) - { - IdentityProvider idp; - if(target.TryGetTarget(out idp)) - { - idp.DoLoadMetadata(); - } - } - - /// - /// Does this Idp want the AuthnRequests signed? - /// - public bool WantAuthnRequestsSigned { get; set; } - - private void ReloadMetadataIfRequired() - { - if (LoadMetadata && MetadataValidUntil.Value < DateTime.UtcNow) - { - lock (metadataLoadLock) - { - DoLoadMetadata(); - } - } - } - - /// - /// Create a logout request to the idp, for the current identity. - /// - /// - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "serviceCertificates")] - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "ServiceCertificates")] - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "ISPOptions")] - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1726:UsePreferredTerms", MessageId = "Logout")] - public Saml2LogoutRequest CreateLogoutRequest(ClaimsPrincipal user) - { - if (user == null) throw new ArgumentNullException(nameof(user)); - if (spOptions.SigningServiceCertificate == null) - { - throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, - "Tried to issue single logout request to {0}, but no signing certificate for the SP is configured and single logout requires signing. Add a certificate to the ISPOptions.ServiceCertificates collection, or to element if you're using web.config.", - EntityId.Id)); - } - - return new Saml2LogoutRequest() - { - DestinationUrl = SingleLogoutServiceUrl, - Issuer = spOptions.EntityId, - NameId = user.FindFirst(Saml2ClaimTypes.LogoutNameIdentifier) - .ToSaml2NameIdentifier(), - SessionIndex = - user.FindFirst(Saml2ClaimTypes.SessionIndex).Value, - SigningCertificate = spOptions.SigningServiceCertificate, - SigningAlgorithm = OutboundSigningAlgorithm - }; - } - - /// - /// Disable outbound logout requests to this idp, even though - /// Saml2 is configured for single logout and the idp supports - /// it. This setting might be usable when adding SLO to an existing - /// setup, to ensure that everyone is ready for SLO before activating. - /// - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1726:UsePreferredTerms", MessageId = "Logout")] - public bool DisableOutboundLogoutRequests { get; set; } - } -} +using System.Collections.Generic; +using Sustainsys.Saml2.Configuration; +using System; +using System.Configuration; +using System.Globalization; +using System.IdentityModel.Metadata; +using System.IdentityModel.Tokens; +using System.Linq; +using System.Security.Cryptography; +using System.Security.Cryptography.Xml; +using Sustainsys.Saml2.Internal; +using Sustainsys.Saml2.Metadata; +using Sustainsys.Saml2.Saml2P; +using Sustainsys.Saml2.WebSso; +using System.Threading.Tasks; +using System.Net; +using System.Collections.Concurrent; +using System.Security.Claims; +using System.Diagnostics.CodeAnalysis; + +namespace Sustainsys.Saml2 +{ + /// + /// Represents a known identity provider that this service provider can communicate with. + /// + public class IdentityProvider + { + /// + /// Ctor + /// + /// Entity id of the identityprovider. + /// Service provider options to use when + /// creating AuthnRequests for this Idp. + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "sp")] + public IdentityProvider(EntityId entityId, SPOptions spOptions) + { + if (spOptions == null) + { + throw new ArgumentNullException(nameof(spOptions)); + } + + EntityId = entityId; + this.spOptions = spOptions; + OutboundSigningAlgorithm = spOptions.OutboundSigningAlgorithm; + } + + readonly SPOptions spOptions; + + internal IdentityProvider(IdentityProviderElement config, SPOptions spOptions) + { + singleSignOnServiceUrl = config.SignOnUrl; + SingleLogoutServiceUrl = config.LogoutUrl; + EntityId = new EntityId(config.EntityId); + binding = config.Binding; + AllowUnsolicitedAuthnResponse = config.AllowUnsolicitedAuthnResponse; + metadataLocation = string.IsNullOrEmpty(config.MetadataLocation) + ? null : config.MetadataLocation; + WantAuthnRequestsSigned = config.WantAuthnRequestsSigned; + DisableOutboundLogoutRequests = config.DisableOutboundLogoutRequests; + + var certificate = config.SigningCertificate.LoadCertificate(); + if (certificate != null) + { + signingKeys.AddConfiguredKey( + new X509RawDataKeyIdentifierClause(certificate)); + } + + OutboundSigningAlgorithm = string.IsNullOrEmpty(config.OutboundSigningAlgorithm) ? + spOptions.OutboundSigningAlgorithm : + XmlHelpers.GetFullSigningAlgorithmName(config.OutboundSigningAlgorithm); + + foreach (var ars in config.ArtifactResolutionServices) + { + ArtifactResolutionServiceUrls[ars.Index] = ars.Location; + } + + // If configured to load metadata, this will immediately do the load. + this.spOptions = spOptions; + LoadMetadata = config.LoadMetadata || !string.IsNullOrEmpty(config.MetadataLocation); + + // Validate if values are only from config. If metadata is loaded, validation + // is done on metadata load. + if (!LoadMetadata) + { + Validate(); + } + } + + private void Validate() + { + if (Binding == 0) + { + throw new ConfigurationErrorsException("Missing binding configuration on Idp " + EntityId.Id + "."); + } + + if (!SigningKeys.Any()) + { + throw new ConfigurationErrorsException("Missing signing certificate configuration on Idp " + EntityId.Id + "."); + } + + if (SingleSignOnServiceUrl == null) + { + throw new ConfigurationErrorsException("Missing assertion consumer service url configuration on Idp " + EntityId.Id + "."); + } + } + + private bool loadMetadata; + + /// + /// Should this idp load metadata? The metadata is loaded immediately + /// when the property is set to true, so the + /// must be correct before settingLoadMetadata to true. + public bool LoadMetadata + { + get + { + return loadMetadata; + } + set + { + loadMetadata = value; + try + { + DoLoadMetadata(); + Validate(); + } + catch (WebException) + { + // Ignore if metadata load failed, an automatic + // retry has been scheduled. + } + } + } + + private Saml2BindingType binding; + + /// + /// The binding used when sending AuthnRequests to the identity provider. + /// + public Saml2BindingType Binding + { + get + { + ReloadMetadataIfRequired(); + return binding; + } + set + { + binding = value; + } + } + + private Uri singleSignOnServiceUrl; + + /// + /// The Url of the single sign on service. This is where the browser is redirected or + /// where the post data is sent to when sending an AuthnRequest to the idp. + /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1726:UsePreferredTerms", MessageId = "SignOn")] + public Uri SingleSignOnServiceUrl + { + get + { + ReloadMetadataIfRequired(); + return singleSignOnServiceUrl; + } + set + { + singleSignOnServiceUrl = value; + } + } + + private IDictionary artifactResolutionServiceUrls + = new ConcurrentDictionary(); + + /// + /// Artifact resolution endpoints on the idp. + /// + public IDictionary ArtifactResolutionServiceUrls + { + get + { + ReloadMetadataIfRequired(); + return artifactResolutionServiceUrls; + } + } + + + Uri singleLogoutServiceUrl; + /// + /// The Url of the single sign out service. This is where the browser + /// is redirected or where the post data is sent to when sending a + /// LogoutRequest to the idp. + /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1726:UsePreferredTerms", MessageId = "Logout")] + public Uri SingleLogoutServiceUrl + { + get + { + ReloadMetadataIfRequired(); + return singleLogoutServiceUrl; + } + set + { + singleLogoutServiceUrl = value; + } + } + + Uri singleLogoutServiceResponseUrl; + /// + /// The Url to send single logout responses to. Defaults to + /// SingleLogoutServiceUrl. + /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1726:UsePreferredTerms", MessageId = "Logout")] + public Uri SingleLogoutServiceResponseUrl + { + get + { + ReloadMetadataIfRequired(); + return singleLogoutServiceResponseUrl ?? SingleLogoutServiceUrl; + } + set + { + singleLogoutServiceResponseUrl = value; + } + } + + private Saml2BindingType singleLogoutServiceBinding; + /// + /// Binding for the Single logout service. If not set, returns the + /// same as the main binding (used for AuthnRequests) + /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1726:UsePreferredTerms", MessageId = "Logout")] + public Saml2BindingType SingleLogoutServiceBinding + { + get + { + ReloadMetadataIfRequired(); + return singleLogoutServiceBinding == 0 + ? Binding + : singleLogoutServiceBinding; + } + set + { + singleLogoutServiceBinding = value; + } + } + + /// + /// The Entity Id of the identity provider. + /// + public EntityId EntityId { get; private set; } + + /// + /// Is this idp allowed to send unsolicited responses, i.e. idp initiated sign in? + /// + public bool AllowUnsolicitedAuthnResponse { get; set; } + + private string metadataLocation; + + /// + /// Location of metadata for the Identity Provider. Automatically enables + /// . The location can be a URL, an absolute + /// path to a local file or an app relative path + /// (e.g. ~/App_Data/IdpMetadata.xml). By default the entity id is + /// interpreted as the metadata location (which is a convention). + /// + public string MetadataLocation + { + get + { + return metadataLocation ?? EntityId.Id; + } + set + { + metadataLocation = value; + LoadMetadata = true; + } + } + + /// + /// Create an authenticate request aimed for this idp. + /// + /// Urls for Saml2, used to populate fields + /// in the created AuthnRequest + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "AuthenticateRequestSigningBehavior")] + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "ServiceCertificates")] + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "AuthenticateRequests")] + public Saml2AuthenticationRequest CreateAuthenticateRequest( + Saml2Urls saml2Urls) + { + if (saml2Urls == null) + { + throw new ArgumentNullException(nameof(saml2Urls)); + } + + var authnRequest = new Saml2AuthenticationRequest() + { + DestinationUrl = SingleSignOnServiceUrl, + AssertionConsumerServiceUrl = saml2Urls.AssertionConsumerServiceUrl, + Issuer = spOptions.EntityId, + // For now we only support one attribute consuming service. + AttributeConsumingServiceIndex = spOptions.AttributeConsumingServices.Any() ? 0 : (int?)null, + NameIdPolicy = spOptions.NameIdPolicy, + RequestedAuthnContext = spOptions.RequestedAuthnContext, + SigningAlgorithm = this.OutboundSigningAlgorithm + }; + + if (spOptions.AuthenticateRequestSigningBehavior == SigningBehavior.Always + || (spOptions.AuthenticateRequestSigningBehavior == SigningBehavior.IfIdpWantAuthnRequestsSigned + && WantAuthnRequestsSigned)) + { + if (spOptions.SigningServiceCertificate == null) + { + throw new ConfigurationErrorsException( + string.Format( + CultureInfo.InvariantCulture, + "Idp \"{0}\" is configured for signed AuthenticateRequests, but ServiceCertificates configuration contains no certificate with usage \"Signing\" or \"Both\". To resolve this issue you can a) add a service certificate with usage \"Signing\" or \"Both\" (default if not specified is \"Both\") or b) Set the AuthenticateRequestSigningBehavior configuration property to \"Never\".", + EntityId.Id)); + } + + authnRequest.SigningCertificate = spOptions.SigningServiceCertificate; + } + + return authnRequest; + } + + /// + /// Signing Algorithm to be used when signing oubound messages. + /// + public string OutboundSigningAlgorithm { get; set; } + + /// + /// Bind a Saml2AuthenticateRequest using the active binding of the idp, + /// producing a CommandResult with the result of the binding. + /// + /// The AuthnRequest to bind. + /// CommandResult with the bound request. + public CommandResult Bind(ISaml2Message request) + { + return Saml2Binding.Get(Binding).Bind(request); + } + + private ConfiguredAndLoadedSigningKeysCollection signingKeys = + new ConfiguredAndLoadedSigningKeysCollection(); + + /// + /// The public key of the idp that is used to verify signatures of responses/assertions. + /// + public ConfiguredAndLoadedSigningKeysCollection SigningKeys + { + get + { + ReloadMetadataIfRequired(); + return signingKeys; + } + } + + object metadataLoadLock = new object(); + + private void DoLoadMetadata() + { + if (LoadMetadata) + { + lock (metadataLoadLock) + { + try + { + spOptions.Logger?.WriteInformation("Loading metadata for idp " + EntityId.Id); + var metadata = MetadataLoader.LoadIdp( + MetadataLocation, + spOptions.Compatibility.UnpackEntitiesDescriptorInIdentityProviderMetadata); + + ReadMetadata(metadata); + } + catch (WebException ex) + { + spOptions.Logger?.WriteError("Failed to load metadata for idp " + EntityId.Id, ex); + MetadataValidUntil = DateTime.MinValue; + throw; + } + } + } + } + + /// + /// Reads the supplied metadata and sets all properties of the + /// IdentityProvider based on the metadata. + /// + /// Metadata to read. + public void ReadMetadata(ExtendedEntityDescriptor metadata) + { + if (metadata == null) + { + throw new ArgumentNullException(nameof(metadata)); + } + + lock (metadataLoadLock) + { + if (metadata.EntityId.Id != EntityId.Id) + { + var msg = string.Format(CultureInfo.InvariantCulture, + "Unexpected entity id \"{0}\" found when loading metadata for \"{1}\".", + metadata.EntityId.Id, EntityId.Id); + throw new ConfigurationErrorsException(msg); + } + + ReadMetadataIdpDescriptor(metadata); + + MetadataValidUntil = metadata.CalculateMetadataValidUntil(); + } + } + + private void ReadMetadataIdpDescriptor(ExtendedEntityDescriptor metadata) + { + var idpDescriptor = metadata.RoleDescriptors + .OfType().Single(); + + WantAuthnRequestsSigned = idpDescriptor.WantAuthenticationRequestsSigned; + + var ssoService = GetPreferredEndpoint(idpDescriptor.SingleSignOnServices); + if (ssoService != null) + { + binding = Saml2Binding.UriToSaml2BindingType(ssoService.Binding); + singleSignOnServiceUrl = ssoService.Location; + } + + var sloService = GetPreferredEndpoint(idpDescriptor.SingleLogoutServices); + if (sloService != null) + { + SingleLogoutServiceUrl = sloService.Location; + SingleLogoutServiceBinding = Saml2Binding.UriToSaml2BindingType(sloService.Binding); + singleLogoutServiceResponseUrl = sloService.ResponseLocation; + } + + foreach (var ars in idpDescriptor.ArtifactResolutionServices) + { + artifactResolutionServiceUrls[ars.Value.Index] = ars.Value.Location; + } + + foreach (var ars in artifactResolutionServiceUrls.Keys + .Where(k => !idpDescriptor.ArtifactResolutionServices.Keys.Contains(k))) + { + artifactResolutionServiceUrls.Remove(ars); + } + + var keys = idpDescriptor.Keys.Where(k => k.Use == KeyType.Unspecified || k.Use == KeyType.Signing); + + signingKeys.SetLoadedItems(keys.Select(k => k.KeyInfo.First(c => c.CanCreateKey)).ToList()); + } + + private static ProtocolEndpoint GetPreferredEndpoint(ICollection endpoints) + { + // Prefer an endpoint with a redirect binding, then check for POST which + // is the other supported by Saml2. + return endpoints.FirstOrDefault(s => s.Binding == Saml2Binding.HttpRedirectUri) ?? + endpoints.FirstOrDefault(s => s.Binding == Saml2Binding.HttpPostUri); + } + + private DateTime? metadataValidUntil; + + /// + /// Validity time of the metadata this idp was configured from. Null if + /// idp was not configured from metadata. + /// + public DateTime? MetadataValidUntil + { + get + { + return metadataValidUntil; + } + private set + { + metadataValidUntil = value; + + if (LoadMetadata) + { + ScheduleMetadataRefresh(); + } + } + } + + private void ScheduleMetadataRefresh() + { + // Use a weak reference to allow garbage collector to collect any + // non-referenced IdentityProvider objects without the timer being + // the thing that keeps it alive. + var weakThis = new WeakReference(this); + + Task.Delay(MetadataRefreshScheduler.GetDelay(MetadataValidUntil.Value)) + .ContinueWith((_) => DoLoadMetadataIfTargetAlive(weakThis)); + } + + // Exclude because we don't want to wait for a GC run during unit test run + // to trigger the case when the Idp has been garbaged collected. + [ExcludeFromCodeCoverage] + private static void DoLoadMetadataIfTargetAlive(WeakReference target) + { + IdentityProvider idp; + if(target.TryGetTarget(out idp)) + { + idp.DoLoadMetadata(); + } + } + + /// + /// Does this Idp want the AuthnRequests signed? + /// + public bool WantAuthnRequestsSigned { get; set; } + + private void ReloadMetadataIfRequired() + { + if (LoadMetadata && MetadataValidUntil.Value < DateTime.UtcNow) + { + lock (metadataLoadLock) + { + DoLoadMetadata(); + } + } + } + + /// + /// Create a logout request to the idp, for the current identity. + /// + /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "serviceCertificates")] + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "ServiceCertificates")] + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "ISPOptions")] + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1726:UsePreferredTerms", MessageId = "Logout")] + public Saml2LogoutRequest CreateLogoutRequest(ClaimsPrincipal user) + { + if (user == null) throw new ArgumentNullException(nameof(user)); + if (spOptions.SigningServiceCertificate == null) + { + throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, + "Tried to issue single logout request to {0}, but no signing certificate for the SP is configured and single logout requires signing. Add a certificate to the ISPOptions.ServiceCertificates collection, or to element if you're using web.config.", + EntityId.Id)); + } + + return new Saml2LogoutRequest() + { + DestinationUrl = SingleLogoutServiceUrl, + Issuer = spOptions.EntityId, + NameId = user.FindFirst(Saml2ClaimTypes.LogoutNameIdentifier) + .ToSaml2NameIdentifier(), + SessionIndex = + user.FindFirst(Saml2ClaimTypes.SessionIndex).Value, + SigningCertificate = spOptions.SigningServiceCertificate, + SigningAlgorithm = OutboundSigningAlgorithm + }; + } + + /// + /// Disable outbound logout requests to this idp, even though + /// Saml2 is configured for single logout and the idp supports + /// it. This setting might be usable when adding SLO to an existing + /// setup, to ensure that everyone is ready for SLO before activating. + /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1726:UsePreferredTerms", MessageId = "Logout")] + public bool DisableOutboundLogoutRequests { get; set; } + } +} diff --git a/Kentor.AuthServices/Internal/CryptographyExtensions.cs b/Sustainsys.Saml2/Internal/CryptographyExtensions.cs similarity index 100% rename from Kentor.AuthServices/Internal/CryptographyExtensions.cs rename to Sustainsys.Saml2/Internal/CryptographyExtensions.cs diff --git a/Kentor.AuthServices/Internal/DateTimeHelper.cs b/Sustainsys.Saml2/Internal/DateTimeHelper.cs similarity index 100% rename from Kentor.AuthServices/Internal/DateTimeHelper.cs rename to Sustainsys.Saml2/Internal/DateTimeHelper.cs diff --git a/Kentor.AuthServices/Internal/DelimitedString.cs b/Sustainsys.Saml2/Internal/DelimitedString.cs similarity index 100% rename from Kentor.AuthServices/Internal/DelimitedString.cs rename to Sustainsys.Saml2/Internal/DelimitedString.cs diff --git a/Kentor.AuthServices/Internal/DictionaryExtensions.cs b/Sustainsys.Saml2/Internal/DictionaryExtensions.cs similarity index 100% rename from Kentor.AuthServices/Internal/DictionaryExtensions.cs rename to Sustainsys.Saml2/Internal/DictionaryExtensions.cs diff --git a/Kentor.AuthServices/Internal/EntityIdEqualityComparer.cs b/Sustainsys.Saml2/Internal/EntityIdEqualityComparer.cs similarity index 100% rename from Kentor.AuthServices/Internal/EntityIdEqualityComparer.cs rename to Sustainsys.Saml2/Internal/EntityIdEqualityComparer.cs diff --git a/Kentor.AuthServices/Internal/Enumerator.cs b/Sustainsys.Saml2/Internal/Enumerator.cs similarity index 100% rename from Kentor.AuthServices/Internal/Enumerator.cs rename to Sustainsys.Saml2/Internal/Enumerator.cs diff --git a/Kentor.AuthServices/Internal/PathHelper.cs b/Sustainsys.Saml2/Internal/PathHelper.cs similarity index 100% rename from Kentor.AuthServices/Internal/PathHelper.cs rename to Sustainsys.Saml2/Internal/PathHelper.cs diff --git a/Kentor.AuthServices/Internal/QueryStringHelper.cs b/Sustainsys.Saml2/Internal/QueryStringHelper.cs similarity index 100% rename from Kentor.AuthServices/Internal/QueryStringHelper.cs rename to Sustainsys.Saml2/Internal/QueryStringHelper.cs diff --git a/Kentor.AuthServices/Internal/RSAEncryptedXml.cs b/Sustainsys.Saml2/Internal/RSAEncryptedXml.cs similarity index 100% rename from Kentor.AuthServices/Internal/RSAEncryptedXml.cs rename to Sustainsys.Saml2/Internal/RSAEncryptedXml.cs diff --git a/Kentor.AuthServices/Internal/ReturnRequestedIssuerNameRegistry.cs b/Sustainsys.Saml2/Internal/ReturnRequestedIssuerNameRegistry.cs similarity index 100% rename from Kentor.AuthServices/Internal/ReturnRequestedIssuerNameRegistry.cs rename to Sustainsys.Saml2/Internal/ReturnRequestedIssuerNameRegistry.cs diff --git a/Kentor.AuthServices/Internal/StatusCodeHelper.cs b/Sustainsys.Saml2/Internal/StatusCodeHelper.cs similarity index 100% rename from Kentor.AuthServices/Internal/StatusCodeHelper.cs rename to Sustainsys.Saml2/Internal/StatusCodeHelper.cs diff --git a/Kentor.AuthServices/Internal/StringHelpers.cs b/Sustainsys.Saml2/Internal/StringHelpers.cs similarity index 100% rename from Kentor.AuthServices/Internal/StringHelpers.cs rename to Sustainsys.Saml2/Internal/StringHelpers.cs diff --git a/Kentor.AuthServices/ManagedSha256SignatureDescription.cs b/Sustainsys.Saml2/ManagedSha256SignatureDescription.cs similarity index 100% rename from Kentor.AuthServices/ManagedSha256SignatureDescription.cs rename to Sustainsys.Saml2/ManagedSha256SignatureDescription.cs diff --git a/Kentor.AuthServices/Metadata/AttributeConsumingService.cs b/Sustainsys.Saml2/Metadata/AttributeConsumingService.cs similarity index 100% rename from Kentor.AuthServices/Metadata/AttributeConsumingService.cs rename to Sustainsys.Saml2/Metadata/AttributeConsumingService.cs diff --git a/Kentor.AuthServices/Metadata/ExtendedEntitiesDescriptor.cs b/Sustainsys.Saml2/Metadata/ExtendedEntitiesDescriptor.cs similarity index 100% rename from Kentor.AuthServices/Metadata/ExtendedEntitiesDescriptor.cs rename to Sustainsys.Saml2/Metadata/ExtendedEntitiesDescriptor.cs diff --git a/Kentor.AuthServices/Metadata/ExtendedEntityDescriptor.cs b/Sustainsys.Saml2/Metadata/ExtendedEntityDescriptor.cs similarity index 100% rename from Kentor.AuthServices/Metadata/ExtendedEntityDescriptor.cs rename to Sustainsys.Saml2/Metadata/ExtendedEntityDescriptor.cs diff --git a/Kentor.AuthServices/Metadata/ExtendedMetadataSerializer.cs b/Sustainsys.Saml2/Metadata/ExtendedMetadataSerializer.cs similarity index 100% rename from Kentor.AuthServices/Metadata/ExtendedMetadataSerializer.cs rename to Sustainsys.Saml2/Metadata/ExtendedMetadataSerializer.cs diff --git a/Kentor.AuthServices/Metadata/ExtendedServiceProviderSingleSignOnDescriptor.cs b/Sustainsys.Saml2/Metadata/ExtendedServiceProviderSingleSignOnDescriptor.cs similarity index 100% rename from Kentor.AuthServices/Metadata/ExtendedServiceProviderSingleSignOnDescriptor.cs rename to Sustainsys.Saml2/Metadata/ExtendedServiceProviderSingleSignOnDescriptor.cs diff --git a/Kentor.AuthServices/Metadata/FilteringXmlDictionaryReader.cs b/Sustainsys.Saml2/Metadata/FilteringXmlDictionaryReader.cs similarity index 100% rename from Kentor.AuthServices/Metadata/FilteringXmlDictionaryReader.cs rename to Sustainsys.Saml2/Metadata/FilteringXmlDictionaryReader.cs diff --git a/Kentor.AuthServices/Metadata/KeyInfoSerializer.cs b/Sustainsys.Saml2/Metadata/KeyInfoSerializer.cs similarity index 100% rename from Kentor.AuthServices/Metadata/KeyInfoSerializer.cs rename to Sustainsys.Saml2/Metadata/KeyInfoSerializer.cs diff --git a/Kentor.AuthServices/Metadata/MetadataLoader.cs b/Sustainsys.Saml2/Metadata/MetadataLoader.cs similarity index 100% rename from Kentor.AuthServices/Metadata/MetadataLoader.cs rename to Sustainsys.Saml2/Metadata/MetadataLoader.cs diff --git a/Kentor.AuthServices/Metadata/MetadataRefreshScheduler.cs b/Sustainsys.Saml2/Metadata/MetadataRefreshScheduler.cs similarity index 100% rename from Kentor.AuthServices/Metadata/MetadataRefreshScheduler.cs rename to Sustainsys.Saml2/Metadata/MetadataRefreshScheduler.cs diff --git a/Kentor.AuthServices/Metadata/MetadatabaseExtensions.cs b/Sustainsys.Saml2/Metadata/MetadatabaseExtensions.cs similarity index 100% rename from Kentor.AuthServices/Metadata/MetadatabaseExtensions.cs rename to Sustainsys.Saml2/Metadata/MetadatabaseExtensions.cs diff --git a/Kentor.AuthServices/Metadata/RequestedAttribute.cs b/Sustainsys.Saml2/Metadata/RequestedAttribute.cs similarity index 100% rename from Kentor.AuthServices/Metadata/RequestedAttribute.cs rename to Sustainsys.Saml2/Metadata/RequestedAttribute.cs diff --git a/Kentor.AuthServices/Metadata/SPOptionsExtensions.cs b/Sustainsys.Saml2/Metadata/SPOptionsExtensions.cs similarity index 100% rename from Kentor.AuthServices/Metadata/SPOptionsExtensions.cs rename to Sustainsys.Saml2/Metadata/SPOptionsExtensions.cs diff --git a/Kentor.AuthServices/Metadata/ServiceProviderSingleSignOnDescriptorExtensions.cs b/Sustainsys.Saml2/Metadata/ServiceProviderSingleSignOnDescriptorExtensions.cs similarity index 100% rename from Kentor.AuthServices/Metadata/ServiceProviderSingleSignOnDescriptorExtensions.cs rename to Sustainsys.Saml2/Metadata/ServiceProviderSingleSignOnDescriptorExtensions.cs diff --git a/Kentor.AuthServices/MetadataPublishOverrideType.cs b/Sustainsys.Saml2/MetadataPublishOverrideType.cs similarity index 100% rename from Kentor.AuthServices/MetadataPublishOverrideType.cs rename to Sustainsys.Saml2/MetadataPublishOverrideType.cs diff --git a/Kentor.AuthServices/NameIdFormatExtension.cs b/Sustainsys.Saml2/NameIdFormatExtension.cs similarity index 100% rename from Kentor.AuthServices/NameIdFormatExtension.cs rename to Sustainsys.Saml2/NameIdFormatExtension.cs diff --git a/Kentor.AuthServices/NullLoggerAdapter.cs b/Sustainsys.Saml2/NullLoggerAdapter.cs similarity index 100% rename from Kentor.AuthServices/NullLoggerAdapter.cs rename to Sustainsys.Saml2/NullLoggerAdapter.cs diff --git a/Kentor.AuthServices/Properties/AssemblyInfo.cs b/Sustainsys.Saml2/Properties/AssemblyInfo.cs similarity index 97% rename from Kentor.AuthServices/Properties/AssemblyInfo.cs rename to Sustainsys.Saml2/Properties/AssemblyInfo.cs index 4db7489dd..9bd67ee34 100644 --- a/Kentor.AuthServices/Properties/AssemblyInfo.cs +++ b/Sustainsys.Saml2/Properties/AssemblyInfo.cs @@ -1,33 +1,33 @@ -using System; -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("Sustainsys.Saml2")] -[assembly: AssemblyDescription("Saml2 Authentication for ASP.NET")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyProduct("Sustainsys.Saml2")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("6ca3099a-e209-4c65-aaf4-1a73d8d9bd48")] - -[assembly: CLSCompliant(true)] - -[assembly: InternalsVisibleTo("Tests")] -[assembly: InternalsVisibleTo("TestHelpers")] -[assembly: InternalsVisibleTo("Owin.Tests")] -[assembly: InternalsVisibleTo("HttpModule.Tests")] -[assembly: InternalsVisibleTo("AspNetCore2.Tests")] - -// Required for NSubstitute to be able to generate stub for internal interface. -[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")] +using System; +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("Sustainsys.Saml2")] +[assembly: AssemblyDescription("Saml2 Authentication for ASP.NET")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyProduct("Sustainsys.Saml2")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("6ca3099a-e209-4c65-aaf4-1a73d8d9bd48")] + +[assembly: CLSCompliant(true)] + +[assembly: InternalsVisibleTo("Tests")] +[assembly: InternalsVisibleTo("TestHelpers")] +[assembly: InternalsVisibleTo("Owin.Tests")] +[assembly: InternalsVisibleTo("HttpModule.Tests")] +[assembly: InternalsVisibleTo("AspNetCore2.Tests")] + +// Required for NSubstitute to be able to generate stub for internal interface. +[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")] diff --git a/Kentor.AuthServices/RelayStateGenerator.cs b/Sustainsys.Saml2/RelayStateGenerator.cs similarity index 100% rename from Kentor.AuthServices/RelayStateGenerator.cs rename to Sustainsys.Saml2/RelayStateGenerator.cs diff --git a/Kentor.AuthServices/SAML2P/AuthnContextComparisonType.cs b/Sustainsys.Saml2/SAML2P/AuthnContextComparisonType.cs similarity index 100% rename from Kentor.AuthServices/SAML2P/AuthnContextComparisonType.cs rename to Sustainsys.Saml2/SAML2P/AuthnContextComparisonType.cs diff --git a/Kentor.AuthServices/SAML2P/FilteringXmlNodeReader.cs b/Sustainsys.Saml2/SAML2P/FilteringXmlNodeReader.cs similarity index 100% rename from Kentor.AuthServices/SAML2P/FilteringXmlNodeReader.cs rename to Sustainsys.Saml2/SAML2P/FilteringXmlNodeReader.cs diff --git a/Kentor.AuthServices/SAML2P/ISaml2Message.cs b/Sustainsys.Saml2/SAML2P/ISaml2Message.cs similarity index 100% rename from Kentor.AuthServices/SAML2P/ISaml2Message.cs rename to Sustainsys.Saml2/SAML2P/ISaml2Message.cs diff --git a/Kentor.AuthServices/SAML2P/NameIdFormat.cs b/Sustainsys.Saml2/SAML2P/NameIdFormat.cs similarity index 100% rename from Kentor.AuthServices/SAML2P/NameIdFormat.cs rename to Sustainsys.Saml2/SAML2P/NameIdFormat.cs diff --git a/Kentor.AuthServices/SAML2P/Saml2ArtifactResolve.cs b/Sustainsys.Saml2/SAML2P/Saml2ArtifactResolve.cs similarity index 100% rename from Kentor.AuthServices/SAML2P/Saml2ArtifactResolve.cs rename to Sustainsys.Saml2/SAML2P/Saml2ArtifactResolve.cs diff --git a/Kentor.AuthServices/SAML2P/Saml2ArtifactResponse.cs b/Sustainsys.Saml2/SAML2P/Saml2ArtifactResponse.cs similarity index 100% rename from Kentor.AuthServices/SAML2P/Saml2ArtifactResponse.cs rename to Sustainsys.Saml2/SAML2P/Saml2ArtifactResponse.cs diff --git a/Kentor.AuthServices/SAML2P/Saml2AuthenticationRequest.cs b/Sustainsys.Saml2/SAML2P/Saml2AuthenticationRequest.cs similarity index 97% rename from Kentor.AuthServices/SAML2P/Saml2AuthenticationRequest.cs rename to Sustainsys.Saml2/SAML2P/Saml2AuthenticationRequest.cs index 2f00e9da0..bc7034d2f 100644 --- a/Kentor.AuthServices/SAML2P/Saml2AuthenticationRequest.cs +++ b/Sustainsys.Saml2/SAML2P/Saml2AuthenticationRequest.cs @@ -1,224 +1,224 @@ -using System; -using System.Collections.Generic; -using System.Globalization; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Xml; -using System.Xml.Linq; -using Sustainsys.Saml2.Configuration; -using Sustainsys.Saml2.Internal; -using Sustainsys.Saml2.WebSso; - -namespace Sustainsys.Saml2.Saml2P -{ - /// - /// An authentication request corresponding to section 3.4.1 in SAML Core specification. - /// - public class Saml2AuthenticationRequest : Saml2RequestBase - { - /// - /// Default constructor - /// - public Saml2AuthenticationRequest() - { - RelayState = SecureKeyGenerator.CreateRelayState(); - } - - /// - /// The SAML2 request name - /// - protected override string LocalName - { - get { return "AuthnRequest"; } - } - - /// - /// Serializes the request to a Xml message. - /// - /// XElement - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1308:NormalizeStringsToUppercase", Justification = "Lowercase demanded by specification.")] - public XElement ToXElement() - { - var x = new XElement(Saml2Namespaces.Saml2P + LocalName); - - x.Add(base.ToXNodes()); - if (Binding.HasValue) - { - x.AddAttributeIfNotNullOrEmpty("ProtocolBinding", Saml2Binding.Saml2BindingTypeToUri(Binding.Value)); - } - x.AddAttributeIfNotNullOrEmpty("AssertionConsumerServiceURL", AssertionConsumerServiceUrl); - x.AddAttributeIfNotNullOrEmpty("AttributeConsumingServiceIndex", AttributeConsumingServiceIndex); - if (ForceAuthentication) - { - x.Add(new XAttribute("ForceAuthn", ForceAuthentication)); - } - - AddNameIdPolicy(x); - - if (RequestedAuthnContext != null && RequestedAuthnContext.ClassRef != null) - { - x.Add(new XElement(Saml2Namespaces.Saml2P + "RequestedAuthnContext", - new XAttribute("Comparison", RequestedAuthnContext.Comparison.ToString().ToLowerInvariant()), - - // Add the classref as original string to avoid URL normalization - // and make sure the emitted value is exactly the configured. - new XElement(Saml2Namespaces.Saml2 + "AuthnContextClassRef", - RequestedAuthnContext.ClassRef.OriginalString))); - } - - AddScoping(x); - - return x; - } - - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "NameIdPolicy")] - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "AllowCreate")] - private void AddNameIdPolicy(XElement xElement) - { - if (NameIdPolicy != null && - (NameIdPolicy.AllowCreate.HasValue || NameIdPolicy.Format != NameIdFormat.NotConfigured)) - { - if (NameIdPolicy.AllowCreate.HasValue && NameIdPolicy.Format == NameIdFormat.Transient) - { - throw new InvalidOperationException("When NameIdPolicy/Format is set to Transient, it is not permitted to specify AllowCreate. Change Format or leave AllowCreate as null."); - } - - var nameIdPolicyElement = new XElement(Saml2Namespaces.Saml2P + "NameIDPolicy"); - - if (NameIdPolicy.Format != NameIdFormat.NotConfigured) - { - nameIdPolicyElement.Add(new XAttribute("Format", - NameIdPolicy.Format.GetUri())); - } - - if (NameIdPolicy.AllowCreate.HasValue) - { - nameIdPolicyElement.Add(new XAttribute("AllowCreate", - NameIdPolicy.AllowCreate)); - } - - xElement.Add(nameIdPolicyElement); - } - } - - private void AddScoping(XElement xElement) - { - if (Scoping != null) - { - xElement.Add(Scoping.ToXElement()); - } - } - - /// - /// Serializes the message into wellformed Xml. - /// - /// string containing the Xml data. - public override string ToXml() - { - return ToXElement().ToString(); - } - - /// - /// Read the supplied Xml and parse it into a authenticationrequest. - /// - /// xml data. - /// Relay State attached to the message or null if not present. - /// Saml2Request - /// On xml errors or unexpected xml structure. - public static Saml2AuthenticationRequest Read(string xml, string relayState) - { - if (xml == null) - { - return null; - } - var x = XmlHelpers.XmlDocumentFromString(xml); - - return new Saml2AuthenticationRequest(x.DocumentElement, relayState); - } - - /// - /// Ctor - /// - /// Xml data - /// RelayState associateed with the message. - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1806:DoNotIgnoreMethodResults", MessageId = "System.Enum.TryParse(System.String,System.Boolean,Sustainsys.Saml2.Saml2P.NameIdFormat@)")] - public Saml2AuthenticationRequest(XmlElement xml, string relayState) - { - ReadBaseProperties(xml); - RelayState = relayState; - - var AssertionConsumerServiceUriString = xml.Attributes["AssertionConsumerServiceURL"].GetValueIfNotNull(); - - if (AssertionConsumerServiceUriString != null) - { - AssertionConsumerServiceUrl = new Uri(AssertionConsumerServiceUriString); - } - - var forceAuthnString = xml.Attributes["ForceAuthn"].GetValueIfNotNull(); - if (forceAuthnString != null) - { - ForceAuthentication = bool.Parse(forceAuthnString); - } - - var node = xml["NameIDPolicy", Saml2Namespaces.Saml2PName]; - if (node != null) - { - var fullFormat = node.Attributes["Format"].GetValueIfNotNull(); - var format = fullFormat?.Split(':').LastOrDefault(); - NameIdFormat nameIdFormat = NameIdFormat.NotConfigured; - if (format != null) - { - Enum.TryParse(format, true, out nameIdFormat); - } - - bool? allowCreate = null; - var allowCreateStr = node.Attributes["AllowCreate"].GetValueIfNotNull(); - if (allowCreateStr != null) - { - allowCreate = bool.Parse(allowCreateStr); - } - - NameIdPolicy = new Saml2NameIdPolicy(allowCreate, nameIdFormat); - } - } - - /// - /// The assertion consumer url that the idp should send its response back to. - /// - public Uri AssertionConsumerServiceUrl { get; set; } - - /// - /// Index to the SP metadata where the list of requested attributes is found. - /// - public int? AttributeConsumingServiceIndex { get; set; } - - /// - /// Scoping for request - /// - public Saml2Scoping Scoping { get; set; } - - /// - /// NameId policy. - /// - public Saml2NameIdPolicy NameIdPolicy { get; set; } - - /// - /// RequestedAuthnContext. - /// - public Saml2RequestedAuthnContext RequestedAuthnContext { get; set; } - - /// - /// Binding type to request the Idp to use when responding. - /// - public Saml2BindingType? Binding { get; set; } - - /// - /// Sets whether request should force the idp to authenticate the presenter directly, - /// rather than rely on a previous security context. - /// If false, the ForceAuthn parameter is omitted from the request. - /// If true, the request is sent with ForceAuthn="true". - /// - public bool ForceAuthentication { get; set; } = false; - } -} +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Xml; +using System.Xml.Linq; +using Sustainsys.Saml2.Configuration; +using Sustainsys.Saml2.Internal; +using Sustainsys.Saml2.WebSso; + +namespace Sustainsys.Saml2.Saml2P +{ + /// + /// An authentication request corresponding to section 3.4.1 in SAML Core specification. + /// + public class Saml2AuthenticationRequest : Saml2RequestBase + { + /// + /// Default constructor + /// + public Saml2AuthenticationRequest() + { + RelayState = SecureKeyGenerator.CreateRelayState(); + } + + /// + /// The SAML2 request name + /// + protected override string LocalName + { + get { return "AuthnRequest"; } + } + + /// + /// Serializes the request to a Xml message. + /// + /// XElement + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1308:NormalizeStringsToUppercase", Justification = "Lowercase demanded by specification.")] + public XElement ToXElement() + { + var x = new XElement(Saml2Namespaces.Saml2P + LocalName); + + x.Add(base.ToXNodes()); + if (Binding.HasValue) + { + x.AddAttributeIfNotNullOrEmpty("ProtocolBinding", Saml2Binding.Saml2BindingTypeToUri(Binding.Value)); + } + x.AddAttributeIfNotNullOrEmpty("AssertionConsumerServiceURL", AssertionConsumerServiceUrl); + x.AddAttributeIfNotNullOrEmpty("AttributeConsumingServiceIndex", AttributeConsumingServiceIndex); + if (ForceAuthentication) + { + x.Add(new XAttribute("ForceAuthn", ForceAuthentication)); + } + + AddNameIdPolicy(x); + + if (RequestedAuthnContext != null && RequestedAuthnContext.ClassRef != null) + { + x.Add(new XElement(Saml2Namespaces.Saml2P + "RequestedAuthnContext", + new XAttribute("Comparison", RequestedAuthnContext.Comparison.ToString().ToLowerInvariant()), + + // Add the classref as original string to avoid URL normalization + // and make sure the emitted value is exactly the configured. + new XElement(Saml2Namespaces.Saml2 + "AuthnContextClassRef", + RequestedAuthnContext.ClassRef.OriginalString))); + } + + AddScoping(x); + + return x; + } + + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "NameIdPolicy")] + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "AllowCreate")] + private void AddNameIdPolicy(XElement xElement) + { + if (NameIdPolicy != null && + (NameIdPolicy.AllowCreate.HasValue || NameIdPolicy.Format != NameIdFormat.NotConfigured)) + { + if (NameIdPolicy.AllowCreate.HasValue && NameIdPolicy.Format == NameIdFormat.Transient) + { + throw new InvalidOperationException("When NameIdPolicy/Format is set to Transient, it is not permitted to specify AllowCreate. Change Format or leave AllowCreate as null."); + } + + var nameIdPolicyElement = new XElement(Saml2Namespaces.Saml2P + "NameIDPolicy"); + + if (NameIdPolicy.Format != NameIdFormat.NotConfigured) + { + nameIdPolicyElement.Add(new XAttribute("Format", + NameIdPolicy.Format.GetUri())); + } + + if (NameIdPolicy.AllowCreate.HasValue) + { + nameIdPolicyElement.Add(new XAttribute("AllowCreate", + NameIdPolicy.AllowCreate)); + } + + xElement.Add(nameIdPolicyElement); + } + } + + private void AddScoping(XElement xElement) + { + if (Scoping != null) + { + xElement.Add(Scoping.ToXElement()); + } + } + + /// + /// Serializes the message into wellformed Xml. + /// + /// string containing the Xml data. + public override string ToXml() + { + return ToXElement().ToString(); + } + + /// + /// Read the supplied Xml and parse it into a authenticationrequest. + /// + /// xml data. + /// Relay State attached to the message or null if not present. + /// Saml2Request + /// On xml errors or unexpected xml structure. + public static Saml2AuthenticationRequest Read(string xml, string relayState) + { + if (xml == null) + { + return null; + } + var x = XmlHelpers.XmlDocumentFromString(xml); + + return new Saml2AuthenticationRequest(x.DocumentElement, relayState); + } + + /// + /// Ctor + /// + /// Xml data + /// RelayState associateed with the message. + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1806:DoNotIgnoreMethodResults", MessageId = "System.Enum.TryParse(System.String,System.Boolean,Sustainsys.Saml2.Saml2P.NameIdFormat@)")] + public Saml2AuthenticationRequest(XmlElement xml, string relayState) + { + ReadBaseProperties(xml); + RelayState = relayState; + + var AssertionConsumerServiceUriString = xml.Attributes["AssertionConsumerServiceURL"].GetValueIfNotNull(); + + if (AssertionConsumerServiceUriString != null) + { + AssertionConsumerServiceUrl = new Uri(AssertionConsumerServiceUriString); + } + + var forceAuthnString = xml.Attributes["ForceAuthn"].GetValueIfNotNull(); + if (forceAuthnString != null) + { + ForceAuthentication = bool.Parse(forceAuthnString); + } + + var node = xml["NameIDPolicy", Saml2Namespaces.Saml2PName]; + if (node != null) + { + var fullFormat = node.Attributes["Format"].GetValueIfNotNull(); + var format = fullFormat?.Split(':').LastOrDefault(); + NameIdFormat nameIdFormat = NameIdFormat.NotConfigured; + if (format != null) + { + Enum.TryParse(format, true, out nameIdFormat); + } + + bool? allowCreate = null; + var allowCreateStr = node.Attributes["AllowCreate"].GetValueIfNotNull(); + if (allowCreateStr != null) + { + allowCreate = bool.Parse(allowCreateStr); + } + + NameIdPolicy = new Saml2NameIdPolicy(allowCreate, nameIdFormat); + } + } + + /// + /// The assertion consumer url that the idp should send its response back to. + /// + public Uri AssertionConsumerServiceUrl { get; set; } + + /// + /// Index to the SP metadata where the list of requested attributes is found. + /// + public int? AttributeConsumingServiceIndex { get; set; } + + /// + /// Scoping for request + /// + public Saml2Scoping Scoping { get; set; } + + /// + /// NameId policy. + /// + public Saml2NameIdPolicy NameIdPolicy { get; set; } + + /// + /// RequestedAuthnContext. + /// + public Saml2RequestedAuthnContext RequestedAuthnContext { get; set; } + + /// + /// Binding type to request the Idp to use when responding. + /// + public Saml2BindingType? Binding { get; set; } + + /// + /// Sets whether request should force the idp to authenticate the presenter directly, + /// rather than rely on a previous security context. + /// If false, the ForceAuthn parameter is omitted from the request. + /// If true, the request is sent with ForceAuthn="true". + /// + public bool ForceAuthentication { get; set; } = false; + } +} diff --git a/Kentor.AuthServices/SAML2P/Saml2IdPEntry.cs b/Sustainsys.Saml2/SAML2P/Saml2IdPEntry.cs similarity index 100% rename from Kentor.AuthServices/SAML2P/Saml2IdPEntry.cs rename to Sustainsys.Saml2/SAML2P/Saml2IdPEntry.cs diff --git a/Kentor.AuthServices/SAML2P/Saml2LogoutRequest.cs b/Sustainsys.Saml2/SAML2P/Saml2LogoutRequest.cs similarity index 100% rename from Kentor.AuthServices/SAML2P/Saml2LogoutRequest.cs rename to Sustainsys.Saml2/SAML2P/Saml2LogoutRequest.cs diff --git a/Kentor.AuthServices/SAML2P/Saml2LogoutResponse.cs b/Sustainsys.Saml2/SAML2P/Saml2LogoutResponse.cs similarity index 100% rename from Kentor.AuthServices/SAML2P/Saml2LogoutResponse.cs rename to Sustainsys.Saml2/SAML2P/Saml2LogoutResponse.cs diff --git a/Kentor.AuthServices/SAML2P/Saml2NameIDPolicy.cs b/Sustainsys.Saml2/SAML2P/Saml2NameIDPolicy.cs similarity index 100% rename from Kentor.AuthServices/SAML2P/Saml2NameIDPolicy.cs rename to Sustainsys.Saml2/SAML2P/Saml2NameIDPolicy.cs diff --git a/Kentor.AuthServices/SAML2P/Saml2PSecurityTokenHandler.cs b/Sustainsys.Saml2/SAML2P/Saml2PSecurityTokenHandler.cs similarity index 100% rename from Kentor.AuthServices/SAML2P/Saml2PSecurityTokenHandler.cs rename to Sustainsys.Saml2/SAML2P/Saml2PSecurityTokenHandler.cs diff --git a/Kentor.AuthServices/SAML2P/Saml2RequestBase.cs b/Sustainsys.Saml2/SAML2P/Saml2RequestBase.cs similarity index 100% rename from Kentor.AuthServices/SAML2P/Saml2RequestBase.cs rename to Sustainsys.Saml2/SAML2P/Saml2RequestBase.cs diff --git a/Kentor.AuthServices/SAML2P/Saml2RequestedAuthnContext.cs b/Sustainsys.Saml2/SAML2P/Saml2RequestedAuthnContext.cs similarity index 100% rename from Kentor.AuthServices/SAML2P/Saml2RequestedAuthnContext.cs rename to Sustainsys.Saml2/SAML2P/Saml2RequestedAuthnContext.cs diff --git a/Kentor.AuthServices/SAML2P/Saml2Response.cs b/Sustainsys.Saml2/SAML2P/Saml2Response.cs similarity index 100% rename from Kentor.AuthServices/SAML2P/Saml2Response.cs rename to Sustainsys.Saml2/SAML2P/Saml2Response.cs diff --git a/Kentor.AuthServices/SAML2P/Saml2Scoping.cs b/Sustainsys.Saml2/SAML2P/Saml2Scoping.cs similarity index 97% rename from Kentor.AuthServices/SAML2P/Saml2Scoping.cs rename to Sustainsys.Saml2/SAML2P/Saml2Scoping.cs index ec633d3c7..caaa590f5 100644 --- a/Kentor.AuthServices/SAML2P/Saml2Scoping.cs +++ b/Sustainsys.Saml2/SAML2P/Saml2Scoping.cs @@ -1,106 +1,106 @@ -using System; -using System.Collections.Generic; -using System.Globalization; -using System.IdentityModel.Metadata; -using System.Linq; -using System.Xml.Linq; - -namespace Sustainsys.Saml2.Saml2P -{ - /// - /// Saml2Scoping specifies a set of identity providers trusted by the - /// requester to authenticate the presenter, as well as limitations and - /// context related to proxying of the authentication request message to - /// subsequent identity providers by the responder. - /// - public class Saml2Scoping - { - /// - /// Gets advisory list of identity providers and associated information - /// that the requester deems acceptable to respond to the request. - /// - public IList IdPEntries { get; } = new List(); - - /// - /// Fluent config helper that adds a to the - /// - /// - /// Idp entry to add - /// this - public Saml2Scoping With(Saml2IdpEntry idpEntry) - { - IdPEntries.Add(idpEntry); - return this; - } - - private int? proxyCount; - - /// - /// Specifies the number of proxying indirections permissible between - /// the identity provider that receives the authentication request and - /// the identity provider who ultimately authenticates the principal. - /// A count of zero permits no proxying, while omitting (null) this - /// attribute expresses no such restriction. - /// - public int? ProxyCount - { - get - { - return proxyCount; - } - set - { - if(value < 0) - { - throw new ArgumentException("ProxyCount cannot be negative."); - } - proxyCount = value; - } - } - - /// - /// Gets or sets the set of requesting entities on whose behalf the - /// requester is acting. Used to communicate the chain of requesters - /// when proxying occurs. - /// - public IList RequesterIds { get; } = new List(); - - /// - /// Fluent config helper that adds a requester id to the - /// - /// - /// Requester Id to add - /// this - public Saml2Scoping WithRequesterId(EntityId requesterId) - { - RequesterIds.Add(requesterId); - return this; - } - - /// - /// Create XElement for the Saml2Scoping. - /// - public XElement ToXElement() - { - var scopingElement = new XElement(Saml2Namespaces.Saml2P + "Scoping"); - - if (ProxyCount.HasValue && ProxyCount.Value >= 0) - { - scopingElement.AddAttributeIfNotNullOrEmpty("ProxyCount", ProxyCount); - } - - if (IdPEntries.Count > 0) - { - scopingElement.Add(new XElement( - Saml2Namespaces.Saml2P + "IDPList", - IdPEntries.Select(x => x.ToXElement()))); - } - - scopingElement.Add(RequesterIds.Select(x => - new XElement(Saml2Namespaces.Saml2P + "RequesterID", x.Id))); - - return scopingElement; - } - } -} - +using System; +using System.Collections.Generic; +using System.Globalization; +using System.IdentityModel.Metadata; +using System.Linq; +using System.Xml.Linq; + +namespace Sustainsys.Saml2.Saml2P +{ + /// + /// Saml2Scoping specifies a set of identity providers trusted by the + /// requester to authenticate the presenter, as well as limitations and + /// context related to proxying of the authentication request message to + /// subsequent identity providers by the responder. + /// + public class Saml2Scoping + { + /// + /// Gets advisory list of identity providers and associated information + /// that the requester deems acceptable to respond to the request. + /// + public IList IdPEntries { get; } = new List(); + + /// + /// Fluent config helper that adds a to the + /// + /// + /// Idp entry to add + /// this + public Saml2Scoping With(Saml2IdpEntry idpEntry) + { + IdPEntries.Add(idpEntry); + return this; + } + + private int? proxyCount; + + /// + /// Specifies the number of proxying indirections permissible between + /// the identity provider that receives the authentication request and + /// the identity provider who ultimately authenticates the principal. + /// A count of zero permits no proxying, while omitting (null) this + /// attribute expresses no such restriction. + /// + public int? ProxyCount + { + get + { + return proxyCount; + } + set + { + if(value < 0) + { + throw new ArgumentException("ProxyCount cannot be negative."); + } + proxyCount = value; + } + } + + /// + /// Gets or sets the set of requesting entities on whose behalf the + /// requester is acting. Used to communicate the chain of requesters + /// when proxying occurs. + /// + public IList RequesterIds { get; } = new List(); + + /// + /// Fluent config helper that adds a requester id to the + /// + /// + /// Requester Id to add + /// this + public Saml2Scoping WithRequesterId(EntityId requesterId) + { + RequesterIds.Add(requesterId); + return this; + } + + /// + /// Create XElement for the Saml2Scoping. + /// + public XElement ToXElement() + { + var scopingElement = new XElement(Saml2Namespaces.Saml2P + "Scoping"); + + if (ProxyCount.HasValue && ProxyCount.Value >= 0) + { + scopingElement.AddAttributeIfNotNullOrEmpty("ProxyCount", ProxyCount); + } + + if (IdPEntries.Count > 0) + { + scopingElement.Add(new XElement( + Saml2Namespaces.Saml2P + "IDPList", + IdPEntries.Select(x => x.ToXElement()))); + } + + scopingElement.Add(RequesterIds.Select(x => + new XElement(Saml2Namespaces.Saml2P + "RequesterID", x.Id))); + + return scopingElement; + } + } +} + diff --git a/Kentor.AuthServices/SAML2P/Saml2SoapBinding.cs b/Sustainsys.Saml2/SAML2P/Saml2SoapBinding.cs similarity index 100% rename from Kentor.AuthServices/SAML2P/Saml2SoapBinding.cs rename to Sustainsys.Saml2/SAML2P/Saml2SoapBinding.cs diff --git a/Kentor.AuthServices/SAML2P/Saml2StatusCode.cs b/Sustainsys.Saml2/SAML2P/Saml2StatusCode.cs similarity index 100% rename from Kentor.AuthServices/SAML2P/Saml2StatusCode.cs rename to Sustainsys.Saml2/SAML2P/Saml2StatusCode.cs diff --git a/Kentor.AuthServices/SAML2P/Saml2StatusResponseType.cs b/Sustainsys.Saml2/SAML2P/Saml2StatusResponseType.cs similarity index 100% rename from Kentor.AuthServices/SAML2P/Saml2StatusResponseType.cs rename to Sustainsys.Saml2/SAML2P/Saml2StatusResponseType.cs diff --git a/Kentor.AuthServices/Saml2AssertionExtensions.cs b/Sustainsys.Saml2/Saml2AssertionExtensions.cs similarity index 96% rename from Kentor.AuthServices/Saml2AssertionExtensions.cs rename to Sustainsys.Saml2/Saml2AssertionExtensions.cs index 4519defd6..4f6eda963 100644 --- a/Kentor.AuthServices/Saml2AssertionExtensions.cs +++ b/Sustainsys.Saml2/Saml2AssertionExtensions.cs @@ -1,56 +1,56 @@ -using System; -using System.Globalization; -using System.IdentityModel.Tokens; -using System.Linq; -using System.Xml.Linq; -using Sustainsys.Saml2.Internal; - -namespace Sustainsys.Saml2 -{ - /// - /// Extension methods for Saml2Assertion - /// - public static class Saml2AssertionExtensions - { - /// - /// Writes out the assertion as an XElement. - /// - /// The assertion to create xml for. - /// XElement - public static XElement ToXElement(this Saml2Assertion assertion) - { - if(assertion == null) - { - throw new ArgumentNullException(nameof(assertion)); - } - - var xml = new XElement(Saml2Namespaces.Saml2 + "Assertion", - new XAttribute(XNamespace.Xmlns + "saml2", Saml2Namespaces.Saml2Name), - new XAttribute("Version", assertion.Version), - new XAttribute("ID", assertion.Id.Value), - new XAttribute("IssueInstant", - assertion.IssueInstant.ToSaml2DateTimeString()), - new XElement(Saml2Namespaces.Saml2 + "Issuer", assertion.Issuer.Value)); - - if (assertion.Subject != null) - { - xml.Add(assertion.Subject.ToXElement()); - } - - if(assertion.Conditions != null) - { - xml.Add(assertion.Conditions.ToXElement()); - } - - if (assertion.Statements != null) - { - foreach (var statement in assertion.Statements) - { - xml.Add(statement.ToXElement()); - }; - } - - return xml; - } - } -} +using System; +using System.Globalization; +using System.IdentityModel.Tokens; +using System.Linq; +using System.Xml.Linq; +using Sustainsys.Saml2.Internal; + +namespace Sustainsys.Saml2 +{ + /// + /// Extension methods for Saml2Assertion + /// + public static class Saml2AssertionExtensions + { + /// + /// Writes out the assertion as an XElement. + /// + /// The assertion to create xml for. + /// XElement + public static XElement ToXElement(this Saml2Assertion assertion) + { + if(assertion == null) + { + throw new ArgumentNullException(nameof(assertion)); + } + + var xml = new XElement(Saml2Namespaces.Saml2 + "Assertion", + new XAttribute(XNamespace.Xmlns + "saml2", Saml2Namespaces.Saml2Name), + new XAttribute("Version", assertion.Version), + new XAttribute("ID", assertion.Id.Value), + new XAttribute("IssueInstant", + assertion.IssueInstant.ToSaml2DateTimeString()), + new XElement(Saml2Namespaces.Saml2 + "Issuer", assertion.Issuer.Value)); + + if (assertion.Subject != null) + { + xml.Add(assertion.Subject.ToXElement()); + } + + if(assertion.Conditions != null) + { + xml.Add(assertion.Conditions.ToXElement()); + } + + if (assertion.Statements != null) + { + foreach (var statement in assertion.Statements) + { + xml.Add(statement.ToXElement()); + }; + } + + return xml; + } + } +} diff --git a/Kentor.AuthServices/AuthServicesClaimTypes.cs b/Sustainsys.Saml2/Saml2ClaimTypes.cs similarity index 100% rename from Kentor.AuthServices/AuthServicesClaimTypes.cs rename to Sustainsys.Saml2/Saml2ClaimTypes.cs diff --git a/Kentor.AuthServices/Saml2ConditionsExtensions.cs b/Sustainsys.Saml2/Saml2ConditionsExtensions.cs similarity index 96% rename from Kentor.AuthServices/Saml2ConditionsExtensions.cs rename to Sustainsys.Saml2/Saml2ConditionsExtensions.cs index 24a529ca8..f5f2dac0f 100644 --- a/Kentor.AuthServices/Saml2ConditionsExtensions.cs +++ b/Sustainsys.Saml2/Saml2ConditionsExtensions.cs @@ -1,44 +1,44 @@ -using System; -using System.Collections.Generic; -using System.IdentityModel.Tokens; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Xml.Linq; -using Sustainsys.Saml2.Internal; - -namespace Sustainsys.Saml2 -{ - /// - /// Extension methods for Saml2Condition - /// - public static class Saml2ConditionsExtensions - { - /// - /// Writes out the conditions as an XElement. - /// - /// Conditions to create xml for. - /// XElement - public static XElement ToXElement(this Saml2Conditions conditions) - { - if(conditions == null) - { - throw new ArgumentNullException(nameof(conditions)); - } - - var xml = new XElement(Saml2Namespaces.Saml2 + "Conditions"); - - xml.AddAttributeIfNotNullOrEmpty("NotOnOrAfter", - conditions.NotOnOrAfter?.ToSaml2DateTimeString()); - - foreach(var ar in conditions.AudienceRestrictions) - { - xml.Add(new XElement(Saml2Namespaces.Saml2 + "AudienceRestriction", - ar.Audiences.Select(a => - new XElement(Saml2Namespaces.Saml2 + "Audience", a.OriginalString)))); - } - - return xml; - } - } -} +using System; +using System.Collections.Generic; +using System.IdentityModel.Tokens; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Xml.Linq; +using Sustainsys.Saml2.Internal; + +namespace Sustainsys.Saml2 +{ + /// + /// Extension methods for Saml2Condition + /// + public static class Saml2ConditionsExtensions + { + /// + /// Writes out the conditions as an XElement. + /// + /// Conditions to create xml for. + /// XElement + public static XElement ToXElement(this Saml2Conditions conditions) + { + if(conditions == null) + { + throw new ArgumentNullException(nameof(conditions)); + } + + var xml = new XElement(Saml2Namespaces.Saml2 + "Conditions"); + + xml.AddAttributeIfNotNullOrEmpty("NotOnOrAfter", + conditions.NotOnOrAfter?.ToSaml2DateTimeString()); + + foreach(var ar in conditions.AudienceRestrictions) + { + xml.Add(new XElement(Saml2Namespaces.Saml2 + "AudienceRestriction", + ar.Audiences.Select(a => + new XElement(Saml2Namespaces.Saml2 + "Audience", a.OriginalString)))); + } + + return xml; + } + } +} diff --git a/Kentor.AuthServices/Saml2NameIdExtensions.cs b/Sustainsys.Saml2/Saml2NameIdExtensions.cs similarity index 100% rename from Kentor.AuthServices/Saml2NameIdExtensions.cs rename to Sustainsys.Saml2/Saml2NameIdExtensions.cs diff --git a/Kentor.AuthServices/Saml2Namespaces.cs b/Sustainsys.Saml2/Saml2Namespaces.cs similarity index 97% rename from Kentor.AuthServices/Saml2Namespaces.cs rename to Sustainsys.Saml2/Saml2Namespaces.cs index ab4bcde5e..6133bf489 100644 --- a/Kentor.AuthServices/Saml2Namespaces.cs +++ b/Sustainsys.Saml2/Saml2Namespaces.cs @@ -1,87 +1,87 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Xml; -using System.Xml.Linq; - -namespace Sustainsys.Saml2 -{ - /// - /// SAML2 namespace constants. - /// - public static class Saml2Namespaces - { - /// - /// Namespace of the SAML2 protocol. - /// - public const string Saml2PName = "urn:oasis:names:tc:SAML:2.0:protocol"; - - /// - /// Namespace of the SAML2 protocol. - /// - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")] - public static readonly XNamespace Saml2P = XNamespace.Get(Saml2PName); - - /// - /// Namespace Uri of Saml2 protocol. - /// - public static readonly Uri Saml2PUri = new Uri(Saml2PName); - - /// - /// Namespace of SAML2 assertions. - /// - public const string Saml2Name = "urn:oasis:names:tc:SAML:2.0:assertion"; - - /// - /// Namespace of SAML2 assertions. - /// - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")] - public static readonly XNamespace Saml2 = XNamespace.Get(Saml2Name); - - /// - /// Namespace Uri of SAML2 assertions. - /// - public static readonly Uri Saml2Uri = new Uri(Saml2Name); - - /// - /// Namespace of SAML2 Metadata. - /// - public const string Saml2MetadataName = "urn:oasis:names:tc:SAML:2.0:metadata"; - - /// - /// Namespace of SAML2 Metadata. - /// - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")] - public static readonly XNamespace Saml2Metadata = XNamespace.Get(Saml2MetadataName); - - /// - /// Namespace for idp discovery protocol extension. - /// - public const string Saml2IdpDiscoveryName = "urn:oasis:names:tc:SAML:profiles:SSO:idp-discovery-protocol"; - - /// - /// Namespace for idp discovery protocol extension. - /// - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")] - public static readonly XNamespace Saml2IdpDiscovery = XNamespace.Get(Saml2IdpDiscoveryName); - - /// - /// Namespace for Xml schema instance. - /// - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")] - public static readonly XNamespace XmlSchemaInstance = XNamespace.Get(System.Xml.Schema.XmlSchema.InstanceNamespace); - - /// - /// Namespace for Soap envelope. - /// - public const string SoapEnvelopeName = "http://schemas.xmlsoap.org/soap/envelope/"; - - /// - /// Namespace for Soap envelope. - /// - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")] - public static readonly XNamespace SoapEnvelope = XNamespace.Get(SoapEnvelopeName); - } -} +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Xml; +using System.Xml.Linq; + +namespace Sustainsys.Saml2 +{ + /// + /// SAML2 namespace constants. + /// + public static class Saml2Namespaces + { + /// + /// Namespace of the SAML2 protocol. + /// + public const string Saml2PName = "urn:oasis:names:tc:SAML:2.0:protocol"; + + /// + /// Namespace of the SAML2 protocol. + /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")] + public static readonly XNamespace Saml2P = XNamespace.Get(Saml2PName); + + /// + /// Namespace Uri of Saml2 protocol. + /// + public static readonly Uri Saml2PUri = new Uri(Saml2PName); + + /// + /// Namespace of SAML2 assertions. + /// + public const string Saml2Name = "urn:oasis:names:tc:SAML:2.0:assertion"; + + /// + /// Namespace of SAML2 assertions. + /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")] + public static readonly XNamespace Saml2 = XNamespace.Get(Saml2Name); + + /// + /// Namespace Uri of SAML2 assertions. + /// + public static readonly Uri Saml2Uri = new Uri(Saml2Name); + + /// + /// Namespace of SAML2 Metadata. + /// + public const string Saml2MetadataName = "urn:oasis:names:tc:SAML:2.0:metadata"; + + /// + /// Namespace of SAML2 Metadata. + /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")] + public static readonly XNamespace Saml2Metadata = XNamespace.Get(Saml2MetadataName); + + /// + /// Namespace for idp discovery protocol extension. + /// + public const string Saml2IdpDiscoveryName = "urn:oasis:names:tc:SAML:profiles:SSO:idp-discovery-protocol"; + + /// + /// Namespace for idp discovery protocol extension. + /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")] + public static readonly XNamespace Saml2IdpDiscovery = XNamespace.Get(Saml2IdpDiscoveryName); + + /// + /// Namespace for Xml schema instance. + /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")] + public static readonly XNamespace XmlSchemaInstance = XNamespace.Get(System.Xml.Schema.XmlSchema.InstanceNamespace); + + /// + /// Namespace for Soap envelope. + /// + public const string SoapEnvelopeName = "http://schemas.xmlsoap.org/soap/envelope/"; + + /// + /// Namespace for Soap envelope. + /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")] + public static readonly XNamespace SoapEnvelope = XNamespace.Get(SoapEnvelopeName); + } +} diff --git a/Kentor.AuthServices/Saml2StatementExtension.cs b/Sustainsys.Saml2/Saml2StatementExtension.cs similarity index 97% rename from Kentor.AuthServices/Saml2StatementExtension.cs rename to Sustainsys.Saml2/Saml2StatementExtension.cs index 330bdada9..0d773fc46 100644 --- a/Kentor.AuthServices/Saml2StatementExtension.cs +++ b/Sustainsys.Saml2/Saml2StatementExtension.cs @@ -1,83 +1,83 @@ -using System; -using System.Collections.Generic; -using System.IdentityModel.Tokens; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Xml.Linq; -using Sustainsys.Saml2.Internal; - -namespace Sustainsys.Saml2 -{ - /// - /// Extension methods for Saml2Statement - /// - public static class Saml2StatementExtension - { - /// - /// Writes out the statement as an XElement. - /// - /// Statement to create xml for. - /// XElement - public static XElement ToXElement(this Saml2Statement statement) - { - if (statement == null) - { - throw new ArgumentNullException(nameof(statement)); - } - - var attributeStatement = statement as Saml2AttributeStatement; - if (attributeStatement != null) - { - return ToXElement(attributeStatement); - } - - var authnStatement = statement as Saml2AuthenticationStatement; - if(authnStatement != null) - { - return ToXElement(authnStatement); - } - - throw new NotImplementedException("Statement of type " + statement.GetType().Name + " is not supported."); - } - - private static XElement ToXElement(Saml2AuthenticationStatement authnStatement) - { - var result = new XElement(Saml2Namespaces.Saml2 + "AuthnStatement", - new XAttribute("AuthnInstant", authnStatement.AuthenticationInstant.ToSaml2DateTimeString()), - new XElement(Saml2Namespaces.Saml2 + "AuthnContext", - new XElement(Saml2Namespaces.Saml2 + "AuthnContextClassRef", - authnStatement.AuthenticationContext.ClassReference.OriginalString))); - - if(authnStatement.SessionIndex != null) - { - result.Add(new XAttribute("SessionIndex", authnStatement.SessionIndex)); - } - - return result; - } - - private static XElement ToXElement(Saml2AttributeStatement attributeStatement) - { - var element = new XElement(Saml2Namespaces.Saml2 + "AttributeStatement"); - - foreach (var attribute in attributeStatement.Attributes) - { - var attributeElement = new XElement(Saml2Namespaces.Saml2 + "Attribute", new XAttribute("Name", attribute.Name)); - - attributeElement.AddAttributeIfNotNullOrEmpty("FriendlyName", attribute.FriendlyName); - attributeElement.AddAttributeIfNotNullOrEmpty("NameFormat", attribute.NameFormat); - attributeElement.AddAttributeIfNotNullOrEmpty("OriginalIssuer", attribute.OriginalIssuer); - - foreach (var value in attribute.Values) - { - attributeElement.Add(new XElement(Saml2Namespaces.Saml2 + "AttributeValue", value)); - } - - element.Add(attributeElement); - } - - return element; - } - } -} +using System; +using System.Collections.Generic; +using System.IdentityModel.Tokens; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Xml.Linq; +using Sustainsys.Saml2.Internal; + +namespace Sustainsys.Saml2 +{ + /// + /// Extension methods for Saml2Statement + /// + public static class Saml2StatementExtension + { + /// + /// Writes out the statement as an XElement. + /// + /// Statement to create xml for. + /// XElement + public static XElement ToXElement(this Saml2Statement statement) + { + if (statement == null) + { + throw new ArgumentNullException(nameof(statement)); + } + + var attributeStatement = statement as Saml2AttributeStatement; + if (attributeStatement != null) + { + return ToXElement(attributeStatement); + } + + var authnStatement = statement as Saml2AuthenticationStatement; + if(authnStatement != null) + { + return ToXElement(authnStatement); + } + + throw new NotImplementedException("Statement of type " + statement.GetType().Name + " is not supported."); + } + + private static XElement ToXElement(Saml2AuthenticationStatement authnStatement) + { + var result = new XElement(Saml2Namespaces.Saml2 + "AuthnStatement", + new XAttribute("AuthnInstant", authnStatement.AuthenticationInstant.ToSaml2DateTimeString()), + new XElement(Saml2Namespaces.Saml2 + "AuthnContext", + new XElement(Saml2Namespaces.Saml2 + "AuthnContextClassRef", + authnStatement.AuthenticationContext.ClassReference.OriginalString))); + + if(authnStatement.SessionIndex != null) + { + result.Add(new XAttribute("SessionIndex", authnStatement.SessionIndex)); + } + + return result; + } + + private static XElement ToXElement(Saml2AttributeStatement attributeStatement) + { + var element = new XElement(Saml2Namespaces.Saml2 + "AttributeStatement"); + + foreach (var attribute in attributeStatement.Attributes) + { + var attributeElement = new XElement(Saml2Namespaces.Saml2 + "Attribute", new XAttribute("Name", attribute.Name)); + + attributeElement.AddAttributeIfNotNullOrEmpty("FriendlyName", attribute.FriendlyName); + attributeElement.AddAttributeIfNotNullOrEmpty("NameFormat", attribute.NameFormat); + attributeElement.AddAttributeIfNotNullOrEmpty("OriginalIssuer", attribute.OriginalIssuer); + + foreach (var value in attribute.Values) + { + attributeElement.Add(new XElement(Saml2Namespaces.Saml2 + "AttributeValue", value)); + } + + element.Add(attributeElement); + } + + return element; + } + } +} diff --git a/Kentor.AuthServices/Saml2SubjectExtensions.cs b/Sustainsys.Saml2/Saml2SubjectExtensions.cs similarity index 97% rename from Kentor.AuthServices/Saml2SubjectExtensions.cs rename to Sustainsys.Saml2/Saml2SubjectExtensions.cs index 846bae298..73302016d 100644 --- a/Kentor.AuthServices/Saml2SubjectExtensions.cs +++ b/Sustainsys.Saml2/Saml2SubjectExtensions.cs @@ -1,107 +1,107 @@ -using System; -using System.IdentityModel.Tokens; -using System.Xml.Linq; - -namespace Sustainsys.Saml2 -{ - /// - /// Extension methods for Saml2Subject - /// - public static class Saml2SubjectExtensions - { - /// - /// Writes out the subject as an XElement. - /// - /// The subject to create xml for. - /// XElement - public static XElement ToXElement(this Saml2Subject subject) - { - if (subject == null) - { - throw new ArgumentNullException(nameof(subject)); - } - - var element = new XElement(Saml2Namespaces.Saml2 + "Subject", - subject.NameId.ToXElement()); - - foreach (var subjectConfirmation in subject.SubjectConfirmations) - { - element.Add(subjectConfirmation.ToXElement()); - } - - if (subject.SubjectConfirmations.Count == 0) - { - // Although SubjectConfirmation is optional in the SAML core spec, it is - // mandatory in the Web Browser SSO Profile and must have a value of bearer. - element.Add(new Saml2SubjectConfirmation( - new Uri("urn:oasis:names:tc:SAML:2.0:cm:bearer")).ToXElement()); - } - - return element; - } - - /// - /// Writes out the subject confirmation as an XElement. - /// - /// - /// - /// - public static XElement ToXElement(this Saml2SubjectConfirmation subjectConfirmation) - { - if (subjectConfirmation == null) - { - throw new ArgumentNullException(nameof(subjectConfirmation)); - } - - var element = new XElement(Saml2Namespaces.Saml2 + "SubjectConfirmation", - new XAttribute("Method", subjectConfirmation.Method.OriginalString)); - - if (subjectConfirmation.SubjectConfirmationData != null) - { - element.Add(subjectConfirmation.SubjectConfirmationData.ToXElement()); - } - - return element; - } - - /// - /// Writes out the subject confirmation data as an XElement. - /// - /// - /// - /// - public static XElement ToXElement(this Saml2SubjectConfirmationData subjectConfirmationData) - { - if (subjectConfirmationData == null) - { - throw new ArgumentNullException(nameof(subjectConfirmationData)); - } - - var element = new XElement(Saml2Namespaces.Saml2 + "SubjectConfirmationData"); - - if (subjectConfirmationData.NotOnOrAfter.HasValue) - { - element.SetAttributeValue("NotOnOrAfter", - subjectConfirmationData.NotOnOrAfter.Value.ToSaml2DateTimeString()); - } - - if (subjectConfirmationData.InResponseTo != null) - { - element.SetAttributeValue("InResponseTo", subjectConfirmationData.InResponseTo.Value); - } - - if (subjectConfirmationData.Recipient != null) - { - element.SetAttributeValue("Recipient", subjectConfirmationData.Recipient.OriginalString); - } - - if (subjectConfirmationData.NotBefore.HasValue) - { - element.SetAttributeValue("NotBefore", - subjectConfirmationData.NotBefore.Value.ToSaml2DateTimeString()); - } - - return element; - } - } -} +using System; +using System.IdentityModel.Tokens; +using System.Xml.Linq; + +namespace Sustainsys.Saml2 +{ + /// + /// Extension methods for Saml2Subject + /// + public static class Saml2SubjectExtensions + { + /// + /// Writes out the subject as an XElement. + /// + /// The subject to create xml for. + /// XElement + public static XElement ToXElement(this Saml2Subject subject) + { + if (subject == null) + { + throw new ArgumentNullException(nameof(subject)); + } + + var element = new XElement(Saml2Namespaces.Saml2 + "Subject", + subject.NameId.ToXElement()); + + foreach (var subjectConfirmation in subject.SubjectConfirmations) + { + element.Add(subjectConfirmation.ToXElement()); + } + + if (subject.SubjectConfirmations.Count == 0) + { + // Although SubjectConfirmation is optional in the SAML core spec, it is + // mandatory in the Web Browser SSO Profile and must have a value of bearer. + element.Add(new Saml2SubjectConfirmation( + new Uri("urn:oasis:names:tc:SAML:2.0:cm:bearer")).ToXElement()); + } + + return element; + } + + /// + /// Writes out the subject confirmation as an XElement. + /// + /// + /// + /// + public static XElement ToXElement(this Saml2SubjectConfirmation subjectConfirmation) + { + if (subjectConfirmation == null) + { + throw new ArgumentNullException(nameof(subjectConfirmation)); + } + + var element = new XElement(Saml2Namespaces.Saml2 + "SubjectConfirmation", + new XAttribute("Method", subjectConfirmation.Method.OriginalString)); + + if (subjectConfirmation.SubjectConfirmationData != null) + { + element.Add(subjectConfirmation.SubjectConfirmationData.ToXElement()); + } + + return element; + } + + /// + /// Writes out the subject confirmation data as an XElement. + /// + /// + /// + /// + public static XElement ToXElement(this Saml2SubjectConfirmationData subjectConfirmationData) + { + if (subjectConfirmationData == null) + { + throw new ArgumentNullException(nameof(subjectConfirmationData)); + } + + var element = new XElement(Saml2Namespaces.Saml2 + "SubjectConfirmationData"); + + if (subjectConfirmationData.NotOnOrAfter.HasValue) + { + element.SetAttributeValue("NotOnOrAfter", + subjectConfirmationData.NotOnOrAfter.Value.ToSaml2DateTimeString()); + } + + if (subjectConfirmationData.InResponseTo != null) + { + element.SetAttributeValue("InResponseTo", subjectConfirmationData.InResponseTo.Value); + } + + if (subjectConfirmationData.Recipient != null) + { + element.SetAttributeValue("Recipient", subjectConfirmationData.Recipient.OriginalString); + } + + if (subjectConfirmationData.NotBefore.HasValue) + { + element.SetAttributeValue("NotBefore", + subjectConfirmationData.NotBefore.Value.ToSaml2DateTimeString()); + } + + return element; + } + } +} diff --git a/Kentor.AuthServices/ServiceCertificate.cs b/Sustainsys.Saml2/ServiceCertificate.cs similarity index 100% rename from Kentor.AuthServices/ServiceCertificate.cs rename to Sustainsys.Saml2/ServiceCertificate.cs diff --git a/Kentor.AuthServices/StoredRequestState.cs b/Sustainsys.Saml2/StoredRequestState.cs similarity index 100% rename from Kentor.AuthServices/StoredRequestState.cs rename to Sustainsys.Saml2/StoredRequestState.cs diff --git a/Kentor.AuthServices/Kentor.AuthServices.csproj b/Sustainsys.Saml2/Sustainsys.Saml2.csproj similarity index 91% rename from Kentor.AuthServices/Kentor.AuthServices.csproj rename to Sustainsys.Saml2/Sustainsys.Saml2.csproj index 9388af880..a2334160c 100644 --- a/Kentor.AuthServices/Kentor.AuthServices.csproj +++ b/Sustainsys.Saml2/Sustainsys.Saml2.csproj @@ -1,192 +1,192 @@ - - - - - Release - AnyCPU - {93BA675E-A159-4701-B68B-C4B81015C556} - Library - Properties - Kentor.AuthServices - Kentor.AuthServices - v4.5 - 512 - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - true - ..\Kentor.AuthServices.ruleset - bin\Debug\Kentor.AuthServices.XML - - - full - true - bin\Release\ - TRACE - prompt - 4 - bin\Release\Kentor.AuthServices.XML - true - - - - - - - - - - - - - - - - - - VersionInfo.cs - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CustomDictionary.xml - - - - + + + + + Release + AnyCPU + {93BA675E-A159-4701-B68B-C4B81015C556} + Library + Properties + Sustainsys.Saml2 + Sustainsys.Saml2 + v4.5 + 512 + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + true + ..\Sustainsys.Saml2.ruleset + bin\Debug\Sustainsys.Saml2.XML + + + full + true + bin\Release\ + TRACE + prompt + 4 + bin\Release\Sustainsys.Saml2.XML + true + + + + + + + + + + + + + + + + + + VersionInfo.cs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + CustomDictionary.xml + + + + \ No newline at end of file diff --git a/Kentor.AuthServices/TrustLevel.cs b/Sustainsys.Saml2/TrustLevel.cs similarity index 100% rename from Kentor.AuthServices/TrustLevel.cs rename to Sustainsys.Saml2/TrustLevel.cs diff --git a/Kentor.AuthServices/WebSSO/AcsCommand.cs b/Sustainsys.Saml2/WebSSO/AcsCommand.cs similarity index 100% rename from Kentor.AuthServices/WebSSO/AcsCommand.cs rename to Sustainsys.Saml2/WebSSO/AcsCommand.cs diff --git a/Kentor.AuthServices/WebSSO/Cacheability.cs b/Sustainsys.Saml2/WebSSO/Cacheability.cs similarity index 100% rename from Kentor.AuthServices/WebSSO/Cacheability.cs rename to Sustainsys.Saml2/WebSSO/Cacheability.cs diff --git a/Kentor.AuthServices/WebSSO/CommandFactory.cs b/Sustainsys.Saml2/WebSSO/CommandFactory.cs similarity index 100% rename from Kentor.AuthServices/WebSSO/CommandFactory.cs rename to Sustainsys.Saml2/WebSSO/CommandFactory.cs diff --git a/Kentor.AuthServices/WebSSO/CommandResult.cs b/Sustainsys.Saml2/WebSSO/CommandResult.cs similarity index 100% rename from Kentor.AuthServices/WebSSO/CommandResult.cs rename to Sustainsys.Saml2/WebSSO/CommandResult.cs diff --git a/Kentor.AuthServices/WebSSO/HttpRequestData.cs b/Sustainsys.Saml2/WebSSO/HttpRequestData.cs similarity index 100% rename from Kentor.AuthServices/WebSSO/HttpRequestData.cs rename to Sustainsys.Saml2/WebSSO/HttpRequestData.cs diff --git a/Kentor.AuthServices/WebSSO/ICommand.cs b/Sustainsys.Saml2/WebSSO/ICommand.cs similarity index 100% rename from Kentor.AuthServices/WebSSO/ICommand.cs rename to Sustainsys.Saml2/WebSSO/ICommand.cs diff --git a/Kentor.AuthServices/WebSSO/LogOutCommand.cs b/Sustainsys.Saml2/WebSSO/LogOutCommand.cs similarity index 100% rename from Kentor.AuthServices/WebSSO/LogOutCommand.cs rename to Sustainsys.Saml2/WebSSO/LogOutCommand.cs diff --git a/Kentor.AuthServices/WebSSO/MetadataCommand.cs b/Sustainsys.Saml2/WebSSO/MetadataCommand.cs similarity index 100% rename from Kentor.AuthServices/WebSSO/MetadataCommand.cs rename to Sustainsys.Saml2/WebSSO/MetadataCommand.cs diff --git a/Kentor.AuthServices/WebSSO/NotFoundCommand.cs b/Sustainsys.Saml2/WebSSO/NotFoundCommand.cs similarity index 100% rename from Kentor.AuthServices/WebSSO/NotFoundCommand.cs rename to Sustainsys.Saml2/WebSSO/NotFoundCommand.cs diff --git a/Kentor.AuthServices/WebSSO/Saml2ArtifactBinding.cs b/Sustainsys.Saml2/WebSSO/Saml2ArtifactBinding.cs similarity index 100% rename from Kentor.AuthServices/WebSSO/Saml2ArtifactBinding.cs rename to Sustainsys.Saml2/WebSSO/Saml2ArtifactBinding.cs diff --git a/Kentor.AuthServices/WebSSO/Saml2Binding.cs b/Sustainsys.Saml2/WebSSO/Saml2Binding.cs similarity index 100% rename from Kentor.AuthServices/WebSSO/Saml2Binding.cs rename to Sustainsys.Saml2/WebSSO/Saml2Binding.cs diff --git a/Kentor.AuthServices/WebSSO/Saml2BindingType.cs b/Sustainsys.Saml2/WebSSO/Saml2BindingType.cs similarity index 100% rename from Kentor.AuthServices/WebSSO/Saml2BindingType.cs rename to Sustainsys.Saml2/WebSSO/Saml2BindingType.cs diff --git a/Kentor.AuthServices/WebSSO/Saml2PostBinding.cs b/Sustainsys.Saml2/WebSSO/Saml2PostBinding.cs similarity index 100% rename from Kentor.AuthServices/WebSSO/Saml2PostBinding.cs rename to Sustainsys.Saml2/WebSSO/Saml2PostBinding.cs diff --git a/Kentor.AuthServices/WebSSO/Saml2RedirectBinding.cs b/Sustainsys.Saml2/WebSSO/Saml2RedirectBinding.cs similarity index 100% rename from Kentor.AuthServices/WebSSO/Saml2RedirectBinding.cs rename to Sustainsys.Saml2/WebSSO/Saml2RedirectBinding.cs diff --git a/Kentor.AuthServices/WebSSO/AuthServicesUrls.cs b/Sustainsys.Saml2/WebSSO/Saml2Urls.cs similarity index 100% rename from Kentor.AuthServices/WebSSO/AuthServicesUrls.cs rename to Sustainsys.Saml2/WebSSO/Saml2Urls.cs diff --git a/Kentor.AuthServices/WebSSO/SignInCommand.cs b/Sustainsys.Saml2/WebSSO/SignInCommand.cs similarity index 100% rename from Kentor.AuthServices/WebSSO/SignInCommand.cs rename to Sustainsys.Saml2/WebSSO/SignInCommand.cs diff --git a/Kentor.AuthServices/XmlHelpers.cs b/Sustainsys.Saml2/XmlHelpers.cs similarity index 100% rename from Kentor.AuthServices/XmlHelpers.cs rename to Sustainsys.Saml2/XmlHelpers.cs diff --git a/Tests/AspNetCore2.Tests/AspNetCore2.Tests.csproj b/Tests/AspNetCore2.Tests/AspNetCore2.Tests.csproj index 4a4b1577d..299b5ca71 100644 --- a/Tests/AspNetCore2.Tests/AspNetCore2.Tests.csproj +++ b/Tests/AspNetCore2.Tests/AspNetCore2.Tests.csproj @@ -114,9 +114,9 @@
- + {93BA675E-A159-4701-B68B-C4B81015C556} - Kentor.AuthServices + Sustainsys.Saml2 {0a1a7e8c-838c-4114-894b-564592417afa} diff --git a/Tests/HttpModule.Tests/HttpModule.Tests.csproj b/Tests/HttpModule.Tests/HttpModule.Tests.csproj index f6286a360..da7405bb3 100644 --- a/Tests/HttpModule.Tests/HttpModule.Tests.csproj +++ b/Tests/HttpModule.Tests/HttpModule.Tests.csproj @@ -7,7 +7,7 @@ {4D3EADFB-93E9-4F66-BD61-FBAC9E30A294} Library Properties - Kentor.AuthServices.HttpModule.Tests + Sustainsys.Saml2.HttpModule.Tests HttpModule.Tests v4.6.1 512 @@ -61,7 +61,7 @@ - + @@ -72,17 +72,17 @@ - + {86a588e8-2e2d-4394-9545-24d8ea939cf2} - Kentor.AuthServices.HttpModule + Sustainsys.Saml2.HttpModule {CF1E517E-B2FE-48E1-8BB9-4D9981695C47} TestHelpers - + {93BA675E-A159-4701-B68B-C4B81015C556} - Kentor.AuthServices + Sustainsys.Saml2 diff --git a/Tests/HttpModule.Tests/AuthServicesUrlsTests.cs b/Tests/HttpModule.Tests/Saml2UrlsTests.cs similarity index 100% rename from Tests/HttpModule.Tests/AuthServicesUrlsTests.cs rename to Tests/HttpModule.Tests/Saml2UrlsTests.cs diff --git a/Tests/Kentor.AuthServices.IntegrationTests/Kentor.AuthServices.IntegrationTests.csproj b/Tests/Kentor.AuthServices.IntegrationTests/Kentor.AuthServices.IntegrationTests.csproj index 76e9cdd17..5d23c56e5 100644 --- a/Tests/Kentor.AuthServices.IntegrationTests/Kentor.AuthServices.IntegrationTests.csproj +++ b/Tests/Kentor.AuthServices.IntegrationTests/Kentor.AuthServices.IntegrationTests.csproj @@ -6,8 +6,8 @@ {6139CB5B-88C1-45F8-B151-07985920295A} Library Properties - Kentor.AuthServices.IntegrationTests - Kentor.AuthServices.IntegrationTests + Sustainsys.Saml2.IntegrationTests + Sustainsys.Saml2.IntegrationTests v4.5 512 {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} diff --git a/Tests/Kentor.AuthServices.IntegrationTests/Kentor.AuthServices.IntegrationTests.sln b/Tests/Kentor.AuthServices.IntegrationTests/Kentor.AuthServices.IntegrationTests.sln index 57f26e580..ae5618124 100644 --- a/Tests/Kentor.AuthServices.IntegrationTests/Kentor.AuthServices.IntegrationTests.sln +++ b/Tests/Kentor.AuthServices.IntegrationTests/Kentor.AuthServices.IntegrationTests.sln @@ -3,7 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 2013 VisualStudioVersion = 12.0.31101.0 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kentor.AuthServices.IntegrationTests", "Kentor.AuthServices.IntegrationTests.csproj", "{6139CB5B-88C1-45F8-B151-07985920295A}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sustainsys.Saml2.IntegrationTests", "Sustainsys.Saml2.IntegrationTests.csproj", "{6139CB5B-88C1-45F8-B151-07985920295A}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/Tests/Kentor.AuthServices.IntegrationTests/MetadataTests.cs b/Tests/Kentor.AuthServices.IntegrationTests/MetadataTests.cs index 762ed0698..f21f75957 100644 --- a/Tests/Kentor.AuthServices.IntegrationTests/MetadataTests.cs +++ b/Tests/Kentor.AuthServices.IntegrationTests/MetadataTests.cs @@ -4,7 +4,7 @@ using FluentAssertions; using System.Xml.Linq; -namespace Kentor.AuthServices.IntegrationTests +namespace Sustainsys.Saml2.IntegrationTests { [TestClass] public class MetadataTests @@ -12,7 +12,7 @@ public class MetadataTests [TestMethod] public void Metadata_GetMetadata_Saml2AuthenticationModule() { - var url = "http://localhost:17009/SamplePath/AuthServices/"; + var url = "http://localhost:17009/SamplePath/Saml2/"; TestMetadata(url); } @@ -32,7 +32,7 @@ private static void TestMetadata(string url) [TestMethod] public void Metadata_GetMetadata_Mvc() { - var url = "http://localhost:2181/AuthServices/"; + var url = "http://localhost:2181/Saml2/"; TestMetadata(url); } @@ -40,7 +40,7 @@ public void Metadata_GetMetadata_Mvc() [TestMethod] public void Metadata_GetMetadata_Owin() { - var url = "http://localhost:57294/AuthServices"; + var url = "http://localhost:57294/Saml2"; TestMetadata(url); } diff --git a/Tests/Kentor.AuthServices.IntegrationTests/Properties/AssemblyInfo.cs b/Tests/Kentor.AuthServices.IntegrationTests/Properties/AssemblyInfo.cs index 1b5bb471b..0da838e01 100644 --- a/Tests/Kentor.AuthServices.IntegrationTests/Properties/AssemblyInfo.cs +++ b/Tests/Kentor.AuthServices.IntegrationTests/Properties/AssemblyInfo.cs @@ -5,11 +5,11 @@ // General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information // associated with an assembly. -[assembly: AssemblyTitle("Kentor.AuthServices.IntegrationTests")] +[assembly: AssemblyTitle("Sustainsys.Saml2.IntegrationTests")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("Kentor.AuthServices.IntegrationTests")] +[assembly: AssemblyProduct("Sustainsys.Saml2.IntegrationTests")] [assembly: AssemblyCopyright("Copyright © 2014")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] diff --git a/Tests/Kentor.AuthServices.IntegrationTests/SignInTests.cs b/Tests/Kentor.AuthServices.IntegrationTests/SignInTests.cs index 5f2c062bf..2ef779f2e 100644 --- a/Tests/Kentor.AuthServices.IntegrationTests/SignInTests.cs +++ b/Tests/Kentor.AuthServices.IntegrationTests/SignInTests.cs @@ -2,7 +2,7 @@ using Microsoft.VisualStudio.TestTools.UnitTesting; using FluentAutomation; -namespace Kentor.AuthServices.IntegrationTests +namespace Sustainsys.Saml2.IntegrationTests { [TestClass] public class SignInTests : FluentTest @@ -18,8 +18,8 @@ public void SignInTestsInitialize() public void SignInAndOut_IdpInitiated_MVC() { I.Open("http://localhost:52071/") - .Enter("http://localhost:2181/AuthServices/Acs").In("#AssertionModel_AssertionConsumerServiceUrl") - .Enter("http://localhost:2181/AuthServices").In("#AssertionModel_Audience") + .Enter("http://localhost:2181/Saml2/Acs").In("#AssertionModel_AssertionConsumerServiceUrl") + .Enter("http://localhost:2181/Saml2").In("#AssertionModel_Audience") .Click("#binding_artifact") .Click("#submit"); @@ -29,7 +29,7 @@ public void SignInAndOut_IdpInitiated_MVC() I.Open("http://localhost:52071/Logout") .Enter("JohnDoe").In("#NameId") - .Enter("http://localhost:2181/AuthServices/Logout").In("#DestinationUrl") + .Enter("http://localhost:2181/Saml2/Logout").In("#DestinationUrl") .Click("#submit") .Assert.Text("urn:oasis:names:tc:SAML:2.0:status:Success").In("#status"); @@ -41,14 +41,14 @@ public void SignInAndOut_IdpInitiated_MVC() public void SignInAndOut_IdpInitiated_HttpModule() { I.Open("http://localhost:52071/") - .Enter("http://localhost:17009/SamplePath/AuthServices/Acs").In("#AssertionModel_AssertionConsumerServiceUrl") - .Enter("http://localhost:17009/SamplePath/AuthServices").In("#AssertionModel_Audience") + .Enter("http://localhost:17009/SamplePath/Saml2/Acs").In("#AssertionModel_AssertionConsumerServiceUrl") + .Enter("http://localhost:17009/SamplePath/Saml2").In("#AssertionModel_Audience") .Click("#submit") .Assert.Text("JohnDoe").In("tbody tr td:nth-child(2)"); I.Open("http://localhost:52071/Logout") .Enter("JohnDoe").In("#NameId") - .Enter("http://localhost:17009/SamplePath/AuthServices/Logout").In("#DestinationUrl") + .Enter("http://localhost:17009/SamplePath/Saml2/Logout").In("#DestinationUrl") .Click("#submit") .Assert.Text("urn:oasis:names:tc:SAML:2.0:status:Success").In("#status"); @@ -61,10 +61,10 @@ public void SignInAndOut_SPInitiated_MVC_via_DiscoveryService() { I.Open("http://localhost:2181") .Click("a[href=\"/Home/Secure\"]") - .Assert.Text(s => s.StartsWith("http://localhost:2181/AuthServices/SignIn?ReturnUrl=%2FHome%2FSecure&RelayState=")).In("#return"); + .Assert.Text(s => s.StartsWith("http://localhost:2181/Saml2/SignIn?ReturnUrl=%2FHome%2FSecure&RelayState=")).In("#return"); I.Click("#submit") - .Assert.Text("http://localhost:2181/AuthServices/Acs").In("#AssertionModel_AssertionConsumerServiceUrl"); + .Assert.Text("http://localhost:2181/Saml2/Acs").In("#AssertionModel_AssertionConsumerServiceUrl"); I.Assert.False(() => string.IsNullOrEmpty(I.Find("#AssertionModel_InResponseTo").Element.Value)); @@ -73,10 +73,10 @@ public void SignInAndOut_SPInitiated_MVC_via_DiscoveryService() I.Assert.Text("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier - JohnDoe").In(".body-content ul li:first-child"); - I.Click("a[href=\"/AuthServices/Logout\"") + I.Click("a[href=\"/Saml2/Logout\"") .Wait(2); - I.Enter("http://localhost:2181/AuthServices/Logout").In("#DestinationUrl") + I.Enter("http://localhost:2181/Saml2/Logout").In("#DestinationUrl") .Click("#submit") .Wait(2); @@ -87,11 +87,11 @@ public void SignInAndOut_SPInitiated_MVC_via_DiscoveryService() public void SignInAndOut_SPInitiated_HttpModule_via_DiscoveryService() { I.Open("http://localhost:17009/SamplePath") - .Click("a[href=\"/SamplePath/AuthServices/SignIn\"]") - .Assert.Text(s => s.StartsWith("http://localhost:17009/SamplePath/AuthServices/SignIn?RelayState=")).In("#return"); + .Click("a[href=\"/SamplePath/Saml2/SignIn\"]") + .Assert.Text(s => s.StartsWith("http://localhost:17009/SamplePath/Saml2/SignIn?RelayState=")).In("#return"); I.Click("#submit") - .Assert.Text("http://localhost:17009/SamplePath/AuthServices/Acs").In("#AssertionModel_AssertionConsumerServiceUrl"); + .Assert.Text("http://localhost:17009/SamplePath/Saml2/Acs").In("#AssertionModel_AssertionConsumerServiceUrl"); I.Assert.False(() => string.IsNullOrEmpty(I.Find("#AssertionModel_InResponseTo").Element.Value)); @@ -100,7 +100,7 @@ public void SignInAndOut_SPInitiated_HttpModule_via_DiscoveryService() I.Click("#logout"); - I.Enter("http://localhost:17009/SamplePath/AuthServices/Logout").In("#DestinationUrl") + I.Enter("http://localhost:17009/SamplePath/Saml2/Logout").In("#DestinationUrl") .Click("#submit"); I.Assert.Text("not signed in").In("#status"); @@ -110,17 +110,17 @@ public void SignInAndOut_SPInitiated_HttpModule_via_DiscoveryService() [TestMethod] public void SignIn_AuthnRequest_MVC_SpecificIdp() { - I.Open("http://localhost:2181/AuthServices/SignIn?idp=http%3a%2f%2fstubidp.kentor.se%2fMetadata") - .Assert.Url(u => u.Host == "stubidp.kentor.se"); + I.Open("http://localhost:2181/Saml2/SignIn?idp=http%3a%2f%2fstubidp.Sustainsys.se%2fMetadata") + .Assert.Url(u => u.Host == "stubidp.Sustainsys.se"); } [TestMethod] public void SignInAndOut_IdpInitiated_Owin() { I.Open("http://localhost:52071/") - .Enter("http://localhost:57294/AuthServices/Acs").In("#AssertionModel_AssertionConsumerServiceUrl") + .Enter("http://localhost:57294/Saml2/Acs").In("#AssertionModel_AssertionConsumerServiceUrl") .Enter("IntegrationTestNameId").In("#AssertionModel_NameId") - .Enter("http://localhost:57294/AuthServices").In("#AssertionModel_Audience"); + .Enter("http://localhost:57294/Saml2").In("#AssertionModel_Audience"); I.Click("#submit") .Wait(1); @@ -135,7 +135,7 @@ public void SignInAndOut_IdpInitiated_Owin() I.Open("http://localhost:52071/Logout") .Enter("IntegrationTestNameId").In("#NameId") - .Enter("http://localhost:57294/AuthServices/Logout").In("#DestinationUrl") + .Enter("http://localhost:57294/Saml2/Logout").In("#DestinationUrl") .Click("#submit") .Assert.Text("urn:oasis:names:tc:SAML:2.0:status:Success").In("#status"); @@ -147,11 +147,11 @@ public void SignInAndOut_IdpInitiated_Owin() public void SignInAndOut_SPInitiated_Owin_via_DiscoveryService() { I.Open("http://localhost:57294/Account/Login") - .Click("#KentorAuthServices") - .Assert.Text(s => s.StartsWith("http://localhost:57294/AuthServices/SignIn?ReturnUrl=%2FAccount%2FExternalLoginCallback&RelayState=")).In("#return"); + .Click("#SustainsysSaml2") + .Assert.Text(s => s.StartsWith("http://localhost:57294/Saml2/SignIn?ReturnUrl=%2FAccount%2FExternalLoginCallback&RelayState=")).In("#return"); I.Click("#submit") - .Assert.Text("http://localhost:57294/AuthServices/Acs").In("#AssertionModel_AssertionConsumerServiceUrl"); + .Assert.Text("http://localhost:57294/Saml2/Acs").In("#AssertionModel_AssertionConsumerServiceUrl"); I.Assert.False(() => string.IsNullOrEmpty(I.Find("#AssertionModel_InResponseTo").Element.Value)); @@ -169,7 +169,7 @@ public void SignInAndOut_SPInitiated_Owin_via_DiscoveryService() I.Click("#logout").Wait(1); - I.Enter("http://localhost:57294/AuthServices/Logout").In("#DestinationUrl") + I.Enter("http://localhost:57294/Saml2/Logout").In("#DestinationUrl") .Click("#submit"); I.Assert.Text("not signed in").In("#status"); diff --git a/Tests/Mvc.Tests/Mvc.Tests.csproj b/Tests/Mvc.Tests/Mvc.Tests.csproj index b3d92a104..6d9d1b3fe 100644 --- a/Tests/Mvc.Tests/Mvc.Tests.csproj +++ b/Tests/Mvc.Tests/Mvc.Tests.csproj @@ -7,7 +7,7 @@ {F09D61F6-CA41-4B73-B59E-2A5C5626F058} Library Properties - Kentor.AuthServices.Mvc.Tests + Sustainsys.Saml2.Mvc.Tests Mvc.Tests v4.6.1 512 @@ -88,7 +88,7 @@ HttpRequestBaseExtensionsTests.cs - + @@ -97,17 +97,17 @@ - + {7d32f0a3-cec8-4dc6-a096-5905ea9c3770} - Kentor.AuthServices.Mvc + Sustainsys.Saml2.Mvc {cf1e517e-b2fe-48e1-8bb9-4d9981695c47} TestHelpers - + {93BA675E-A159-4701-B68B-C4B81015C556} - Kentor.AuthServices + Sustainsys.Saml2 diff --git a/Tests/Mvc.Tests/AuthServicesControllerTests.cs b/Tests/Mvc.Tests/Saml2ControllerTests.cs similarity index 100% rename from Tests/Mvc.Tests/AuthServicesControllerTests.cs rename to Tests/Mvc.Tests/Saml2ControllerTests.cs diff --git a/Tests/Owin.Tests/Owin.Tests.csproj b/Tests/Owin.Tests/Owin.Tests.csproj index cd7da67eb..02ca6b1a2 100644 --- a/Tests/Owin.Tests/Owin.Tests.csproj +++ b/Tests/Owin.Tests/Owin.Tests.csproj @@ -7,7 +7,7 @@ {0E01A985-54CC-4190-851F-6475C7BB1A5D} Library Properties - Kentor.AuthServices.Owin.Tests + Sustainsys.Saml2.Owin.Tests Owin.Tests v4.6.2 512 @@ -74,12 +74,12 @@ - + - - - + + + @@ -93,17 +93,17 @@ - + {fa1e7723-124c-4d2d-a731-e16400b0073b} - Kentor.AuthServices.Owin + Sustainsys.Saml2.Owin {cf1e517e-b2fe-48e1-8bb9-4d9981695c47} TestHelpers - + {93BA675E-A159-4701-B68B-C4B81015C556} - Kentor.AuthServices + Sustainsys.Saml2 diff --git a/Tests/Owin.Tests/KentorAuthServicesAuthenticationExtensionsTests.cs b/Tests/Owin.Tests/Saml2AuthenticationExtensionsTests.cs similarity index 100% rename from Tests/Owin.Tests/KentorAuthServicesAuthenticationExtensionsTests.cs rename to Tests/Owin.Tests/Saml2AuthenticationExtensionsTests.cs diff --git a/Tests/Owin.Tests/KentorAuthServicesAuthenticationMiddlewareTests.cs b/Tests/Owin.Tests/Saml2AuthenticationMiddlewareTests.cs similarity index 100% rename from Tests/Owin.Tests/KentorAuthServicesAuthenticationMiddlewareTests.cs rename to Tests/Owin.Tests/Saml2AuthenticationMiddlewareTests.cs diff --git a/Tests/Owin.Tests/KentorAuthServicesAuthenticationOptionsTests.cs b/Tests/Owin.Tests/Saml2AuthenticationOptionsTests.cs similarity index 100% rename from Tests/Owin.Tests/KentorAuthServicesAuthenticationOptionsTests.cs rename to Tests/Owin.Tests/Saml2AuthenticationOptionsTests.cs diff --git a/Tests/Owin.Tests/AuthServicesUrlsTests.cs b/Tests/Owin.Tests/Saml2UrlsTests.cs similarity index 100% rename from Tests/Owin.Tests/AuthServicesUrlsTests.cs rename to Tests/Owin.Tests/Saml2UrlsTests.cs diff --git a/Tests/TestHelpers/Kentor.AuthServices.Tests.pfx b/Tests/TestHelpers/Kentor.AuthServices.Tests.pfx deleted file mode 100644 index 12422cf4f..000000000 Binary files a/Tests/TestHelpers/Kentor.AuthServices.Tests.pfx and /dev/null differ diff --git a/Tests/TestHelpers/Kentor.AuthServices.Tests2.pfx b/Tests/TestHelpers/Sustainsys.Saml2.Tests2.pfx similarity index 100% rename from Tests/TestHelpers/Kentor.AuthServices.Tests2.pfx rename to Tests/TestHelpers/Sustainsys.Saml2.Tests2.pfx diff --git a/Tests/TestHelpers/Kentor.AuthServices.TestsSignOnly.pfx b/Tests/TestHelpers/Sustainsys.Saml2.TestsSignOnly.pfx similarity index 100% rename from Tests/TestHelpers/Kentor.AuthServices.TestsSignOnly.pfx rename to Tests/TestHelpers/Sustainsys.Saml2.TestsSignOnly.pfx diff --git a/Tests/TestHelpers/TestHelpers.csproj b/Tests/TestHelpers/TestHelpers.csproj index 02bd5d685..39b387b3c 100644 --- a/Tests/TestHelpers/TestHelpers.csproj +++ b/Tests/TestHelpers/TestHelpers.csproj @@ -7,7 +7,7 @@ {CF1E517E-B2FE-48E1-8BB9-4D9981695C47} Library Properties - Kentor.AuthServices.TestHelpers + Sustainsys.Saml2.TestHelpers TestHelpers v4.6.1 512 @@ -49,13 +49,13 @@ - + PreserveNewest - + PreserveNewest - + PreserveNewest @@ -64,9 +64,9 @@ - + {93ba675e-a159-4701-b68b-c4b81015c556} - Kentor.AuthServices + Sustainsys.Saml2 diff --git a/Tests/Tests/Configuration/KentorAuthServicesSectionTests.cs b/Tests/Tests/Configuration/SustainsysSaml2SectionTests.cs similarity index 100% rename from Tests/Tests/Configuration/KentorAuthServicesSectionTests.cs rename to Tests/Tests/Configuration/SustainsysSaml2SectionTests.cs diff --git a/Tests/Tests/Exceptions/AuthServicesExceptionTests.cs b/Tests/Tests/Exceptions/Saml2ExceptionTests.cs similarity index 100% rename from Tests/Tests/Exceptions/AuthServicesExceptionTests.cs rename to Tests/Tests/Exceptions/Saml2ExceptionTests.cs diff --git a/Tests/Tests/Tests.csproj b/Tests/Tests/Tests.csproj index 224b21035..af95efe21 100644 --- a/Tests/Tests/Tests.csproj +++ b/Tests/Tests/Tests.csproj @@ -6,7 +6,7 @@ {D3334615-C970-464F-8F45-50CB53A5C0EE} Library Properties - Kentor.AuthServices.Tests + Sustainsys.Saml2.Tests Tests v4.6.2 512 @@ -172,7 +172,7 @@ - + @@ -190,8 +190,8 @@ - - + + @@ -208,9 +208,9 @@ {CF1E517E-B2FE-48E1-8BB9-4D9981695C47} TestHelpers - + {93ba675e-a159-4701-b68b-c4b81015c556} - Kentor.AuthServices + Sustainsys.Saml2 diff --git a/Tests/Tests/WebSSO/AuthServicesUrlsTests.cs b/Tests/Tests/WebSSO/Saml2UrlsTests.cs similarity index 100% rename from Tests/Tests/WebSSO/AuthServicesUrlsTests.cs rename to Tests/Tests/WebSSO/Saml2UrlsTests.cs diff --git a/doc/Configuration.md b/doc/Configuration.md index 2fc092991..b3530444c 100644 --- a/doc/Configuration.md +++ b/doc/Configuration.md @@ -58,8 +58,8 @@ read web.config, but can also be configured from code (see [Owin middleware](Owi - diff --git a/nuget/Kentor.AuthServices.HttpModule.nuspec b/nuget/Sustainsys.Saml2.HttpModule.nuspec similarity index 100% rename from nuget/Kentor.AuthServices.HttpModule.nuspec rename to nuget/Sustainsys.Saml2.HttpModule.nuspec diff --git a/nuget/Kentor.AuthServices.Mvc.nuspec b/nuget/Sustainsys.Saml2.Mvc.nuspec similarity index 100% rename from nuget/Kentor.AuthServices.Mvc.nuspec rename to nuget/Sustainsys.Saml2.Mvc.nuspec diff --git a/nuget/Kentor.AuthServices.Owin.nuspec b/nuget/Sustainsys.Saml2.Owin.nuspec similarity index 100% rename from nuget/Kentor.AuthServices.Owin.nuspec rename to nuget/Sustainsys.Saml2.Owin.nuspec diff --git a/nuget/Kentor.AuthServices.nuspec b/nuget/Sustainsys.Saml2.nuspec similarity index 100% rename from nuget/Kentor.AuthServices.nuspec rename to nuget/Sustainsys.Saml2.nuspec