private static CommandResult HandleRequest(UnbindResult unbindResult, IOptions options) { var request = Saml2LogoutRequest.FromXml(unbindResult.Data); var idp = options.IdentityProviders[request.Issuer]; if (options.SPOptions.SigningServiceCertificate == null) { throw new ConfigurationErrorsException(string.Format(CultureInfo.InvariantCulture, "Received a LogoutRequest from \"{0}\" but cannot reply because single logout responses " + "must be signed and there is no signing certificate configured. Looks like the idp is " + "configured for Single Logout despite AuthServices not exposing that functionality in the metadata.", request.Issuer.Id)); } if (idp.SingleLogoutServiceResponseUrl == null) { throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "Received a LogoutRequest from \"{0}\" but cannot reply because on logout endpoint is " + "configured on the idp. Set a SingleLogoutServiceUrl if the idp is configured manually, " + "or check that the idp metadata contains a SingleLogoutService endpoint.", idp.EntityId.Id)); } var response = new Saml2LogoutResponse(Saml2StatusCode.Success) { DestinationUrl = idp.SingleLogoutServiceResponseUrl, SigningCertificate = options.SPOptions.SigningServiceCertificate, SigningAlgorithm = idp.OutboundSigningAlgorithm, InResponseTo = request.Id, Issuer = options.SPOptions.EntityId, RelayState = unbindResult.RelayState }; options.SPOptions.Logger.WriteInformation("Got a logout request " + request.Id + ", responding with logout response " + response.Id); var result = Saml2Binding.Get(idp.SingleLogoutServiceBinding).Bind(response); result.TerminateLocalSession = true; return(result); }
private static CommandResult InitiateLogout(HttpRequestData request, string returnPath, IOptions options) { var idpEntityId = ClaimsPrincipal.Current.FindFirst(AuthServicesClaimTypes.LogoutNameIdentifier)?.Issuer ?? ClaimsPrincipal.Current.FindFirst(ClaimTypes.NameIdentifier)?.Issuer; CommandResult commandResult; IdentityProvider idp; if (idpEntityId != null && options.IdentityProviders.TryGetValue(new EntityId(idpEntityId), out idp) && ClaimsPrincipal.Current.FindFirst(AuthServicesClaimTypes.SessionIndex) != null && idp.SingleLogoutServiceUrl != null && options.SPOptions.SigningServiceCertificate != null && !idp.DisableOutboundLogoutRequests) { var logoutRequest = idp.CreateLogoutRequest(); commandResult = Saml2Binding.Get(Saml2BindingType.HttpRedirect) .Bind(logoutRequest); commandResult.RequestState = new StoredRequestState( idp.EntityId, GetReturnUrl(request, returnPath, options), logoutRequest.Id, null); commandResult.SetCookieName = "Kentor." + logoutRequest.RelayState; } else { commandResult = new CommandResult { HttpStatusCode = HttpStatusCode.SeeOther, Location = GetReturnUrl(request, returnPath, options) }; } commandResult.TerminateLocalSession = true; return(commandResult); }
public CommandResult Run(HttpRequestData request, IOptions options) { if (request == null) { throw new ArgumentNullException("request"); } if (options == null) { throw new ArgumentNullException("options"); } var binding = Saml2Binding.Get(request); if (binding != null) { try { var samlResponse = Saml2Response.Read(binding.Unbind(request)); return(ProcessResponse(options, samlResponse)); } catch (FormatException ex) { throw new BadFormatSamlResponseException( "The SAML Response did not contain valid BASE64 encoded data.", ex); } catch (XmlException ex) { throw new BadFormatSamlResponseException( "The SAML response contains incorrect XML", ex); } } throw new NoSamlResponseFoundException(); }
public static CommandResult Run( HttpRequestData request, string returnPath, IOptions options) { if (request == null) { throw new ArgumentNullException(nameof(request)); } if (options == null) { throw new ArgumentNullException(nameof(options)); } var binding = Saml2Binding.Get(request); if (binding != null) { var unbindResult = binding.Unbind(request, options); VerifyMessageIsSigned(unbindResult, options); switch (unbindResult.Data.LocalName) { case "LogoutRequest": return(HandleRequest(unbindResult, options)); case "LogoutResponse": return(HandleResponse(unbindResult, request)); default: throw new NotImplementedException(); } } return(InitiateLogout(request, returnPath, options)); }
private static CommandResult InitiateLogout(HttpRequestData request, Uri returnUrl, IOptions options) { string idpEntityId = null; Claim sessionIndexClaim = null; if (request.User != null) { idpEntityId = request.User.FindFirst(AuthServicesClaimTypes.LogoutNameIdentifier)?.Issuer; sessionIndexClaim = request.User.FindFirst(AuthServicesClaimTypes.SessionIndex); } IdentityProvider idp; var knownIdp = options.IdentityProviders.TryGetValue(new EntityId(idpEntityId), out idp); options.SPOptions.Logger.WriteVerbose("Initiating logout, checking requirements for federated logout" + "\n Issuer of LogoutNameIdentifier claim (should be Idp entity id): " + idpEntityId + "\n Issuer is a known Idp: " + knownIdp + "\n Session index claim (should have a value): " + sessionIndexClaim + "\n Idp has SingleLogoutServiceUrl: " + idp?.SingleLogoutServiceUrl?.OriginalString + "\n There is a signingCertificate in SPOptions: " + (options.SPOptions.SigningServiceCertificate != null) + "\n Idp configured to DisableOutboundLogoutRequests (should be false): " + idp?.DisableOutboundLogoutRequests); CommandResult commandResult; if (idpEntityId != null && knownIdp && sessionIndexClaim != null && idp.SingleLogoutServiceUrl != null && options.SPOptions.SigningServiceCertificate != null && !idp.DisableOutboundLogoutRequests) { var logoutRequest = idp.CreateLogoutRequest(request.User); commandResult = Saml2Binding.Get(idp.SingleLogoutServiceBinding) .Bind(logoutRequest); commandResult.RelayState = logoutRequest.RelayState; commandResult.RequestState = new StoredRequestState( idp.EntityId, returnUrl, logoutRequest.Id, null); if (!options.SPOptions.Compatibility.DisableLogoutStateCookie) { commandResult.SetCookieName = "Kentor." + logoutRequest.RelayState; } options.SPOptions.Logger.WriteInformation("Sending logout request to " + idp.EntityId.Id); } else { commandResult = new CommandResult { HttpStatusCode = HttpStatusCode.SeeOther, Location = returnUrl }; options.SPOptions.Logger.WriteInformation("Doing a local only logout."); } commandResult.TerminateLocalSession = true; return(commandResult); }