/// <summary> /// Sends the SAML response to the Service Provider. /// </summary> /// <param name="samlResponse">The SAML response object.</param> /// <param name="relayState">The relay state.</param> public static void SendResponse(Page page, ComponentPro.Saml2.Response samlResponse, string relayState) { // Sign the SAML response. X509Certificate2 x509Certificate = (X509Certificate2)page.Application[Global.IdPCertKey]; samlResponse.Sign(x509Certificate); switch (Global.AssertionServiceSamlBinding) { case SamlBinding.HttpPost: // Send the SAML Response object. samlResponse.SendPostBindingForm(page.Response.OutputStream, Global.AssertionServiceUrl, relayState); break; case SamlBinding.HttpArtifact: // Create the artifact. string identificationUrl = GetAbsoluteUrl(page, "~/"); Saml2ArtifactType0004 httpArtifact = new Saml2ArtifactType0004(SamlArtifact.GetSourceId(identificationUrl), SamlArtifact.GetHandle()); // Convert the authentication request to XML and save to the application Cache. SamlSettings.CacheProvider.Insert(httpArtifact.ToString(), samlResponse.GetXml(), new TimeSpan(1, 0, 0)); // Send the artifact with POST form. httpArtifact.SendPostForm(page.Response.OutputStream, Global.AssertionServiceUrl, relayState); break; default: throw new ApplicationException("Invalid assertion consumer service binding."); } }
/// <summary> /// Processes a successful SAML response. /// </summary> private void ProcessSuccessResponse(ComponentPro.Saml2.Response samlResponse, string relayState) { // Extract the asserted identity from the SAML response. Assertion samlAssertion = (Assertion)samlResponse.Assertions[0]; // Get the subject name identifier. string userName = samlAssertion.Subject.NameId.NameIdentifier; // Get the originally requested resource URL from the relay state. string resourceUrl = (string)SamlSettings.CacheProvider.Remove(relayState); if (resourceUrl == null) { Trace.Write("ServiceProvider", "Nothing in cache"); // Set resource Url to the root dir resourceUrl = "/"; } // Create a login context for the asserted identity. FormsAuthentication.SetAuthCookie(userName, false); // Redirect to the originally requested resource URL. Response.Redirect(resourceUrl); }
// Send the SAML response over the specified binding. public static void SendSamlResponse(Page page, ComponentPro.Saml2.Response samlResponse, SsoAuthnState ssoState) { // Sign the SAML response X509Certificate2 x509Certificate = (X509Certificate2)page.Application[Global.IdPCertKey]; samlResponse.Sign(x509Certificate); // Send the SAML response to the service provider. switch (ssoState.IdpProtocolBinding) { case SamlBinding.HttpPost: samlResponse.SendPostBindingForm(page.Response.OutputStream, ssoState.AssertionConsumerServiceURL, ssoState.RelayState); break; case SamlBinding.HttpArtifact: // Create the artifact. string identificationUrl = Util.GetAbsoluteUrl(page, "~/"); Saml2ArtifactType0004 httpArtifact = new Saml2ArtifactType0004(SamlArtifact.GetSourceId(identificationUrl), SamlArtifact.GetHandle()); // Cache the authentication request for subsequent sending using the artifact resolution protocol. Sliding expiration time is 1 hour. SamlSettings.CacheProvider.Insert(httpArtifact.ToString(), samlResponse.GetXml(), new TimeSpan(1, 0, 0)); // Send the artifact. httpArtifact.SendPostForm(page.Response.OutputStream, ssoState.AssertionConsumerServiceURL, ssoState.RelayState); break; default: Trace.Write("IdentityProvider", "Invalid identity provider binding"); break; } }
/// <summary> /// Processes a successful SAML response and redirect to the requested URL. /// </summary> /// <param name="page">The page object.</param> /// <param name="samlResponse">The SAML response object.</param> /// <param name="relayState">The relay state.</param> public static void SamlSuccessRedirect(Page page, ComponentPro.Saml2.Response samlResponse, string relayState) { // Get the previously loaded certificate. X509Certificate2 x509Certificate = (X509Certificate2)page.Application[Global.SpCertKey]; Assertion samlAssertion; // Check assertions. if (samlResponse.GetAssertions().Count > 0) { // Extract the first assertion. samlAssertion = samlResponse.GetAssertions()[0]; } else if (samlResponse.GetEncryptedAssertions().Count > 0) { // Extract the first assertion. samlAssertion = samlResponse.GetEncryptedAssertions()[0].Decrypt(x509Certificate.PrivateKey, null); } else { throw new ApplicationException("No assertions in response"); } string userName; // Get the subject name identifier. if (samlAssertion.Subject.NameId != null) { userName = samlAssertion.Subject.NameId.NameIdentifier; } else if (samlAssertion.Subject.EncryptedId != null) { NameId nameId = samlAssertion.Subject.EncryptedId.Decrypt(x509Certificate.PrivateKey, null); userName = nameId.NameIdentifier; } else { throw new ApplicationException("No name in subject"); } // Get the originally requested resource URL from the relay state. string resourceUrl = (string)SamlSettings.CacheProvider.Remove(relayState); if (resourceUrl == null) { throw new ApplicationException("Invalid relay state"); } // Create a login context for the asserted identity. FormsAuthentication.SetAuthCookie(userName, false); // Redirect to the originally requested resource URL. page.Response.Redirect(resourceUrl, false); }
/// <summary> /// Processes an error SAML response. /// </summary> private void ProcessErrorResponse(ComponentPro.Saml2.Response samlResponse) { string errorMessage = null; if ((samlResponse.Status.StatusMessage != null)) { errorMessage = samlResponse.Status.StatusMessage.Message; } string redirectUrl = string.Format("~/UserLogin.aspx?{0}={1}", Util.ErrorVarName, HttpUtility.UrlEncode(errorMessage)); Response.Redirect(redirectUrl, false); }
/// <summary> /// Processes an error SAML response and redirect to the requested URL. /// </summary> /// <param name="page">The page object.</param> /// <param name="samlResponse">The SAML response object.</param> /// <param name="relayState">The relay state.</param> public static void SamlErrorRedirect(Page page, ComponentPro.Saml2.Response samlResponse) { string errorMessage = null; if (samlResponse.Status.StatusMessage != null) { errorMessage = samlResponse.Status.StatusMessage.Message; } string redirectUrl = String.Format("~/UserLogin.aspx?error={0}", HttpUtility.UrlEncode(errorMessage)); page.Response.Redirect(redirectUrl, false); }
/// <summary> /// Processes the SAML response received from the IdP. /// </summary> /// <param name="page">The page object.</param> /// <param name="relayState">The relay state</param> /// <param name="samlResponse">The SAML response object.</param> public static void ProcessResponse(Page page, out ComponentPro.Saml2.Response samlResponse, out string relayState) { // Extract the binding type from the query string. string bindingType = page.Request.QueryString["binding"]; switch (bindingType) { case "artifact": // Create an artifact from the query string. Saml2ArtifactType0004 httpArtifact = Saml2ArtifactType0004.CreateFromHttpArtifactQueryString(page.Request); // Create an artifact resolve request. ArtifactResolve artifactResolve = new ArtifactResolve(); artifactResolve.Issuer = new Issuer(GetAbsoluteUrl(page, "~/")); artifactResolve.Artifact = new Artifact(httpArtifact.ToString()); // Send the artifact resolve request and create an artifact response from the received XML. ArtifactResponse artifactResponse = ArtifactResponse.SendSamlMessageReceiveAftifactResponse(Global.ArtifactServiceUrl, artifactResolve); // Get the SAML Response from the artifact response. samlResponse = new ComponentPro.Saml2.Response(artifactResponse.Message); relayState = httpArtifact.RelayState; break; case "post": System.Diagnostics.Debug.WriteLine("POST"); // Create a SAML response from the form data. samlResponse = ComponentPro.Saml2.Response.Create(page.Request); relayState = samlResponse.RelayState; break; default: throw new ApplicationException("Unknown binding type"); } // Is the SAML response signed? if (samlResponse.IsSigned()) { // Get the previously loaded certificate. X509Certificate2 x509Certificate = (X509Certificate2)page.Application[Global.IdPCertKey]; // Validate the certificate. if (!samlResponse.Validate(x509Certificate)) { throw new ApplicationException("The SAML response signature failed to verify."); } } }
/// <summary> /// Processes the SAML response received from the IdP. /// </summary> /// <param name="page">The page object.</param> /// <param name="relayState">The relay state</param> /// <param name="samlResponse">The SAML response object.</param> public static void ProcessResponse(Page page, out ComponentPro.Saml2.Response samlResponse, out string relayState) { // Extract the binding type from the query string. string bindingType = page.Request.QueryString["binding"]; switch (bindingType) { case "artifact": // Create an artifact from the query string. Saml2ArtifactType0004 httpArtifact = Saml2ArtifactType0004.CreateFromHttpArtifactQueryString(page.Request); // Create an artifact resolve request. ArtifactResolve artifactResolve = new ArtifactResolve(); artifactResolve.Issuer = new Issuer(GetAbsoluteUrl(page, "~/")); artifactResolve.Artifact = new Artifact(httpArtifact.ToString()); // Send the artifact resolve request and create an artifact response from the received XML. ArtifactResponse artifactResponse = ArtifactResponse.SendSamlMessageReceiveAftifactResponse(Global.ArtifactServiceUrl, artifactResolve); // Get the SAML Response from the artifact response. samlResponse = new ComponentPro.Saml2.Response(artifactResponse.Message); relayState = httpArtifact.RelayState; break; case "post": // Create a SAML response from the form data. samlResponse = ComponentPro.Saml2.Response.Create(page.Request); relayState = samlResponse.RelayState; break; default: throw new ApplicationException("Unknown binding type"); } // Is the SAML response signed? if (samlResponse.IsSigned()) { // Get the previously loaded certificate. X509Certificate2 x509Certificate = (X509Certificate2)page.Application[Global.IdPCertKey]; // Validate the certificate. if (!samlResponse.Validate(x509Certificate)) { throw new ApplicationException("The SAML response signature failed to verify."); } } }
/// <summary> /// Receives the SAML response from the identity provider. /// </summary> /// <param name="samlResponse"></param> /// <param name="relayState"></param> private void ReceiveResponse(out ComponentPro.Saml2.Response samlResponse, out string relayState) { // Determine the identity provider to service provider binding type. // We use a query string parameter rather than having separate endpoints per binding. string bindingType = Request.QueryString[Util.BindingVarName]; switch (bindingType) { case SamlBindingUri.HttpPost: samlResponse = ComponentPro.Saml2.Response.Create(Request); relayState = samlResponse.RelayState; break; case SamlBindingUri.HttpArtifact: Saml2ArtifactType0004 httpArtifact = Saml2ArtifactType0004.CreateFromHttpArtifactHttpForm(Request); // Create an artifact resolve request. ArtifactResolve artifactResolve = new ArtifactResolve(); artifactResolve.Issuer = new Issuer(Util.GetAbsoluteUrl(this, "~/")); artifactResolve.Artifact = new Artifact(httpArtifact.ToString()); // Send the artifact resolve request and receive the artifact response. string spArtifactResponderUrl = WebConfigurationManager.AppSettings["ArtifactIdProviderUrl"]; ArtifactResponse artifactResponse = ArtifactResponse.SendSamlMessageReceiveAftifactResponse(spArtifactResponderUrl, artifactResolve); // Extract the authentication request from the artifact response. samlResponse = new Response(artifactResponse.Message); relayState = httpArtifact.RelayState; break; default: Trace.Write("ServiceProvider", "Invalid identity provider to service provider binding"); samlResponse = null; relayState = null; return; } // Verify the response's signature. X509Certificate2 x509Certificate = (X509Certificate2)Application[Global.IdPCertKey]; if (!samlResponse.Validate(x509Certificate)) { throw new System.ApplicationException("The SAML response signature failed to verify."); } }
/// <summary> /// Builds the SAML response. /// </summary> /// <param name="authnRequest">The AuthnRequest object.</param> /// <returns>A SAML Response object.</returns> public static ComponentPro.Saml2.Response BuildResponse(Page page, AuthnRequest authnRequest) { ComponentPro.Saml2.Response samlResponse = new ComponentPro.Saml2.Response(); samlResponse.Destination = Global.AssertionServiceUrl; Issuer issuer = new Issuer(GetAbsoluteUrl(page, "~/")); samlResponse.Issuer = issuer; if (page.User.Identity.IsAuthenticated) { samlResponse.Status = new Status(SamlPrimaryStatusCode.Success, null); Assertion samlAssertion = new Assertion(); samlAssertion.Issuer = issuer; Subject subject = new Subject(new NameId(page.User.Identity.Name)); SubjectConfirmation subjectConfirmation = new SubjectConfirmation(SamlSubjectConfirmationMethod.Bearer); SubjectConfirmationData subjectConfirmationData = new SubjectConfirmationData(); subjectConfirmationData.InResponseTo = authnRequest.Id; subjectConfirmationData.Recipient = Global.AssertionServiceUrl; subjectConfirmation.SubjectConfirmationData = subjectConfirmationData; subject.SubjectConfirmations.Add(subjectConfirmation); samlAssertion.Subject = subject; AuthnStatement authnStatement = new AuthnStatement(); authnStatement.AuthnContext = new AuthnContext(); authnStatement.AuthnContext.AuthnContextClassRef = new AuthnContextClassRef(SamlAuthenticateContext.Password); samlAssertion.Statements.Add(authnStatement); samlResponse.Assertions.Add(samlAssertion); } else { samlResponse.Status = new Status(SamlPrimaryStatusCode.Responder, SamlSecondaryStatusCode.AuthnFailed, "The user is not authenticated at the identity provider"); } return(samlResponse); }
// Create a SAML response with the user's local identity, if any, or indicating an error. public static ComponentPro.Saml2.Response CreateSamlResponse(Page page) { ComponentPro.Saml2.Response samlResponse = new ComponentPro.Saml2.Response(); string issuerUrl = Util.GetAbsoluteUrl(page, "~/"); samlResponse.Issuer = new Issuer(issuerUrl); if (page.User.Identity.IsAuthenticated) { samlResponse.Status = new Status(SamlPrimaryStatusCode.Success, null); Assertion samlAssertion = new Assertion(); samlAssertion.Subject = new Subject(new NameId(page.User.Identity.Name)); samlAssertion.Statements.Add(new AuthnStatement()); samlResponse.Assertions.Add(samlAssertion); } else { samlResponse.Status = new Status(SamlPrimaryStatusCode.Responder, SamlSecondaryStatusCode.AuthnFailed, "The user is not authenticated at the identity provider"); } return(samlResponse); }
private void RecieveResponse(out ComponentPro.Saml2.Response samlResponse, out string relayState, string binding) { var bindingType = binding; if (bindingType == null) { if (HttpContext.Session.GetString("User") != null) { HttpContext.Session.Set("User", null); } else { HttpContext.Response.Redirect("trylogin"); } } switch (bindingType) { case SamlBindingUri.HttpPost: samlResponse = ComponentPro.Saml2.Response.Create(HttpContext.Request); relayState = samlResponse.RelayState; break; default: samlResponse = null; relayState = null; return; } var x509Certificate = _certificateProvider.GetCertificate(); if (!samlResponse.Validate(x509Certificate)) { throw new ApplicationException("The SAML response signature failed to verify."); } }
protected override void OnLoad(EventArgs e) { base.OnLoad(e); try { #region Receive SAML Response // Create a SAML response from the HTTP request. ComponentPro.Saml2.Response samlResponse = ComponentPro.Saml2.Response.Create(Request); // Is it signed? if (samlResponse.IsSigned()) { // Loaded the previously loaded certificate. X509Certificate2 x509Certificate = (X509Certificate2)Application[Global.CertKeyName]; // Validate the SAML response with the certificate. if (!samlResponse.Validate(x509Certificate)) { throw new ApplicationException("SAML response signature is not valid."); } } #endregion #region Process the response // Success? if (!samlResponse.IsSuccess()) { throw new ApplicationException("SAML response is not success"); } Assertion samlAssertion; // Define ENCRYPTEDSAML preprocessor flag if you wish to decrypt the SAML response. #if ENCRYPTEDSAML if (samlResponse.GetEncryptedAssertions().Count > 0) { EncryptedAssertion encryptedAssertion = samlResponse.GetEncryptedAssertions()[0]; // Load the private key. // Consider caching the loaded key in production environment for better performance. X509Certificate2 decryptionKey = new X509Certificate2(Path.Combine(HttpRuntime.AppDomainAppPath, "EncryptionKey.pfx"), "password"); // Decrypt the encrypted assertion. samlAssertion = encryptedAssertion.Decrypt(decryptionKey.PrivateKey, null); } else { throw new ApplicationException("No encrypted assertions found in the SAML response"); } #else // Get the asserted identity. if (samlResponse.GetAssertions().Count > 0) { samlAssertion = samlResponse.GetAssertions()[0]; } else { throw new ApplicationException("No assertions found in the SAML response"); } #endif // Get the subject name identifier. string userName; if (samlAssertion.Subject.NameId != null) { userName = samlAssertion.Subject.NameId.NameIdentifier; } else { throw new ApplicationException("Name identifier not found in subject"); } #region Extract Custom Attributes // If you need to add custom attributes, uncomment the following code //if (samlAssertion.AttributeStatements.Count > 0) //{ // foreach (AttributeStatement attributeStatement in samlAssertion.AttributeStatements) // { // // If you need to decrypt encrypted attributes, refer to this topic: http://www.samlcomponent.net/encrypting-and-decrypting-saml-response-xml // foreach (ComponentPro.Saml2.Attribute attribute in attributeStatement.Attributes) // { // // Process your custom attribute here. // // ... // } // } //} #endregion // Set authentication cookie. FormsAuthentication.SetAuthCookie(userName, false); // Redirect to the requested URL. Response.Redirect(samlResponse.RelayState, false); #endregion } catch (Exception exception) { Trace.Write("ServiceProvider", "An Error occurred", exception); } }
protected override void OnLoad(EventArgs e) { base.OnLoad(e); try { // Load the Single Sign On state from the Session state. // If the saved authentication state is a null reference, receive the authentication request from the query string and form data. SsoAuthnState ssoState = (SsoAuthnState)Session[SsoAuthnStateSessionKey]; if (ssoState == null || !User.Identity.IsAuthenticated) { AuthnRequest authnRequest; string relayState; // Receive the authentication request and relay state. Util.ProcessAuthnRequest(this, out authnRequest, out relayState); // Check whether the provider MUST authenticate the presenter directly rather than rely on a previous security context. bool forceAuthn = authnRequest.ForceAuthn; bool allowCreate = false; if (authnRequest.NameIdPolicy != null) { // Check whether the identity provider is allowed. allowCreate = authnRequest.NameIdPolicy.AllowCreate; } ssoState = new SsoAuthnState(); ssoState.AuthnRequest = authnRequest; ssoState.State = relayState; // A boolean flag determining whether or not a local login is required. bool requireLocalLogin = false; if (forceAuthn) { requireLocalLogin = true; } else { if (!User.Identity.IsAuthenticated && allowCreate) { requireLocalLogin = true; } } // Local login is required? if (requireLocalLogin) { // Then save the session state. Session[SsoAuthnStateSessionKey] = ssoState; // And redirect to the login page. FormsAuthentication.RedirectToLoginPage(); return; } } // Create a new SAML 2 Response. ComponentPro.Saml2.Response samlResponse = Util.BuildResponse(this, ssoState.AuthnRequest); // Send the SAML response to the service provider. Util.SendResponse(this, samlResponse, ssoState.State); } catch (Exception exception) { Trace.Write("IdentityProvider", "An Error occurred", exception); } }
protected override void OnLoad(EventArgs e) { base.OnLoad(e); try { // Extract the SP target url. string targetUrl = Request.QueryString["spUrl"]; // Validate it. if (string.IsNullOrEmpty(targetUrl)) { return; } // Create a SAML response object. ComponentPro.Saml2.Response samlResponse = new ComponentPro.Saml2.Response(); // Assign the consumer service url. samlResponse.Destination = ConsumerServiceUrl; Issuer issuer = new Issuer(GetAbsoluteUrl("~/")); samlResponse.Issuer = issuer; samlResponse.Status = new Status(SamlPrimaryStatusCode.Success, null); Assertion samlAssertion = new Assertion(); samlAssertion.Issuer = issuer; // Use the local user's local identity. Subject subject = new Subject(new NameId(User.Identity.Name)); SubjectConfirmation subjectConfirmation = new SubjectConfirmation(SamlSubjectConfirmationMethod.Bearer); SubjectConfirmationData subjectConfirmationData = new SubjectConfirmationData(); subjectConfirmationData.Recipient = ConsumerServiceUrl; subjectConfirmation.SubjectConfirmationData = subjectConfirmationData; subject.SubjectConfirmations.Add(subjectConfirmation); samlAssertion.Subject = subject; // Create a new authentication statement. AuthnStatement authnStatement = new AuthnStatement(); authnStatement.AuthnContext = new AuthnContext(); authnStatement.AuthnContext.AuthnContextClassRef = new AuthnContextClassRef(SamlAuthenticateContext.Password); samlAssertion.Statements.Add(authnStatement); // If you need to add custom attributes, uncomment the following code // #region Custom Attributes // AttributeStatement attributeStatement = new AttributeStatement(); // attributeStatement.Attributes.Add(new ComponentPro.Saml2.Attribute("email", SamlAttributeNameFormat.Basic, null, // "*****@*****.**")); // attributeStatement.Attributes.Add(new ComponentPro.Saml2.Attribute("FirstName", SamlAttributeNameFormat.Basic, null, // "John")); // attributeStatement.Attributes.Add(new ComponentPro.Saml2.Attribute("LastName", SamlAttributeNameFormat.Basic, null, // "Smith")); // // Insert a custom token key to the SAML response. // attributeStatement.Attributes.Add(new ComponentPro.Saml2.Attribute("CustomTokenForVerification", SamlAttributeNameFormat.Basic, null, // "YourEncryptedTokenHere")); // samlAssertion.Statements.Add(attributeStatement); // #endregion // Define ENCRYPTEDSAML preprocessor flag if you wish to encrypt the SAML response. #if ENCRYPTEDSAML // Load the certificate for the encryption. // Please make sure the file is in the root directory. X509Certificate2 encryptingCert = new X509Certificate2(Path.Combine(HttpRuntime.AppDomainAppPath, "EncryptionX509Certificate.cer"), "password"); // Create an encrypted SAML assertion from the SAML assertion we have created. EncryptedAssertion encryptedSamlAssertion = new EncryptedAssertion(samlAssertion, encryptingCert, new System.Security.Cryptography.Xml.EncryptionMethod(SamlKeyAlgorithm.TripleDesCbc)); // Add encrypted assertion to the SAML response object. samlResponse.Assertions.Add(encryptedSamlAssertion); #else // Add assertion to the SAML response object. samlResponse.Assertions.Add(samlAssertion); #endif // Get the previously loaded certificate. X509Certificate2 x509Certificate = (X509Certificate2)Application[Global.CertKeyName]; // Sign the SAML response with the certificate. samlResponse.Sign(x509Certificate); // Send the SAML response to the service provider. samlResponse.SendPostBindingForm(Response.OutputStream, ConsumerServiceUrl, targetUrl); } catch (Exception exception) { Trace.Write("IdentityProvider", "An Error occurred", exception); } }
/// <summary> /// Processes a successful SAML response and redirect to the requested URL. /// </summary> /// <param name="page">The page object.</param> /// <param name="samlResponse">The SAML response object.</param> /// <param name="relayState">The relay state.</param> public static void SamlSuccessRedirect(Page page, ComponentPro.Saml2.Response samlResponse, string relayState) { // Get the previously loaded certificate. X509Certificate2 x509Certificate = (X509Certificate2)page.Application[Global.SpCertKey]; Assertion samlAssertion; // Check assertions. if (samlResponse.GetAssertions().Count > 0) { // Extract the first assertion. samlAssertion = samlResponse.GetAssertions()[0]; } else if (samlResponse.GetEncryptedAssertions().Count > 0) { // Extract the first assertion. samlAssertion = samlResponse.GetEncryptedAssertions()[0].Decrypt(x509Certificate.PrivateKey, null); } else { throw new ApplicationException("No assertions in response"); } string userName; // Get the subject name identifier. if (samlAssertion.Subject.NameId != null) { //userName = samlAssertion.Subject.NameId.NameIdentifier; userName = samlAssertion.GetAttributeValueByFriendlyName("eduPersonPrincipalName"); System.Collections.Generic.Dictionary<string, string> dict = new System.Collections.Generic.Dictionary<string, string>(); foreach (ComponentPro.Saml2.Attribute attribute in samlAssertion.AttributeStatements[0].Attributes) { dict.Add(attribute.FriendlyName, attribute.Values[0].ToString()); System.Diagnostics.Trace.WriteLine(attribute.FriendlyName + ":" + attribute.Values[0].ToString()); } HttpContext.Current.Session.Add("samlAttributes", dict); } else if (samlAssertion.Subject.EncryptedId != null) { NameId nameId = samlAssertion.Subject.EncryptedId.Decrypt(x509Certificate.PrivateKey, null); userName = nameId.NameIdentifier; } else { throw new ApplicationException("No name in subject"); } try { string aaURL = "https://idp.testshib.org:8443/idp/profile/SAML2/SOAP/AttributeQuery"; //Testing subject NameId subje = new NameId(userName,null,null,SamlNameIdentifierFormat.Unspecified,aaURL); //Testing subject Subject subject = new Subject(new NameId(userName)); SubjectConfirmation subjectConfirmation = new SubjectConfirmation(SamlSubjectConfirmationMethod.Bearer); SubjectConfirmationData subjectConfirmationData = new SubjectConfirmationData(); subjectConfirmationData.Recipient = aaURL; subjectConfirmation.SubjectConfirmationData = subjectConfirmationData; subject.SubjectConfirmations.Add(subjectConfirmation); AttributeQuery attributeQuery = new AttributeQuery(); //attributeQuery.Subject = subject; attributeQuery.Destination = aaURL; attributeQuery.Issuer = new Issuer(Global.entityId); attributeQuery.Attributes.Add(new ComponentPro.Saml2.Attribute() { FriendlyName = "givenName" }); attributeQuery.Subject = new Subject(samlAssertion.Subject.NameId); attributeQuery.Sign(x509Certificate); System.Diagnostics.Trace.WriteLine("Trying to get attributes from AA"); System.Diagnostics.Trace.WriteLine("AA query " + attributeQuery.GetXml().OuterXml); System.Diagnostics.Trace.WriteLine("AA Subject " + attributeQuery.Subject.ToString()); ArtifactResponse artifactResponse = ArtifactResponse.SendSamlMessageReceiveAftifactResponse(aaURL, attributeQuery); Response attrResponse; attrResponse = new ComponentPro.Saml2.Response(artifactResponse.Message); System.Diagnostics.Trace.WriteLine("AA reponse " + attrResponse.GetXml().OuterXml); } catch (Exception e) { System.Diagnostics.Trace.WriteLine("Execption: " + e.ToString()); //throw; } // Get the originally requested resource URL from the relay state. string resourceUrl = (string)SamlSettings.CacheProvider.Remove(relayState); if (resourceUrl == null) { throw new ApplicationException("Invalid relay state"); } // Create a login context for the asserted identity. FormsAuthentication.SetAuthCookie(userName, false); // Redirect to the originally requested resource URL. page.Response.Redirect(resourceUrl, false); }
protected override void OnLoad(System.EventArgs e) { base.OnLoad(e); try { // Look up for the SP ID string referer = this.Request.UrlReferrer.AbsoluteUri; int i = -1; if (!referer.StartsWith(Services.LocalUri)) { 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"); } } // Get the saved SSO state, if any. // If there isn't saved state then receive the authentication request. // If there is saved state then we've just completed a local login in response // to a prior authentication request. SsoAuthnState ssoState = (SsoAuthnState)Session[SsoSessionKey]; // Receive the authentication request. AuthnRequest authnRequest = null; string relayState = null; if (i != -1) { Util.ReceiveAuthnRequest(this, out authnRequest, out relayState); if (authnRequest == null) { // No authentication request found. return; } } if (ssoState == null) { // Process the authentication request. bool forceAuthn = authnRequest.ForceAuthn; bool allowCreate = false; if (authnRequest.NameIdPolicy != null) { allowCreate = authnRequest.NameIdPolicy.AllowCreate; } ssoState = new SsoAuthnState(); ssoState.AuthnRequest = authnRequest; ssoState.RelayState = relayState; ssoState.IdpProtocolBinding = SamlBindingUri.UriToBinding(authnRequest.ProtocolBinding); ssoState.AssertionConsumerServiceURL = authnRequest.AssertionConsumerServiceUrl; // Determine whether or not a local login is required. bool requireLocalLogin = false; if (forceAuthn) { requireLocalLogin = true; } else { if (!User.Identity.IsAuthenticated & allowCreate) { requireLocalLogin = true; } } // If a local login is required then save the authentication request // and initiate a local login. if (requireLocalLogin) { // Save the SSO state. Session[SsoSessionKey] = ssoState; // Initiate a local login. System.Web.Security.FormsAuthentication.RedirectToLoginPage(); return; } } // Create a SAML response with the user's local identity, if any. ComponentPro.Saml2.Response samlResponse = Util.CreateSamlResponse(this); if (i != -1) { // Update the Relay state before sending SAML response. // Dynamically update the assertion consumer service URL corresponding to the service provider. ssoState.AssertionConsumerServiceURL = authnRequest.AssertionConsumerServiceUrl; } // Send the SAML response to the service provider. Util.SendSamlResponse(this, samlResponse, ssoState); } catch (Exception exception) { Trace.Write("IdentityProvider", "An Error occurred", exception); } }