public LogoutResponseFactoryTests() { _logoutResponseFactory = new LogoutResponseFactory(); }
/// <summary> /// SAML2 Logout. /// /// The SAML2 logout is complicated as there are two main scenarios. /// /// Scenario 1. /// /// It's this application that triggers the logout. /// The application sends the LogoutRequest to the server /// and the server is supposed to answer with the LogoutResponse, /// sent to this endpoint (assuming the /account/logout is /// registered as the logout endpoint in the IdP). /// /// In this app the LogoutRequest sending is handled in the HomeController /// (home/logout) /// /// Scenario 2. /// /// Another application triggers the logout. The server /// gets the LogoutRequest from this another app and /// sends LogoutRequest here. This app is supposed to /// answer with the LogoutResponse. /// /// Both scenarios means that to handle logouts correctly, /// the app has to be able to both send and receive /// both LogoutRequest and LogoutResponse /// </summary> public ActionResult Logout() { var sam2 = new Saml2AuthenticationModule(); var idpCertificate = new ClientCertificateProvider().GetIdPCertificate(); if (sam2.IsLogoutRequest(this.Request) || sam2.IsLogoutResponse(this.Request) ) { // first check if this is a LogoutResponse from the IdP var logoutResponse = new LogoutResponseFactory().From(this.Request); if (logoutResponse != null) { var result = sam2.MessageSigner.Validate(logoutResponse, idpCertificate); if (!result) { throw new ValidationException("The LogoutResponse is not correctly signed with the IdP certificate"); } } // then check if this is a LogoutRequest from the IdP var logoutRequest = new LogoutRequestFactory().From(this.Request); if (logoutRequest != null) { var result = sam2.MessageSigner.Validate(logoutRequest, idpCertificate); if (!result) { throw new ValidationException("The LogoutResponse is not correctly signed with the IdP certificate"); } } // both possibilities were validated // signout can be performed FormsAuthentication.SignOut(); // create the response in case of the LogoutRequest if (logoutRequest != null) { var assertionIssuer = ConfigurationManager.AppSettings["AssertionIssuer"]; var identityProvider = ConfigurationManager.AppSettings["IdentityProvider"]; var x509Configuration = new X509Configuration() { SignatureCertificate = new ClientCertificateProvider().GetClientCertificate(), IncludeKeyInfo = true, SignatureAlgorithm = Signature.SignatureAlgorithm.SHA256 }; var requestBinding = Binding.POST; var logoutResponseFactory = new LogoutResponseFactory(); logoutResponseFactory.Issuer = assertionIssuer; logoutResponseFactory.Destination = identityProvider; logoutResponseFactory.RequestBinding = requestBinding; logoutResponseFactory.X509Configuration = x509Configuration; // mark the response logoutResponseFactory.InResponseTo = logoutRequest.SessionIndex; switch (logoutResponseFactory.RequestBinding) { case Constants.Binding.POST: return(Content(logoutResponseFactory.CreatePostBindingContent())); default: throw new ArgumentException(string.Format("The {0} logout response binding is not supported", logoutResponseFactory.RequestBinding)); } } } // go back to the main page (possibly with logout return(Redirect(FormsAuthentication.DefaultUrl)); }
public IdpInitiatedLogoutResponseHandler(LogoutResponseFactory messageFactory, IEnumerable <ISamlBindingStrategy> bindings) : base(messageFactory, bindings) { }