如何在ASP.NET中编写C#代码生成Shibboleth SAML请求并替换IIS的*.sso过滤器
Absolutely, this is a totally viable approach! You can bypass the Shibboleth SP's IIS filter entirely by generating SAML 2.0 authentication requests directly in your C# code. Here's how to pull this off effectively:
Key Prerequisites First
Before diving into code, make sure you have these details handy (you can grab most from your Shibboleth IDP and existing SP metadata):
- Shibboleth IDP's Entity ID (e.g.,
https://your-idp-domain/idp/shibboleth) - IDP's SSO endpoint URL (the HTTP-Redirect or POST endpoint where you'll send the auth request)
- IDP's signing certificate (to validate responses later)
- Your application's SP Entity ID (the same one you used in your Shibboleth SP config)
- Your application's Assertion Consumer Service (ACS) URL (the endpoint in your C# app that will receive the IDP's SAML response)
Step 1: Use a Mature SAML 2.0 Library for C#
Don't reinvent the wheel—use a battle-tested library to handle SAML serialization, signing, and validation. The most popular choice is ITfoxtec Identity SAML 2.0:
- Install it via NuGet:
Or via Package Manager Console:dotnet add package ITfoxtec.Identity.Saml2Install-Package ITfoxtec.Identity.Saml2
Step 2: Generate the SAML Authentication Request
Here's a code snippet to generate a SAML AuthnRequest and redirect the user to the Shibboleth IDP:
using ITfoxtec.Identity.Saml2; using ITfoxtec.Identity.Saml2.Schemas; using ITfoxtec.Identity.Saml2.MvcCore; using System.Security.Cryptography.X509Certificates; public IActionResult InitiateSso() { // Configure core SAML settings var saml2Settings = new Saml2Settings { Issuer = "your-sp-entity-id", // Your app's SP Entity ID IdPSsoUrl = "https://your-idp-domain/idp/profile/SAML2/Redirect/SSO", // IDP's SSO Redirect endpoint IdPCertificate = new X509Certificate2("path-to-idp-signing-certificate.cer"), // IDP's public cert for response validation AssertionConsumerServiceUrl = Url.Action(nameof(AssertionConsumerService), "Auth", null, Request.Scheme), // Your ACS endpoint SignatureAlgorithm = SecurityAlgorithms.RsaSha256, // Match IDP's supported algorithm }; // Create and configure the authentication request var authnRequest = new Saml2AuthnRequest(saml2Settings, Saml2BindingType.HttpRedirect); authnRequest.NameIdPolicy = new NameIdPolicy { AllowCreate = true, Format = NameIdFormats.EmailAddress }; // Adjust to match your LDAP user identifier authnRequest.RequestedAuthnContext = new RequestedAuthnContext { Comparison = AuthnContextComparisonTypes.Exact, AuthnContextClassRef = new List<string> { AuthnContextClassTypes.PasswordProtectedTransport } // Aligns with LDAP password auth }; // Redirect the user to the Shibboleth IDP with the generated request return authnRequest.ToActionResult(); }
Step 3: Handle the IDP's SAML Response
Once the user authenticates via LDAP, the Shibboleth IDP will send a SAML response to your ACS endpoint. Here's how to validate and process it:
using Microsoft.AspNetCore.Authentication.Cookies; using System.Security.Claims; public async Task<IActionResult> AssertionConsumerService() { var saml2Settings = new Saml2Settings { Issuer = "your-sp-entity-id", IdPSsoUrl = "https://your-idp-domain/idp/profile/SAML2/Redirect/SSO", IdPCertificate = new X509Certificate2("path-to-idp-signing-certificate.cer"), AssertionConsumerServiceUrl = Url.Action(nameof(AssertionConsumerService), "Auth", null, Request.Scheme), }; var saml2AuthnResponse = new Saml2AuthnResponse(saml2Settings); try { // Read and parse the incoming SAML response saml2AuthnResponse.ReadSamlResponse(Request.ToGenericHttpRequest()); if (saml2AuthnResponse.Status != Saml2StatusCodes.Success) { throw new Exception($"SAML Response status: {saml2AuthnResponse.Status}"); } // Validate the response signature and assertion integrity await saml2AuthnResponse.ValidateAsync(); // Extract user claims from the SAML assertion var userClaims = saml2AuthnResponse.Claims; // Create a user session in your application (example uses ASP.NET Core Identity) await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(saml2AuthnResponse.ClaimsIdentity)); return RedirectToAction("Index", "Home"); } catch (Exception ex) { // Handle errors like invalid signatures, expired requests, or authentication failures return BadRequest($"SAML authentication failed: {ex.Message}"); } }
Step 4: Update Shibboleth IDP Configuration
Make sure your IDP's relying party trust settings are updated to:
- Point to your new ACS URL (instead of the Shibboleth SP's
/Shibboleth.sso/SAML2/POSTendpoint) - Accept unsigned or signed requests (enable signing in your C# code if the IDP requires it)
Additional Tips
- Test with SAML Tracer: Use a browser extension like SAML Tracer to inspect the SAML request/response and compare it to the one generated by the Shibboleth SP—this helps debug any discrepancies.
- Request Signing: If your IDP requires signed requests, add your SP's signing certificate to the
saml2Settingsand setauthnRequest.SignAuthnRequest = true;. - Logout Handling: You can use the same library to generate SAML logout requests to the IDP if you need session termination functionality.
内容的提问来源于stack exchange,提问作者Dalip Choudhary

