Sustainsys / Saml2

Saml2 Authentication services for ASP.NET
Other
961 stars 603 forks source link

Support Logout over SOAP #1118

Open ricardosaracino opened 5 years ago

ricardosaracino commented 5 years ago

Non Security Issues

IDP initiated SOAP Logout doesnt seem to log user out, i noticed that the IDP has a error in the Federation log (opensso). I need to support both redirect and soap

code is https://github.com/ricardosaracino/SamlOwin

Debug Output

Sustainsys.Saml2.Owin.Saml2AuthenticationMiddleware Verbose: 0 : Expanded Saml2Url
  AssertionConsumerServiceUrl: https://dev-ep-pe.csc-scc.gc.ca/api/saml/Acs
  SignInUrl: https://dev-ep-pe.csc-scc.gc.ca/api/saml/SignIn
  LogoutUrl: https://dev-ep-pe.csc-scc.gc.ca/api/saml/Logout
  ApplicationUrl: https://dev-ep-pe.csc-scc.gc.ca/
Sustainsys.Saml2.Owin.Saml2AuthenticationMiddleware Verbose: 0 : Initiating logout, checking requirements for federated logout
  Issuer of LogoutNameIdentifier claim (should be Idp entity id): http://idp5.canadacentral.cloudapp.azure.com:80/opensso
  Issuer is a known Idp: True
  Session index claim (should have a value): http://Sustainsys.se/Saml2/SessionIndex: s2b638d0977a633e90e067b8bc5cb18aa9bd77eb01
  Idp has SingleLogoutServiceUrl: http://idp5.canadacentral.cloudapp.azure.com:80/opensso/IDPSloRedirect/metaAlias/idp
  There is a signingCertificate in SPOptions: True
  Idp configured to DisableOutboundLogoutRequests (should be false): False
Sustainsys.Saml2.Owin.Saml2AuthenticationMiddleware Information: 0 : Sending logout request to http://idp5.canadacentral.cloudapp.azure.com:80/opensso
Sustainsys.Saml2.Owin.Saml2AuthenticationMiddleware Verbose: 0 : Expanded Saml2Url
  AssertionConsumerServiceUrl: https://dev-ep-pe.csc-scc.gc.ca/api/saml/Acs
  SignInUrl: https://dev-ep-pe.csc-scc.gc.ca/api/saml/SignIn
  LogoutUrl: https://dev-ep-pe.csc-scc.gc.ca/api/saml/Logout
  ApplicationUrl: https://dev-ep-pe.csc-scc.gc.ca/
Sustainsys.Saml2.Owin.Saml2AuthenticationMiddleware Verbose: 0 : Initiating logout, checking requirements for federated logout
  Issuer of LogoutNameIdentifier claim (should be Idp entity id): http://idp5.canadacentral.cloudapp.azure.com:80/opensso
  Issuer is a known Idp: True
  Session index claim (should have a value): http://Sustainsys.se/Saml2/SessionIndex: s2b638d0977a633e90e067b8bc5cb18aa9bd77eb01
  Idp has SingleLogoutServiceUrl: http://idp5.canadacentral.cloudapp.azure.com:80/opensso/IDPSloRedirect/metaAlias/idp
  There is a signingCertificate in SPOptions: True
  Idp configured to DisableOutboundLogoutRequests (should be false): False
Sustainsys.Saml2.Owin.Saml2AuthenticationMiddleware Information: 0 : Sending logout request to http://idp5.canadacentral.cloudapp.azure.com:80/opensso

IDP Metadata

<SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"                             Location="http://idp5.canadacentral.cloudapp.azure.com:80/opensso/IDPSloRedirect/metaAlias/idp"/>

<SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP"                           Location="http://idp5.canadacentral.cloudapp.azure.com:80/opensso/IDPSloSoap/metaAlias/idp"/>

IDP Error Message

ERROR: Unable to send SOAPMessage to IDP
com.sun.xml.messaging.saaj.SOAPExceptionImpl: com.sun.xml.messaging.saaj.SOAPExceptionImpl: Bad response: (303See Other

Information needed

  1. What nuget packages are you using package id="Sustainsys.Saml2" version="2.3.0" targetFramework="net48" package id="Sustainsys.Saml2.Owin" version="2.3.0" targetFramework="net48" package id="Microsoft.AspNet.Identity.Owin" version="2.2.2" targetFramework="net48" package id="Microsoft.AspNet.Mvc" version="5.2.7" targetFramework="net48"

  2. What is the expected behaviour I would expect the user to be logged out

  3. What happens instead. User Remains logged in

Additional info

Please include

ricardosaracino commented 5 years ago

saml2Binding is always null in LogoutCommand.CommandResult

 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));
      Uri returnUrl = LogoutCommand.GetReturnUrl(request, returnPath, options);
// this is always NULL
      Saml2Binding saml2Binding = options.Notifications.GetBinding(request);
      CommandResult commandResult;
      if (saml2Binding != null)
AndersAbel commented 5 years ago

Logout over SOAP is not supported by the library. Implementing it would be quite complex as the session is normally handled by cookies on the client. A logout is done by deleting the cookie. So to be able to do a logout, there must be a front-channel request.

Implementing logout would require some kind of cache holding a list of black-listed sessions that then would be killed on the next request. Is this something you really need? Or can you stick with logout over redirect/POST? Please also note that the metadata generated does not expose SOAP as an accepted binding for the logout endpoing.

ricardosaracino commented 5 years ago

its unfortunately mandated for use, i am going to look for an exception. I did wip up a prototype, https://github.com/ricardosaracino/SamlOwin/blob/master/SamlOwin/ActionFilters/SessionActionFilter.cs