Wednesday, January 19, 2011

Solutions to issue “Using back button upon authentication via SAML SSO gives HTTP 404”

Typically Achieving SSO using SAML 1.1 between two applications deployed to WebLogic domains involves configuring
  1.  Identity Asserter (IA) on Destination  WebLogic domain
  2. Credential Mapper (CM) on the Source WebLogic domain
Details on how to achieve SSO using SAML 1.1 is not the intent of this article, hence this articles just focuses on one of the major issue that is faced with SSO using SAML 1.1. Assuming that with the required IA and CM configuration settings done on the source and  the destination WebLogic domains , SSO using SAML 1.1 starts working. Users can login to one application and they are logged into the other application via SSO using SAML 1.1.
So far so good, but after a user logs in onto the landing page of any of the application  and hits back button of the browser, they encounter HTTP 404 error.
The solution provided below solves the problem:
  1. Deploy the attached web appliation saml_acs.war to all the WebLogic domains configured to be SAML 1.1 destinations    
  2. Target saml_acs.war to the cluster
  3. Set the system flags like below. Set the flag on all the servers in the domain and restart them for the system flags to take effect.
  4. -Dsaml_acs.redirect.url=http(s)://<hostname>:<port>/<landing page>
  5. In the WLS admin console update all the servers
    • Navigate to the “Server name -> Configuration -> Federation Services -> SAML 1.1 Destination Site” tab
    • Change the “Assertion Consumer URI” to “/saml_acs/acs”
    • This requires a restart


    saml_acs.war
    -web-inf
    --web.xml
     <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">
    <web-app>
         <error-page>
            <error-code>404</error-code>
            <location>/redirect.jsp</location>
        </error-page>
    </web-app>

    --weblogic.xml
    <!DOCTYPE weblogic-web-app PUBLIC "-//BEA Systems, Inc.//DTD Web Application 8.1//EN" "http://www.bea.com/servers/wls810/dtd/weblogic810-web-jar.dtd">
    <weblogic-web-app>
      </weblogic-web-app>


    meta-inf

    redirect.jsp
    <%@page import="javax.servlet.http.*"%>

    <%
    /*
    This jsp helps in handing 404 http error that occurs when a user
    authenticates to portal desktop via saml for the first time and
    hits the browser back button.
    set the system property = the portal url like the default property value shown below

    Example:
    -Dsaml_acs.redirect.url="https://<hostname>:<port>/<default landing page if required>"
    */

    String newLocation=System.getProperty("saml_acs.redirect.url","/default landing page");
    response.sendRedirect(newLocation);
    %>












    Thursday, January 13, 2011

    Coherence *Web Session Attribute Scoping examples

    One among the many features of Oracle Coherence *Web is to "Enables session sharing and management across different web applications, domains and heterogeneous application servers".


    Picture 1: Typical Web Session object sharing topology


    Below are the three typical scenarios of sharing of session data by web applications.



    Scenario 1) Sharing of session data and attributes by two web applications (.war) deployed across WebLogic application servers.



    Scenario 2) Sharing of session data and attributes by two web applications (.war) contained in two separate Enterprise application (.ear)


    Scenario 3) Sharing of session data and attributes by two web applications (.war) contained in a single Enterprise application (.ear)


    The following steps provide an example for each of the above scenario.



    Before executing the examples below, prepare your environment 


    1) Download coherence 3.6.x from
    http://www.oracle.com/technetwork/middleware/coherence/downloads/index.html
    2) Extract the downloaded zip to say c:\cohrence361
    3) Create startcoherence.cmd file under c:\cohrence361 and copy the contents between "CUT"  into it.

    --------CUT-----

    setlocal
    if (%COHERENCE_HOME%)==() (
        set COHERENCE_HOME=C:\coherence361
    )
    set COH_OPTS=%COH_OPTS% -server -cp C:\coherence361\lib\coherence.jar;C:\coherence361\lib\coherence-web-spi.war;
    set COH_OPTS=%COH_OPTS% -Dtangosol.coherence.management.remote=true -Dtangosol.coherence.cacheconfig=/WEB-INF/classes/session-cache-config.xml -Dtangosol.coherence.session.localstorage=true
    java %COH_OPTS% -Xms512m -Xmx512m com.tangosol.net.DefaultCacheServer
    :exit
    --------CUT-----


    4) from windows cmd> startcoherence.cmd. This starts the cohrence cache server.


    5) Install Oracle WebLogic Server 10.3.3 by downloading from here


    http://www.oracle.com/technetwork/middleware/weblogic/overview/index.html


    6) Using WebLogic Domain config wizard (<W_HOME>\wlserver_10.3\common\bin\config.cmd, create a domain with three servers


    a. AdminServer  (listening on port 7001)
    b. ManagedServer1 (listening on port 7003)
    c. ManagedServer2 (listening on port 7005)


    7) Deploy C:\coherence361\lib\coherence-web-spi.jar as a Shared module to the above domain and target it to  ManagedServer1, ManagedServer2


    8)  Using Oracle Enterprise pack for Eclipse IDE (OEPE), create two dynamic web projects with the following contents.


    webproject1
    web.xml


    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
      <display-name>webproject1
    </display-name>
      <context-param>
      <param-name>coherence-scopecontroller-class</param-name>
      <param-value>com.tangosol.coherence.servlet.AbstractHttpSessionCollection$GlobalScopeController</param-value>
      </context-param>
    </web-app>
    weblogic.xml
    <?xml version="1.0" encoding="UTF-8"?>
    <wls:weblogic-web-app xmlns:wls="http://xmlns.oracle.com/weblogic/weblogic-web-app" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd http://xmlns.oracle.com/weblogic/weblogic-web-app http://xmlns.oracle.com/weblogic/weblogic-web-app/1.0/weblogic-web-app.xsd">
        <wls:weblogic-version>10.3.2</wls:weblogic-version>
        <wls:context-root>webproject1</wls:context-root>
        <wls:library-ref>
            <wls:library-name>coherence-web-spi</wls:library-name>
            <wls:specification-version>1.0.0.0</wls:specification-version>
           <wls:implementation-version>1.0.0.0</wls:implementation-version>      
        <wls:exact-match>true</wls:exact-match>
        </wls:library-ref>
    </wls:weblogic-web-app>



    WebContent/counter.jsp


    <%@ page language="java" contentType="text/html; charset=ISO-8859-1"
        pageEncoding="ISO-8859-1"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
    <title>Insert title here</title>
    </head>
    <body>

    <h3>
          Counter :
          <%
             Integer counter = new Integer(1);
             HttpSession httpsession = request.getSession(true);
             if (httpsession.isNew()) {
                    httpsession.setAttribute("count", counter);
                    out.println(counter);
             } else {
                    int count = ((Integer) httpsession.getAttribute("count")).intValue();
                    httpsession.setAttribute("count", new Integer(++count));
                    out.println(count);
             }
          %>
          </h3>
    </body>
    </html>



    webproject2

    web.xml


    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
      <display-name>webproject2
    </display-name>
      <context-param>
      <param-name>coherence-scopecontroller-class</param-name>
      <param-value>com.tangosol.coherence.servlet.AbstractHttpSessionCollection$GlobalScopeController</param-value>
      </context-param>
    </web-app>

    weblogic.xml


    <?xml version="1.0" encoding="UTF-8"?>
    <wls:weblogic-web-app xmlns:wls="http://xmlns.oracle.com/weblogic/weblogic-web-app" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd http://xmlns.oracle.com/weblogic/weblogic-web-app http://xmlns.oracle.com/weblogic/weblogic-web-app/1.0/weblogic-web-app.xsd">
        <wls:weblogic-version>10.3.2</wls:weblogic-version>
        <wls:context-root>webproject2</wls:context-root>
        <wls:library-ref>
            <wls:library-name>coherence-web-spi</wls:library-name>
            <wls:specification-version>1.0.0.0</wls:specification-version>
           <wls:implementation-version>1.0.0.0</wls:implementation-version>      
        <wls:exact-match>true</wls:exact-match>
        </wls:library-ref>
    </wls:weblogic-web-app>




    WebContent/counter.jsp


    <%@ page language="java" contentType="text/html; charset=ISO-8859-1"
        pageEncoding="ISO-8859-1"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
    <title>Insert title here</title>
    </head>
    <body>
    <h3>
          Counter :
          <%
             Integer counter = new Integer(1);
             HttpSession httpsession = request.getSession(true);
             if (httpsession.isNew()) {
                    httpsession.setAttribute("count", counter);
                    out.println(counter);
             } else {
                    int count = ((Integer) httpsession.getAttribute("count")).intValue();
                    httpsession.setAttribute("count", new Integer(++count));
                    out.println(count);
             }
          %>
          </h3>
    </body>
    </html>



    9) From OEPE export the projects created in step #8 as webproject1.war and webproject2.war



    Example for Scenario 1
    1) Shut down all the weblogic server instances of the weblogic domain if they are running.
    2) Copy C:\coherence361\lib\coherence.jar to under <weblogic domain>/lib directory or configure in the WebLogic system classpath. The placement of coherence.jar under  <weblogic domain>/lib  is really important when web projects deployed across WebLogic Aplication Server (Separate JMV instances) need to share session objects
    3) Start all the three weblogic server instances
    4) Deploy webproject1.war and webproject2.war and target the deployment to ManagedServer1 and ManagedServer2
    5) Execute the following test case and observe that the session attribute "count" is shared between webproject1 and webproject2


    Scenario 1 Test case:

    1) open IE and access the url http://localhost:7003/webproject1/counter.jsp
    Count =1
    2) open another browser (firefox) and access the url  http://localhost:7005/webproject2/counter.jsp
    Count =2 (count is 2 as webproject2 adds 1 to the counter value set by webproject2
    3) Try opening multiple sessions by changing the port numbers and browsers and observe that the session attribute count is getting shared between two webprojects using Coherence *Web SPI