Implementing Single LogOut using OneLogin SAML

In my last blog, I have explained the implementation of Single Sign-on(SSO) using OneLogin SAML. Probably you should have gone through the previous blog about Single Sign- in. Now, we are going to focus on implementing Single Logout using OneLogin SAML. Well, I have skipped some of the basic steps that are common to both processes which I had already explained on the previous blog.  So it would be easier for both of us to go with the flow if you can refer the previous one. If not, please check it out here.

As the name indicates, it is all about log out. The Single Logout (SLO) enables a user to log out simultaneously from all the applications in a created session. Besides, we know that OneLogin supports both SP-initiated Single Logout and IdP-Initiated Single Logout.

SP-Initiated Single Logout:

 

If we logged out of our application then automatically the Idp (Onelogin) account will be logged out.

In case, if you are new to Onelogin. Here You Go

IdP-Initiated Single Logout:

 

if we logged out of IdP, then it will clear the session and automatically you will get logged out from all the applications.

First, Let us implement the client side part.

Method 1

 

This method will generate and send a SAML(Security Assertion Markup Language)  Logout Request to the IdP. Now, the IdP will authenticate the request and will send the response back.

 


# SP initiated Logout Request
def sp_initiated_logout_request
saml_settings = saml_sso_settings
if saml_settings.idp_slo_target_url.nil?
logger.info "Single Logout IdP Endpoint not found, execute normal logout"
reset_session
else
sp_logout_request = OneLogin::RubySaml::Logoutrequest.new()
# As we are creating a new SAML request, save the transaction_id
# to compare it with the response we get back
session[:transaction_id] = sp_logout_request.uuid

if saml_settings.name_identifier_value.nil?
saml_settings.name_identifier_value = session[:user_id] end

relayState = “Url to redirect to login page”
redirect_to(sp_logout_request.create(saml_settings, :RelayState => relayState))
end
end

 

 

 

Method 2

 

This method will process the response sent by IdP as a reply to proceed logout request. So, here we have to verify and validate the request to delete our sessions that lead to log out of all the applications.

 


def process_logout_response_from_idp
settings = saml_sso_settings

if session.has_key? "transaction_id"
sp_logout_response = OneLogin::RubySaml::Logoutresponse.new(params[:SAMLResponse], settings, :matches_request_id => session[:transaction_id])
else
sp_logout_response = OneLogin::RubySaml::Logoutresponse.new(params[:SAMLResponse], settings)
end

# Validate the SAML Logout Response
if sp_logout_response.validate
# log out this session
logger.info "Delete session for '#{session[:user_id]}'"
reset_session
else
logger.error "The SAML Logout Response is invalid"
end
end

 

 

Method 3

 

 

The above two methods will handle the SP initiated log out, and the below method will handle the IdP initiated log out. First, the IdP will send the logout request then our method will validate the request & clears the session and sends the response back to IdP.

 

Initially, the IdP will send the logout request. Later, our method will validate the request & clear the session then sends the response back to IdP.

 

 


def idp_initiated_logout_request
saml_settings = saml_sso_settings
idp_logout_request = OneLogin::RubySaml::SloLogoutrequest.new(params[:SAMLRequest])
unless idp_logout_request.is_valid?
logger.error "IdP initiated LogoutRequest was not valid!"
render :inline => logger.error
end
# log out this session
reset_session

# Generate a response to the IdP.
idp_logout_request_id = idp_logout_request.id
idp_logout_response = OneLogin::RubySaml::SloLogoutresponse.new.create(saml_settings, idp_logout_request_id, nil, :RelayState => params[:RelayState])
redirect_to idp_logout_response
end

 

 

 Another way to handle all the methods in single common method

 

Method 4

All the above methods could be handled in a single common method as follows. Finally, give this URL as an SLO URL in one login connector.

 


def logout
# Handle the logout request created by IdP
if params[:SAMLRequest] return idp_initiated_logout_request
# Handle the response given back from IdP for sp initiated logout
elsif params[:SAMLResponse] return process_logout_response_from_idp
# Initiating logout from sp
else
return sp_initiated_logout_request
end
end

 

 The client-side part is finished. Now, we have to add the SLO URL in OneLogin connector then finally save it.

 

logout

Now you can test the SP initiated log out and IdP initiated log out.

Successfully you will be logged out from all the application.

 

Conclusion

 

Hope now you have a clear idea about the implementation of SSO and SLO. For doubts or queries, please comment below. And if you are looking forward to more technical blogs about web development and mobile app development follow Agira Technologies a fast growing IT company, exploring upcoming technologies and exposing everything to help the right people at right time. For more queries always reach us.  We love to hear from you!