Sunday, October 27, 2013

Non-programmatic Authentication Using Login Form in JSF (For WebCenter & ADF)

My previous post described a scenario that the OAM DCC programmatic authentication is not supported yet, and here I am presenting a nice alternative to do the DCC authentication non-programmatically.

You may have a read on Frank's book "Oracle Fusion Developer Guide" and there is a section in the ADF security talking about "Creating a login form in JSF" programmatically. This approach works for JEE contained security but would not work well with your WebCenter Portal or ADF app integrated with OAM authentication. I am introducing an approach that does not require any programmatic authentication and can be used safely with any type of authentications (contained security or OAM authentication).

Note: You can create HTML form in JSF but there are many limitations, such as only one form component can be allowed in a page. Due to this, it's impossible to support a complicated login page in JSF. It induced extra pitfalls and challenges on the skinning as well.

If you create a WebCenter Portal application in Jdeveloper, you will have a loginProxy.jspx page already created in your application. This loginProxy.jspx is our solution here. This pre-built page is coded in HTML form and I experienced in some cases it is not well supported for WebCenter portal applications, although it does seem ok with a pure ADF application (this page is not shipped with an ADF fusion application, so you have to create it for ADF app). I would recommend to re-code this page using ADF Faces component.

The process flow is simple:

1. Create an actual login page in JSF (.jspx) page. In this JSF page, it contains the input text for user name, password and a button for submit/login. All these components are coded with ADF faces components. In the value fields, specify a parameter in request scope so they can be passed onto the loginProxy page.



2. Re-code the loginProxy.jspx page using <f:verbatim> which will wrap the form post with the username/password parameters passed from login page. Depending on the authentication type, you may have different form post actions. This page uses the JavaScript to auto submit the form.

For JEE contained security:
 <?xml version='1.0' encoding='UTF-8'?>
 <jsp:root xmlns:jsp="http://java.sun.com/JSP/Page" version="2.1" xmlns:f="http://java.sun.com/jsf/core"
      xmlns:af="http://xmlns.oracle.com/adf/faces/rich">
  <jsp:directive.page contentType="text/html;charset=UTF-8"/>
  <f:view>
   <af:document title="login" id="d1">
    <af:clientListener method="formSubmit" type="load"/>
    <af:resource type="javascript">
     function formSubmit(evt) {
       var form = document.getElementById("loginData");
       form.submit();
     }
    </af:resource>
    <f:verbatim>
     <form id="loginData" name="loginData" method="POST" action="j_security_check">
      <input id="userid" type="hidden" name="j_username" value="${requestScope.userid}"/>
      <input id="password" type="hidden" name="j_password" value="${requestScope.password}"/>
     </form>
    </f:verbatim>
   </af:document>
  </f:view>
 </jsp:root>

For OAM authentication:
 <?xml version='1.0' encoding='UTF-8'?>  
 <jsp:root xmlns:jsp="http://java.sun.com/JSP/Page" version="2.1" xmlns:f="http://java.sun.com/jsf/core"  
      xmlns:af="http://xmlns.oracle.com/adf/faces/rich">  
  <jsp:directive.page contentType="text/html;charset=UTF-8"/>  
  <f:view>  
   <af:document title="login" id="d1">  
    <af:clientListener method="formSubmit" type="load"/>  
    <af:resource type="javascript">  
     function formSubmit(evt) {  
       var form = document.getElementById("loginData");  
       form.submit();  
     }  
    </af:resource>  
    <f:verbatim>  
     <form id="loginData" name="loginData" method="POST" action="/oam/server/auth_cred_submit">  
      <input id="userid" type="hidden" name="userid" value="${requestScope.userid}"/>  
      <input id="password" type="hidden" name="password" value="${requestScope.password}"/>  
     </form>  
    </f:verbatim>  
   </af:document>  
  </f:view>  
 </jsp:root>  

3. Last step is to create a navigation rule from login page to loginProxy page. The navigation rule is specified in the "login" button on the login page.


This approach avoids the programmatic authentication and works great for having a custom login page developed in WebCenter Portal integrated with OAM authentication. It works for both ECC and DCC authentication. As of now, the programmatic authentication on OAM DCC is not supported, so this approach fits right in the gap.

No comments: