Support
Posez vos questions sur Stack Overflow et taguez avec « itfoxtec-identity-saml2 ».
Contactez contact@foxids.com pour du conseil payant.
Package
Versions
NuGet ITfoxtec Identity SAML 2.0
NuGet ITfoxtec Identity SAML 2.0 MVC
NuGet ITfoxtec Identity SAML 2.0 MVC Core
Code et licence
Code et exemple GitHub
Licence open-source
ITfoxtec Identity SAML 2.0
Le package open-source ITfoxtec Identity Saml2 ajoute la prise en charge SAML-P pour Identity Provider (IdP) et Relying Party (RP) en complément de la fonctionnalité SAML 2.0 implémentée en .NET.
Le nom de la société ITfoxtec a changé pour FoxIDs mais les composants conservent pour l’instant le nom ITfoxtec dans le nom du composant.
- .NET 10.0
- .NET 9.0
- .NET 8.0
- .NET 7.0
- .NET 6.0
- .NET Standard 2.1
- .NET Framework 4.6.2 and 4.8
Le package ITfoxtec Identity Saml2 implémente les parties les plus importantes du standard SAML-P ainsi que certaines fonctionnalités optionnelles. La signature et la validation des messages ainsi que le déchiffrement sont pris en charge. Le package supporte la connexion, la déconnexion, le single logout et les métadonnées SAML 2.0. Les connexions SP Initiated et IdP Initiated sont prises en charge.
Le package ITfoxtec Identity Saml2 est testé pour la conformité avec Microsoft Entra ID (Azure AD), AD FS, Azure AD B2C, le NemLog-in3 danois (MitID), le Context Handler danois (appelé en danois Fælleskommunal Adgangsstyring) et de nombreux autres IdP et RP.
Veuillez consulter les exemples de test.
Contactez Anders Revsgaard (anders@foxids.com) si vous avez besoin d’un exemple pour un IdP spécifique tel que le NemLog-in (MitID) danois ou Context Handler.
C’est un service payant où vous pouvez acheter un exemple prêt à l’emploi pour un IdP ou demander un exemple personnalisé.
>
Vous pouvez utiliser l’ outil SAML 2.0 pour décoder les jetons et créer des certificats auto-signés avec l’ outil de certificats.
Bindings pris en charge :
- Redirect Binding
- Post Binding
- Artifact Binding
Les bindings peuvent être utilisés au besoin pour :
- Authn Request
- Authn Response (SAML 2.0 Response)
- Logout Request
- Logout Response
SHA1/SHA256/SHA384/SHA512 sont pris en charge pour la signature des messages.
- SHA1: http://www.w3.org/2000/09/xmldsig#rsa-sha1
- SHA256: http://www.w3.org/2001/04/xmldsig-more#rsa-sha256
- SHA384: http://www.w3.org/2001/04/xmldsig-more#rsa-sha384
- SHA512: http://www.w3.org/2001/04/xmldsig-more#rsa-sha512
ASP.NET MVC et ASP.NET MVC Core sont pris en charge par les packages ITfoxtec Identity SAML 2.0 MVC et MVC Core qui aident à intégrer le package ITfoxtec SAML 2.0 dans une application MVC ou MVC Core.
Code
Le code présenté n’est qu’une sélection du code d’exemple sur GitHub.
Le package ITfoxtec Identity Saml2 est intégré dans une application ASP.NET MVC Core Relying Party (RP) via la configuration dans Startup et l’ajout d’un Auth Controller avec les quatre méthodes suivantes. Le binding présenté peut être modifié selon les besoins.
Il est également possible de définir des paramètres optionnels sur Saml2AuthnRequest et Saml2LogoutRequest. Sur Saml2AuthnRequest, par exemple, ForceAuthn est pris en charge, ce qui force l’utilisateur à saisir ses identifiants même si un contexte SSO existe déjà sur le Security Token Service (STS) / Identity Provider (IdP).
Ajouter la configuration à la méthode ConfigureServices dans Startup
Configuration à l’aide des métadonnées IdP.services.Configure<Saml2Configuration>(Configuration.GetSection("Saml2")); services.Configure<Saml2Configuration>(saml2Configuration => { saml2Configuration.SigningCertificate = CertificateUtil.Load(AppEnvironment.MapToPhysicalFilePath( Configuration["Saml2:SigningCertificateFile"]), Configuration["Saml2:SigningCertificatePassword"]); saml2Configuration.AllowedAudienceUris.Add(saml2Configuration.Issuer); var entityDescriptor = new EntityDescriptor(); entityDescriptor.ReadIdPSsoDescriptorFromUrl(new Uri(Configuration["Saml2:IdPMetadata"])); if (entityDescriptor.IdPSsoDescriptor != null) { saml2Configuration.SingleSignOnDestination = entityDescriptor.IdPSsoDescriptor.SingleSignOnServices.First().Location; saml2Configuration.SingleLogoutDestination = entityDescriptor.IdPSsoDescriptor.SingleLogoutServices.First().Location; saml2Configuration.SignatureValidationCertificates.AddRange(entityDescriptor.IdPSsoDescriptor.SigningCertificates); } else { throw new Exception("IdPSsoDescriptor not loaded from metadata."); } }); services.AddSaml2();
Configuration sans métadonnées.
services.Configure<Saml2Configuration>(Configuration.GetSection("Saml2")); services.Configure<Saml2Configuration>(saml2Configuration => { saml2Configuration.SigningCertificate = CertificateUtil.Load(AppEnvironment.MapToPhysicalFilePath( Configuration["Saml2:SigningCertificateFile"]), Configuration["Saml2:SigningCertificatePassword"]); saml2Configuration.AllowedAudienceUris.Add(saml2Configuration.Issuer); saml2Configuration.SignatureValidationCertificates.Add(CertificateUtil.Load(AppEnvironment.MapToPhysicalFilePath( Configuration["Saml2:SignatureValidationCertificateFile"]))); }); services.AddSaml2();
Méthode de connexion dans le Auth Controller
[Route("Login")] public IActionResult Login(string returnUrl = null) { var binding = new Saml2RedirectBinding(); binding.SetRelayStateQuery(new Dictionary<string, string> { { relayStateReturnUrl, returnUrl ?? Url.Content("~/") } }); return binding.Bind(new Saml2AuthnRequest(config)).ToActionResult(); }
Méthode AssertionConsumerService dans le Auth Controller
Après une connexion réussie ou échouée, la méthode ACS reçoit la réponse.[Route("AssertionConsumerService")] public async Task<IActionResult> AssertionConsumerService() { var httpRequest = Request.ToGenericHttpRequest(validate: true); var saml2AuthnResponse = new Saml2AuthnResponse(config); httpRequest.Binding.Unbind(httpRequest, saml2AuthnResponse); await saml2AuthnResponse.CreateSession(HttpContext, ClaimsTransform: (claimsPrincipal) => ClaimsTransform.Transform(claimsPrincipal)); var returnUrl = httpRequest.Binding.GetRelayStateQuery()[relayStateReturnUrl]; return Redirect(string.IsNullOrWhiteSpace(returnUrl) ? Url.Content("~/") : returnUrl); }
Méthode de déconnexion dans le Auth Controller
[HttpPost("Logout")] [ValidateAntiForgeryToken] public async Task<IActionResult> Logout() { if (!User.Identity.IsAuthenticated) { return Redirect(Url.Content("~/")); } var binding = new Saml2PostBinding(); var saml2LogoutRequest = await new Saml2LogoutRequest(config, User).DeleteSession(HttpContext); return binding.Bind(saml2LogoutRequest).ToActionResult(); }
Méthode LoggedOut dans le Auth Controller
Après une déconnexion réussie ou échouée, la méthode logged out reçoit la réponse.[Route("LoggedOut")] public IActionResult LoggedOut() { var httpRequest = Request.ToGenericHttpRequest(validate: true); httpRequest.Binding.Unbind(httpRequest, new Saml2LogoutResponse(config)); return Redirect(Url.Content("~/")); }
Méthode SingleLogout dans le Auth Controller
Reçoit une requête Single Logout et envoie une réponse.[Route("SingleLogout")] public async Task<IActionResult> SingleLogout() { Saml2StatusCodes status; var httpRequest = Request.ToGenericHttpRequest(validate: true); var logoutRequest = new Saml2LogoutRequest(config, User); try { httpRequest.Binding.Unbind(httpRequest, logoutRequest); status = Saml2StatusCodes.Success; await logoutRequest.DeleteSession(HttpContext); } catch (Exception exc) { // log exception Debug.WriteLine("SingleLogout error: " + exc.ToString()); status = Saml2StatusCodes.RequestDenied; } var responseBinding = new Saml2PostBinding(); responseBinding.RelayState = httpRequest.Binding.RelayState; var saml2LogoutResponse = new Saml2LogoutResponse(config) { InResponseToAsString = logoutRequest.IdAsString, Status = status, }; return responseBinding.Bind(saml2LogoutResponse).ToActionResult(); }