Monday, March 3, 2025

Implementing JCaptcha on PeopleSoft login page

 

Implementing JCaptcha on PeopleSoft login page

Step1:
From the JCaptcha 2.0 war file, extract the 6 jar files highlighted in the screenshot below and place them in the lib directory of the PeopleSoft Webserver - 
In your case the lib directory will be at this location - 
 <%PS_HOME%>\webserv\<domain>\applications\peoplesoft\PORTAL.war\WEB-INF\lib  
We need only the servlet class file (SimpleImageCaptchaServlet.class) from the 7th jar file of the war file. This is the class that renders the Captcha image.
Copy/Extract the class file to this location -

 <%PS_HOME%>\webserv\<domain>\applications\peoplesoft\PORTAL.war\WEB-INF\classes\com\octo\captcha\module\servlet\image  
 in my case  
 C:\psoft\pt85302\webserv\hcm92dmo\applications\peoplesoft\PORTAL.war\WEB-INF\classes\com\octo\captcha\module\servlet\image  
Note: You will have to create these folders (octo\captcha\module\servlet\image) as it won't exist.

Step2:
Now navigate to the WEB-INF folder and open the deployment descriptor file - web.xml and add the code below -

    <servlet>  
        <servlet-name>jcaptcha</servlet-name>  
        <servlet-class>com.octo.captcha.module.servlet.image.SimpleImageCaptchaServlet</servlet-class>  
    </servlet>  
   <servlet-mapping>  
       <servlet-name>jcaptcha</servlet-name>  
       <url-pattern>/chitra_durga.jpg/*</url-pattern>  
   </servlet-mapping>  
You may change the servlet mapping as per your wish.

Verification: If you have successfully executed these steps you can restart the webserver and do a quick test by accessing the servlet that renders the captcha image as shown below.

You will have to repeat the steps henceforth for each domain (in case of multiple domains)

Step-3:
  • Before customizing the files signin.html, text.properties and error.properties, make a backup for restoration purposes. The files can be found here -
     <%PS_HOME%>webserv\<Domain>\applications\peoplesoft\PORTAL.war\WEB-INF\psftdocs\<Domain>  
    
    Open the signin.html file in a text editor and add the following code after the <HEAD> tag
    <META HTTP-EQUIV="CACHE-CONTROL" CONTENT="NO-CACHE">  
    
  • In the JavaScript section add the Ajax code below
     <!--  Ajax function to refresh the captcha image -->  
     <script>  
     function chitra()  
     {  
     var xmlhttp;  
     if (window.XMLHttpRequest)  
      {// code for IE7+, Firefox, Chrome, Opera, Safari  
      xmlhttp=new XMLHttpRequest();  
      }  
     else  
      {// code for IE6, IE5  
      xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");  
      }  
     xmlhttp.onreadystatechange=function()  
      {  
       if (xmlhttp.readyState==4 && xmlhttp.status==200)  
       {  
       document.getElementById("sampige").src="/chitra_durga.jpg?r="+new Date().getTime();  
       }  
      }  
     xmlhttp.open("GET","/chitra_durga.jpg",true);  
     xmlhttp.send();  
     }  
     </script>  
     
    
  • After this, search for the form tag element and modify/replace the action attribute to call the custom Captcha validation JSP as opposed to the PeopleSoft delivered psp servlet as shown below
     <form aaction="<%=psCtxPath%><%=psHome%>/Rao99.jsp" method="post" id="login" name="login" autocomplete="off" onSubmit="<%=psCtxPath%><%=psHome%>/Rao99.jsp">   
    
  • The next piece of customization on the signin html file is to bring in the captcha elements i.e captcha image, refresh icon to refresh the captcha image and a text box to capture the verification code entered by the user. The sample code from my signin page is shown below. Place this code below the "pwd" element.
     <!-- Code Begin Captcha elements-->  
     <tr>  
     <td height="35"><img src="/chitra_durga.jpg" alt="<%=20000%>" id='sampige' width="175" height="65" />&nbsp;</td>  
     <td height="35" align='middle'>  
      <img src="<%=psCtxPath%><%=psHome%>/images/PT_REFRESH_ICN.gif" alt="Refresh" width="16" height="16" onclick="chitra()" />  
      &nbsp;</td>  
     <td height="35"><input type = "text" name="jcaptcha" placeholder="<%=20000%>" class="pslogineditbox" tabindex="4"></td>  
     </tr>  
     
    
    You would have noticed that I have used scriptlet with the number 20000 in a couple of tags. This is the message number that serves as the alternate text for the captcha image as well as the default message shown in the text box provided for the user to key in the captcha verification code. This message text is defined in the text.properties file. The Ajax function chitra() that is triggered upon clicking the refresh icon in turn triggers the Java servlet "chitra_durga.jpg". The servlet generates and streams a fresh captcha image to the client browser.
  • The last piece of customization on the signin html file is to modify the submit button action. Search for the input tag with type "Submit" and modify the code as given here
     <td height="35"><input name="Submit" type="submit" class="psloginbutton" tabindex="4" value="<%=137%>" onclick="<%=psCtxPath%><%=psHome%>/Rao99.jsp"></td>  
    
  • Open the text.properties file and add the code below at the very bottom
     # Using 20000 and above for custom messages  
     20000=Enter the verification code appearing in the image  
    
  • I also need to display a custom error message if the captcha validation fails. To do this open the error.properties file and add the code below at the very bottom
     # Using 20000 and above for custom messages  
     20001=Verification code is required.  
     20002=Invalid verification code. Please try again.  
     20003=Verification failed.  
    

Step-4
In the HTML for the captcha elements, I had used the PeopleSoft delivered refresh icon - PT_REFRESH_ICN. Unfortunately this image is not available by default on the images folder in the web server. It is fetched from the database and cached in the webserver when a PeopleSoft page references the image. Therefore I decided to always have it available on the webserver. I did that by copying the refresh icon to the image folder located at 
 <%PS_HOME%>\webserv\<Domain>\applications\peoplesoft\PORTAL.war\<domain>\images  

Step-5
Create the JSP file that will intercept the login request and do the validation of the captcha entered by the user. The JSP does one of two things, forwards the login request to the psp servlet if captcha validation is successful or else re-load the login page with the custom captcha error message shown (error code = 20001). The code in my JSP file i.e Rao99.jsp is listed below.


 <%@page import="com.octo.captcha.module.servlet.image.SimpleImageCaptchaServlet" %>  
 <%   
   String userCaptchaResponse = request.getParameter("jcaptcha");  
   userCaptchaResponse = userCaptchaResponse.trim();   
   Boolean captchapassed = false;  
   if( userCaptchaResponse.equals("") || userCaptchaResponse == null )  
   {  
 %>  
    <jsp:forward page="/psp/hcm92dmo/?cmd=login&errorCode=20001" >  
    </jsp:forward>  
 <%  
   }  
   else  
   {    // Captcha text is not blank or null  
        try  
        {   
             captchapassed = SimpleImageCaptchaServlet.validateResponse(request, userCaptchaResponse);  
        }  
        catch(Exception e)  
        {  
 %>  
     <jsp:forward page="/psp/hcm92dmo/?cmd=login&errorCode=20003" >  
     </jsp:forward>  
 <%  
        }  
        System.out.println("captcha passed = " + captchapassed ); /* Logging to weblogic console for debugging purpose */  
        if(captchapassed)  
        {  // On captcha validation success redirect to the psp servlet with login command  
 %>  
     <jsp:forward page="/psp/hcm92dmo/?cmd=login" >  
     </jsp:forward>  
 <%  
        }  
        else  
        {// On captcha validation failure redirect to the signon page with error code set to custom# - 20001  
 %>  
     <jsp:forward page="/psp/hcm92dmo/?cmd=login&errorCode=20002" >  
     </jsp:forward>  
 <%  
         }  
   }  
 %>  
The JSP file should be placed at this location on the web server
 <%PS_HOME%>\webserv\<Domain>\applications\peoplesoft\PORTAL.war\<Domain>  

All the modifications done above require a webserver bounce with cache clear before we can proceed to test.

No comments:

Post a Comment

Aggregate Data Into a Single Column - using LISTAGG

  Use LISTAGG as a query expression, to string several rows into a single row, in a single column. Syntax The syntax for the LISTAGG functio...