/// <summary> /// Processes the authentication request. /// </summary> /// <param name="authnRequest">The AuthnRequest object.</param> /// <param name="relayState">The relayState string.</param> public static void ProcessAuthnRequest(Page page, out AuthnRequest authnRequest, out string relayState) { // Use a single endpoint and use a query string parameter to determine the Service Provider to Identity Provider binding type. string bindingType = page.Request.QueryString[SP2IdPBindingTypeVar]; // Get the previously loaded certificate. X509Certificate2 cert = (X509Certificate2)page.Application[Global.SPCertKey]; switch (bindingType) { case RedirectBinding: authnRequest = AuthnRequest.Create(page.Request.RawUrl, cert.PublicKey.Key); relayState = authnRequest.RelayState; break; case PostBinding: authnRequest = AuthnRequest.CreateFromHttpPost(page.Request); relayState = authnRequest.RelayState; break; case ArtifactBinding: Saml2ArtifactType0004 httpArtifact = Saml2ArtifactType0004.CreateFromHttpArtifactHttpForm(page.Request); // Create an artifact resolve request. ArtifactResolve artifactResolve = new ArtifactResolve(); artifactResolve.Issuer = new Issuer(new Uri(page.Request.Url, page.ResolveUrl("~/")).ToString()); artifactResolve.Artifact = new Artifact(httpArtifact.ToString()); // Send the SAML Artifact Resolve Request and parse the received response. ArtifactResponse artifactResponse = ArtifactResponse.SendSamlMessageReceiveAftifactResponse(Global.ArtifactResolutionUrl, artifactResolve); // Extract the authentication request from the received artifact response. authnRequest = new AuthnRequest(artifactResponse.Message); relayState = httpArtifact.RelayState; break; default: throw new ApplicationException("Invalid binding type"); } if (authnRequest.IsSigned()) { if (!authnRequest.Validate(cert)) { throw new ApplicationException("The authentication request signature failed to verify."); } } }
// Receive the authentication request from the service provider. public static void ReceiveAuthnRequest(Page page, out AuthnRequest authnRequest, out string relayState) { // Determine the service provider to identity provider binding type. // We use a query string parameter rather than having separate endpoints per binding. string bindingType = page.Request.QueryString[BindingQueryParameter]; switch (bindingType) { case SamlBindingUri.HttpRedirect: X509Certificate2 x509Certificate = (X509Certificate2)page.Application[Global.SPCertKey]; authnRequest = AuthnRequest.Create(page.Request.RawUrl, x509Certificate.PublicKey.Key); relayState = authnRequest.RelayState; break; case SamlBindingUri.HttpPost: authnRequest = AuthnRequest.CreateFromHttpPost(page.Request); relayState = authnRequest.RelayState; break; case SamlBindingUri.HttpArtifact: // Receive the artifact. Saml2ArtifactType0004 httpArtifact = Saml2ArtifactType0004.CreateFromHttpArtifactQueryString(page.Request); // Create an artifact resolve request. ArtifactResolve artifactResolve = new ArtifactResolve(); artifactResolve.Issuer = new Issuer(Util.GetAbsoluteUrl(page, "~/")); artifactResolve.Artifact = new Artifact(httpArtifact.ToString()); // Look up for the appropriate artifact SP url string referer = page.Request.UrlReferrer.AbsoluteUri; int i; for (i = 0; i < Services.AllowedServiceUrls.Length; i++) { string url = Services.AllowedServiceUrls[i]; if (referer.StartsWith(url)) { break; } } if (i == Services.AllowedServiceUrls.Length) { throw new Exception("Your SP is not allowed"); } // Send the artifact resolve request and receive the artifact response. string artifactServiceProviderUrl = Services.ArtifactServiceProviderUrls[i]; ArtifactResponse artifactResponse = ArtifactResponse.SendSamlMessageReceiveAftifactResponse(artifactServiceProviderUrl, artifactResolve); // Extract the authentication request from the artifact response. authnRequest = new AuthnRequest(artifactResponse.Message); relayState = httpArtifact.RelayState; break; default: Trace.Write("IdentityProvider", "Invalid service provider to identity provider binding"); authnRequest = null; relayState = null; return; } // If using HTTP redirect the message isn't signed as the generated query string is too long for most browsers. if (bindingType != SamlBindingUri.HttpRedirect) { if (authnRequest.IsSigned()) { // Verify the request's signature. X509Certificate2 x509Certificate = (X509Certificate2)page.Application[Global.SPCertKey]; if (!authnRequest.Validate(x509Certificate)) { throw new ApplicationException("The authentication request signature failed to verify."); } } } }