Support

Stellen Sie Fragen auf Stack Overflow und taggen Sie mit 'itfoxtec-identity-saml2'.

Kontaktieren Sie contact@foxids.com für bezahlte Beratung.

Paket

Veröffentlichungen
NuGet ITfoxtec Identity SAML 2.0
NuGet ITfoxtec Identity SAML 2.0 MVC
NuGet ITfoxtec Identity SAML 2.0 MVC Core

Code und Lizenz

GitHub Code und Beispiel
Open-Source-Lizenz

ITfoxtec Identity SAML 2.0

Das Open-Source ITfoxtec Identity Saml2 Paket fügt SAML-P Unterstützung für Identity Provider (IdP) und Relying Party (RP) zusätzlich zur in .NET implementierten SAML 2.0 Funktionalität hinzu.

Der Firmenname ITfoxtec wurde geändert zu FoxIDs aber die Komponenten behalten den ITfoxtec Namen vorerst als Teil des Komponentennamens bei.

Unterstützte .NET Versionen:
  • .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

Das ITfoxtec Identity Saml2 Paket implementiert die wichtigsten Teile des SAML-P Standards und einige optionale Funktionen. Nachrichtensignierung und Validierung sowie Entschlüsselung werden unterstützt. Das Paket unterstützt SAML 2.0 Login, Logout, Single Logout und Metadaten. Sowohl SP Initiated als auch IdP Initiated Sign On werden unterstützt.

Das ITfoxtec Identity Saml2 Paket ist auf Konformität mit Microsoft Entra ID (Azure AD), AD FS, Azure AD B2C, dem dänischen NemLog-in3 (MitID), dem dänischen Context Handler (auf Dänisch Fælleskommunal Adgangsstyring) und vielen weiteren IdPs und RPs getestet.

Bitte sehen Sie die Testbeispiele.

Kontaktieren Sie Anders Revsgaard (anders@foxids.com) wenn Sie ein Beispiel für einen bestimmten IdP benötigen, z. B. das dänische NemLog-in (MitID) oder den Context Handler.
Dies ist ein kostenpflichtiger Service, bei dem Sie ein einsatzbereites Beispielpaket für einen IdP kaufen oder ein angepasstes Beispiel anfordern können.

Sie können das SAML 2.0 Tool verwenden, um Tokens zu decodieren und mit dem Zertifikat Toolselbstsignierte Zertifikate zu erstellen.

Unterstützte Bindings:

  • Redirect Binding
  • Post Binding
  • Artifact Binding

Die Bindings können je nach Bedarf verwendet werden für:

  • Authn Request
  • Authn Response (SAML 2.0 Response)
  • Logout Request
  • Logout Response

SHA1/SHA256/SHA384/SHA512 wird für Nachrichtensignierung unterstützt.

  • 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 und ASP.NET MVC Core werden von den ITfoxtec Identity SAML 2.0 MVC und MVC Core Paketen unterstützt, die helfen, das ITfoxtec SAML 2.0 Paket in eine MVC und MVC Core Anwendung zu integrieren.

Code

Der gezeigte Code ist nur eine Auswahl des Beispielcodes in GitHub.

Das ITfoxtec Identity Saml2 Paket wird in eine ASP.NET MVC Core Relying Party (RP) Anwendung durch Konfiguration in Startup und durch Hinzufügen eines Auth Controllers mit den folgenden vier Methoden integriert. Die gezeigte Binding kann je nach Anforderungen angepasst werden.

Außerdem ist es möglich, einige optionale Parameter für Saml2AuthnRequest und Saml2LogoutRequest zu setzen. Bei Saml2AuthnRequest wird z. B. ForceAuthn unterstützt, was den Benutzer zwingt, Anmeldeinformationen einzugeben, auch wenn bereits ein SSO Kontext beim Security Token Service (STS) / Identity Provider (IdP) existiert.


Fügen Sie die Konfiguration zur ConfigureServices Methode in Startup hinzu

Konfiguration mit IdP Metadaten.
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();   

Konfiguration ohne Metadaten.
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();   

Login Methode im 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();
}

AssertionConsumerService Methode im Auth Controller

Nach erfolgreichem oder fehlgeschlagenem Login erhält die ACS Methode die Antwort.
[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);
}

Logout Methode im 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();
}

LoggedOut Methode im Auth Controller

Nach erfolgreichem oder fehlgeschlagenem Logout erhält die LoggedOut Methode die Antwort.
[Route("LoggedOut")]
public IActionResult LoggedOut()
{
    var httpRequest = Request.ToGenericHttpRequest(validate: true);
    httpRequest.Binding.Unbind(httpRequest, new Saml2LogoutResponse(config));

    return Redirect(Url.Content("~/"));
}

SingleLogout Methode im Auth Controller

Empfängt eine Single Logout Anfrage und sendet eine Antwort.
[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();
}

Ihre Privatsphäre

Wir verwenden Cookies, um Ihre Erfahrung auf unseren Websites zu verbessern. Klicken Sie auf 'Alle Cookies akzeptieren', um der Verwendung von Cookies zuzustimmen. Um nicht notwendige Cookies abzulehnen, klicken Sie auf 'Nur notwendige Cookies'.

Weitere Informationen finden Sie in unserer Datenschutzerklärung