diff --git a/src/Core/Enums/Saml2BindingType.cs b/src/Core/Enums/Saml2BindingType.cs new file mode 100644 index 000000000..be9ed1e31 --- /dev/null +++ b/src/Core/Enums/Saml2BindingType.cs @@ -0,0 +1,9 @@ +namespace Bit.Core.Enums +{ + public enum Saml2BindingType : byte + { + HttpRedirect = 1, + HttpPost = 2, + Artifact = 4 + } +} diff --git a/src/Core/Enums/SsoType.cs b/src/Core/Enums/SsoType.cs new file mode 100644 index 000000000..3c1884bd7 --- /dev/null +++ b/src/Core/Enums/SsoType.cs @@ -0,0 +1,8 @@ +namespace Bit.Core.Enums +{ + public enum SsoType : byte + { + OpenIdConnect = 1, + Saml2 = 2, + } +} diff --git a/src/Core/GlobalSettings.cs b/src/Core/GlobalSettings.cs index b9442e644..17a58a59b 100644 --- a/src/Core/GlobalSettings.cs +++ b/src/Core/GlobalSettings.cs @@ -279,18 +279,6 @@ namespace Bit.Core public class SsoSettings { public int CacheLifetimeInSeconds { get; set; } = 60; - public virtual SamlSettings Saml { get; set; } = new SamlSettings(); - - public class SamlSettings - { - public Saml2NameIdFormat NameIdFormat { get; set; } = - Saml2NameIdFormat.Persistent; - public bool WantAssertionsSigned { get; set; } - public string OutboundSigningAlgorithm { get; set; } - public Saml2SigningBehavior SigningBehavior { get; set; } = - Saml2SigningBehavior.IfIdpWantAuthnRequestsSigned; - public bool ValidateCertificates { get; set; } - } } } } diff --git a/src/Core/Models/Data/SsoConfigurationData.cs b/src/Core/Models/Data/SsoConfigurationData.cs new file mode 100644 index 000000000..a07e54faf --- /dev/null +++ b/src/Core/Models/Data/SsoConfigurationData.cs @@ -0,0 +1,70 @@ +using System; +using Bit.Core.Enums; +using Bit.Core.Sso; + +namespace Bit.Core.Models.Data +{ + public class SsoConfigurationData + { + private const string _oidcSigninPath = "/oidc-signin"; + private const string _oidcSignedOutPath = "/oidc-signedout"; + private const string _saml2ModulePath = "/saml2"; + + public SsoType ConfigType { get; set; } + + // OIDC + public string Authority { get; set; } + public string ClientId { get; set; } + public string ClientSecret { get; set; } + public string MetadataAddress { get; set; } + public bool GetClaimsFromUserInfoEndpoint { get; set; } + + // SAML2 IDP + public string IdpEntityId { get; set; } + public string IdpSingleSignOnServiceUrl { get; set; } + public string IdpSingleLogoutServiceUrl { get; set; } + public string IdpX509PublicCert { get; set; } + public Saml2BindingType IdpBindingType { get; set; } + public bool IdpAllowUnsolicitedAuthnResponse { get; set; } + public string IdpArtifactResolutionServiceUrl { get; set; } + public bool IdpDisableOutboundLogoutRequests { get; set; } + public string IdpOutboundSigningAlgorithm { get; set; } + public bool IdpWantAuthnRequestsSigned { get; set; } + + // SAML2 SP + public Saml2NameIdFormat SpNameIdFormat { get; set; } = Saml2NameIdFormat.Persistent; + public string SpOutboundSigningAlgorithm { get; set; } = SamlSigningAlgorithms.Sha256; + public Saml2SigningBehavior SpSigningBehavior { get; set; } = Saml2SigningBehavior.IfIdpWantAuthnRequestsSigned; + public bool SpWantAssertionsSigned { get; set; } + public bool SpValidateCertificates { get; set; } + + public string BuildCallbackPath(string ssoUri = null) + { + return BuildSsoUrl(_oidcSigninPath, ssoUri); + } + + public string BuildSignedOutCallbackPath(string ssoUri = null) + { + return BuildSsoUrl(_oidcSignedOutPath, ssoUri); + } + + public string BuildSaml2ModulePath(string ssoUri = null) + { + return BuildSsoUrl(_saml2ModulePath, ssoUri); + } + + private string BuildSsoUrl(string relativePath, string ssoUri) + { + if (string.IsNullOrWhiteSpace(ssoUri) || + !Uri.IsWellFormedUriString(ssoUri, UriKind.Absolute)) + { + return relativePath; + } + if (Uri.TryCreate(string.Concat(ssoUri.TrimEnd('/'), relativePath), UriKind.Absolute, out var newUri)) + { + return newUri.ToString(); + } + return relativePath; + } + } +} diff --git a/src/Core/Resources/SharedResources.en.resx b/src/Core/Resources/SharedResources.en.resx index 16b5d096f..6c692cad2 100644 --- a/src/Core/Resources/SharedResources.en.resx +++ b/src/Core/Resources/SharedResources.en.resx @@ -265,6 +265,9 @@ SP Entity ID + + Validate Certificates + Name ID Format @@ -311,7 +314,7 @@ Public Key - Sign Assertions + Want Assertions Signed Signing Algorithm @@ -430,4 +433,13 @@ You are now being returned to the application. Once complete, you may close this tab. + + If IdP Wants Authn Requests Signed + + + Always + + + Never + diff --git a/src/Core/Sso/SamlSigningAlgorithms.cs b/src/Core/Sso/SamlSigningAlgorithms.cs new file mode 100644 index 000000000..b1a545301 --- /dev/null +++ b/src/Core/Sso/SamlSigningAlgorithms.cs @@ -0,0 +1,21 @@ +using System.Collections.Generic; + +namespace Bit.Core.Sso +{ + public static class SamlSigningAlgorithms + { + public const string Default = Sha256; + public const string Sha256 = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"; + public const string Sha384 = "http://www.w3.org/2000/09/xmldsig#rsa-sha384"; + public const string Sha512 = "http://www.w3.org/2000/09/xmldsig#rsa-sha512"; + public const string Sha1 = "http://www.w3.org/2000/09/xmldsig#rsa-sha1"; + + public static IEnumerable GetEnumerable() + { + yield return Sha256; + yield return Sha384; + yield return Sha512; + yield return Sha1; + } + } +}