Access Manager IDP logout does not clear up any session cookies

  • 7024511
  • 27-Mar-2020
  • 30-Apr-2020

Environment

  • Access Manager 4.4
  • Access Manager 4.5

Situation

  • The IDP logout process tries to delete all IDP session cookies which fails with the standard shipped "/opt/novell/nids/lib/webapp/jsp/logoutSuccess_latest.jsp

  • This is more or less a cosmetic issue but can lead into cluster node proxy requests for stale / non existing user sessions. The encrypted "UrnNovellNidpClusterMemberId" cookie defines which cluster node was initially owning the user session and will be used to retrieve already existing user session information. This cookie will be deleted during the IDP logout process

Resolution

  • This issue has been addressed to engineering

  • you can use a custom JSP as listed below.
    Please run this first in your test environment to see if it works as expected

  • In order to run this you need to change the "/opt/novell/nids/lib/webapp/META-INF/context.xml" in order to make sure the "org.apache.tomcat.util.http.LegacyCookieProcessor" will get used. This is required as cookies like ".kgast.nam.local" starting with a "." are not allowed by the standard tomcat cookie handler

    <?xml version="1.0" encoding="UTF-8"?>
    <Context>
        <CookieProcessor className="org.apache.tomcat.util.http.LegacyCookieProcessor" />
        <!-- Disable session persistence across Tomcat restarts -->
        <Manager pathname="" saveOnRestart="false"/>
    </Context>

Cause

  • The standard cookie delete does not provide the path or domain in the set-cookie command. In order to delete a cookie it has to match the name, domain and path

Additional Information



******************************************************************************************
<%@ page language="java" %>
<%@ page pageEncoding="UTF-8" contentType="text/html; charset=UTF-8"%>
<%@ page import="java.util.*" %>
<%@ page import="com.novell.nidp.*" %>
<%@ page import="com.novell.nidp.authentication.local.X509Class" %>
<%@ page import="com.novell.nidp.resource.*" %>
<%@ page import="com.novell.nidp.resource.jsp.*" %>
<%@ page import="com.novell.nidp.ui.*" %>
<%@ page import="com.novell.nidp.sessionassurance.NIDPSessionAssurance" %>
<%@page import="com.novell.nam.nidp.oauth.nidp.authentication.NativeClientPersistentAuthenticationClass"%>

<%
    response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // HTTP 1.1.
    response.setHeader("Pragma", "no-cache"); // HTTP 1.0.
    response.setDateHeader("Expires", 0); // Proxies.

        String FQDN = request.getServerName();
        out.println("<p>Hostname: "+FQDN+"<br>");
        int index = FQDN.indexOf(".");
        String domainName = FQDN.substring(index + 1);
        out.println("Domainname: "+domainName+"</p>");
      
        Cookie cookie = null;
        Cookie[] cookieArray = request.getCookies();
        if( cookieArray != null )
          {

           for (int i = 0; i < cookieArray.length; i++)
           {
            cookie = cookieArray[i];

           if (cookie.getName().equals("JSESSIONID")) {
        //          cookie.setDomain("."+domainName);
                     cookie.setPath("/");
            }
            else if (cookie.getName().equals("UrnNovellNidpClusterMemberId")) {
                     cookie.setDomain(domainName);
                     cookie.setPath("/nidp");
            }
            cookie.setHttpOnly(true);
            cookie.setSecure(true);
            cookie.setMaxAge(0);
            cookie.setValue("false");
            response.addCookie(cookie);
            out.println(" No: " + i + " Cookie: " + cookie.getName()+" deleted: <br>");
           }
         }

       else
        {
        out.println("cookies Not Found");
        }
    com.novell.nidp.authentication.local.PersistenceAuthClass.clearCookie(request,response);
    NativeClientPersistentAuthenticationClass.clearCookie(request, response);
    {
    final Cookie newCookie = new Cookie("_PA_SDK_SSO_", "");
        newCookie.setMaxAge(0);
        newCookie.setPath("/nidp/");
        response.addCookie(newCookie);
    }
    NIDPSessionAssurance nidpSessAssurance = NIDPSessionAssurance.getInstance();
    nidpSessAssurance.clearIDCCookie(request,response);
    response.setHeader("Connection", "close");
    UIHandler uh = new UIHandler(request,response);
    ArrayList logoutStrings = null;
    ArrayList logos = null;
    if (uh.isJSPMsg())
    {
        NIDPLogoutMessage msg =
            (NIDPLogoutMessage)uh.getMessage(true);

        if (msg.isConfirmLogouts())
        {
            logoutStrings = ((NIDPLogoutMessage)msg).getStrings();
               logos = ((NIDPLogoutMessage)msg).getLogos();
        }
    }

%>
    <table border=0>
<%
    if (logos != null && logos.size() > 0)
    {
%>
            <tr>
            <td>
                    <table cellSpacing=7 cellPadding=0 align=left border=0>
                        <tr>
                            <td width=15><img height=1 src="<%=uh.getImage("spacer.gif",false)%>" width=15 border=0 alt=""></td>
                            <td colspan="2"><b><%=uh.getResource(JSPResDesc.LOGOUT_SITES)%></b></td>
                        </tr>
        <%
                for (int i = 0; i < logos.size(); i++)
                {
        %>
                        <tr>
                            <td width="15"><img height=1 src="<%=uh.getImage("spacer.gif",false)%>" width=15 border=0 alt=""></td>
                                        <td class=leadCopy><%= (String)logos.get(i) %></td>
                                        <%
                                                String s = (String)logoutStrings.get(i);
                                                if((s != null) && (s.indexOf("?") != -1))
                                                {
                                        %>
                                                <td><iframe id="remoteContent" src="<%= s %>"  WIDTH=0 HEIGHT=0 frameborder=0></iframe> </td>
                                        <%
                                                }
                                                else
                                                {
                                        %>
                                                <td><img alt="<%=uh.getResource(JSPResDesc.LOGOUT)%>" src="<%= s %>"/></td>
                                        <%
                                                }
                                        %>
                                </tr>
        <%
                }
        %>
 
                    </table>
                  </td>
            </tr>
<%    } %>
        </table>
<% request.getSession().invalidate(); %>
******************************************************************************************

Note: comment out the "out.println" lines which have been added for debugging