Search code examples
asp.netitfoxtec-identity-saml2

How to implement single logout using http-redirect


I am using the library ITfoxtec Identity SAML 2.0 to implement SAML 2.0 with an ASP.Net 4.6 MVC App and a 3rd party IdP that only supports http-redirect single logout. I am able to login, but I can't get the single logout to work. The sample only use http-post to logout. Is there any sample code that is publicly available that shows how to implement a single logout using http-redirect?

Thanking you in advance for your help!


Solution

  • Logout with redirect binding can be supported with small changes by changing the binding class Saml2PostBinding to Saml2RedirectBinding. The following is based on the ITfoxtec Identity SAML 2.0 documentation.

    Logout method in the Auth Controller

    [HttpPost("Logout")]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> Logout()
    {
        if (!User.Identity.IsAuthenticated)
        {
            return Redirect(Url.Content("~/"));
        }
    
        var binding = new Saml2RedirectBinding();
        var saml2LogoutRequest = await new Saml2LogoutRequest(config, User).DeleteSession(HttpContext);
        return binding.Bind(saml2LogoutRequest).ToActionResult();
    }
    

    LoggedOut method in the Auth Controller After successfully or failing logout the logged out method receive the response.

    [Route("LoggedOut")]
    public IActionResult LoggedOut()
    {
        var binding = new Saml2RedirectBinding();
        binding.Unbind(Request.ToGenericHttpRequest(), new Saml2LogoutResponse(config));
    
        return Redirect(Url.Content("~/"));
    }
    

    SingleLogout method in the Auth Controller Receives a Single Logout request and send a response.

    [Route("SingleLogout")]
    public async Task<IActionResult> SingleLogout()
    {
        Saml2StatusCodes status;
        var requestBinding = new Saml2RedirectBinding();
        var logoutRequest = new Saml2LogoutRequest(config, User);
        try
        {
            requestBinding.Unbind(Request.ToGenericHttpRequest(), logoutRequest);
            status = Saml2StatusCodes.Success;
            await logoutRequest.DeleteSession(HttpContext);
        }
        catch (Exception exc)
        {
            // log exception
            Debug.WriteLine("SingleLogout error: " + exc.ToString());
            status = Saml2StatusCodes.RequestDenied;
        }
    
        var responsebinding = new Saml2RedirectBinding();
        responsebinding.RelayState = requestBinding.RelayState;
        var saml2LogoutResponse = new Saml2LogoutResponse(config)
        {
            InResponseToAsString = logoutRequest.IdAsString,
            Status = status,
        };
        return responsebinding.Bind(saml2LogoutResponse).ToActionResult();
    }