The Company
Products
Solutions
Services and Support
Customers
Partners
News
Events
Home >> News >> WebFOCUS Newsletter >> Summer 2004 >> Building a Better Credentials Trap

Building a Better Credentials Trap

By Diane Sklar

Let's face it. Not everyone wants to run WebFOCUS using the standard WebFOCUS authentication routines. Companies want to leverage databases and LDAP repositories full of user credentials. Companies want to hook applications to their own Java™ authentication classes that function across applications.

This article walks through the self-service WebFOCUS technique of authenticating credentials against an external user repository via an external Java class and storing those credentials in a J2EE application server session to make them persistent. This solution is available for sites running WebFOCUS 5.2.3 and later with the WFServlet client option.

Isn't that what cookies are intended to do, make values persistent? The truth is that not all sites allow cookies to be set. Cookies can be detected easily and stolen from the browser machine. They may not even be encrypted. Many sites prefer to use an alternate, server-side means of tracking variables that must be persistent.

Here's a breakdown of the problem: Your user logs on to a WebFOCUS application using a logon page that prompts for user ID and password. The form does whatever authentication routine is relevant for the application. Once the user ID is authenticated, the first page of the application is displayed. Since this is a WebFOCUS self-service application, we can expect that the user selects parameterized reports from a list. So, each time the application needs to connect to the secured Reporting Server and run a report, it will need the credentials that the user entered to log on.

Where can you put those already-authenticated credentials so you can go back and get them after the initial authentication? HTTP is a stateless protocol that keeps no history of connections. What you need is a kind of electronic sock drawer or glove compartment where you can stash the user ID and password between WebFOCUS' non-persistent connections. This will keep your users content since they won't have to constantly re-enter credentials. See Figure 1 for a view of the solution.

Figure 1

Let's start with the logon form. The following form is used as the doorway to a WebFOCUS application.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<HTML>
<HEAD>
<%@ page 
language="java" import="bipg.beans.*"
contentType="text/html; charset=ISO-8859-1"
%>
<jsp:useBean id="auth" class="bipg.beans.DbmsAuthBean" scope="request"></jsp:useBean>
<%
String msg="<H3>Login Failed</H3>";
String username=request.getParameter
("username");
if (username == null)
{
    username="";
    msg="<H3>Please Login:</H3>";
}    
else 
  {
    auth.setUserLogin(username);
    auth.setUserPassword(request.getParameter
("password"));
  }
if(!auth.isAuth())
{
%>
<TITLE>Log In</TITLE>

<script type="text/javascript">
function onSubm()
{
  document.loginform.submit();
}
</script>

</HEAD>

<BODY>
<TABLE BORDER=5 ALIGN="CENTER">
	<TR>
		<TH>WebFOCUS Log In
</TABLE>
<P>
<%= msg %>
<FORM NAME="loginform" METHOD="POST" >
<TABLE>
	<TR>
		<TD>User name: <INPUT TYPE="TEXT" NAME="username"
		VALUE="<%= username %>">
	<TR>
		<TD>Password: <INPUT TYPE="PASSWORD" NAME="password">
	<TR>
		<TH><INPUT TYPE="SUBMIT" VALUE="Log In" onClick="onSubm()"> 
			
</TABLE>

</FORM>
</BODY>
</HTML>
<% 
  } else {
    session.setAttribute("_ibuser", request.getParameter("username"));
    session.setAttribute("_ibpass",request.getParameter("password"));
    response.sendRedirect("http://
localhost/ibi_apps/reportpage.html");
   
}
%>

Notice that in this form, WebFOCUS does not control the authentication of credentials, i.e., there is no statement such as

<input type=hidden name="IBIWF_action" 
value="WF_SIGNON">

invoking the WFServlet to perform a logon. The page prompts for a user ID (username) and a password (password) and then the credential check is performed by a Java bean identified in the jsp:useBean statement. This bean happens to check credentials by connecting to an external RDBMS database but it could as well do other forms of authentication. The statements

auth.setUserLogin(username);
  auth.setUserPassword(request.getParameter("password"));

put the user ID and password in the auth object so that they can be authenticated with the isAuth method from the bean.

The bit of code from the JSP page that stores the credentials in the application server session is

session.setAttribute("_ibuser", request.getParameter("username"));
session.setAttribute("_ibpass",request.getParameter("password"));

These statements create session variables named _ibuser and _ibpass, and assign them values entered by the user on the form. The instantiation of the session object and its storage on the application server do not require special JSP coding. This is part of the J2EE specification for the behavior of servlets and JSPs.

Now that the variables are safely tucked away in the application server session, how can they be passed to the WFServlet and then on to the Reporting Server when a report is executed? All variables accessed by the WFServlet have to be put in the WebFOCUS variable table. Don't go looking for the WebFOCUS variable table in any directory of the WebFOCUS product. It exists in memory only. It is a great big curio cabinet where all the WFServlet's props and tchotchkes are loaded so that they can be selectively picked out and sent to the Reporting Server. We need a way to move the variables from the application server session to the variables in the WebFOCUS Variable Table. In release 5.2.3 of WebFOCUS, for the first time, Java methods (plug-ins) for moving variables in and out of the WebFOCUS Variable Table were packaged with the product so that sites could use them for customized WFServlet processing. These methods are called from the site.wfs file using the WebFOCUS scripting language.

Here is a site.wfs file that loads the username and password into the WebFOCUS Variable Table:

<VER 1>
# place any variables here from cgivars.wfs that you wish to override. 
_HTML_COMMENT_VAR=CGI gened on &_cgi_gen_var\n

  wfvar=username
  httpsession=_ibuser
  <call> CopySessionVarToWFVar
(httpsession,wfvar)
  wfvar=password
  httpsession=_ibpass
  <call> CopySessionVarToWFVar
(httpsession,wfvar)

IBI_REPORT_USER=&username
IBI_REPORT_PASS=&password

Each call to CopySessionVarToWFVar puts one variable in the WebFOCUS variable table. The two assignment statements prior to each <call> statement set up the parameters that are passed to CopySessionVarToWFVar. They are necessary because the CopySessionVarToWFVar routine does not accept literals as parameters. It must be passed variables. When reading the assignment statements, it is helpful to remember two rules about the WebFOCUS scripting language. A string without an ampersand may look like a variable but it is actually a literal (no double or single quotes necessary). A string with an ampersand in front of it actually means "value of" and is like a Dialog Manager variable. So the statement httpsession=_ibuser puts the literal _ibuser, the name of the httpsession variable from the JSP page, into a variable called httpsession. Remember the statement on the JSP page that set up the session variable:

session.setAttribute("_ibuser", request.getParameter("username"));
The statement wfvar=username puts the literal username into the variable wfvar and that value gets changed to the actual user-entered value by the CopySessionToWFVar method. In the last two statements of the site.wfs file, we refer to &username and &password, which assign the value of username and password to their respective WebFOCUS Reporting Server variables. These are the two special values that the WFServlet always passes to the Reporting Server for authentication. To activate the optional WFServlet plugin, you must change the value of the WFEXT initialization parameter of the WFServlet. For releases 5.2.3 and higher of the 5.2.x series, this would be done as follows in the WFServlet section of the Web application's web.xml file:

<!-- init-param>
<param-name>WFEXT</param-name>
<param-value>exits.wf.WfCallableExit</param-value>
<description>Callable Exit</description>
</init-param -->

And voila! Your variables have traveled the journey from JSP page to storage in the application server session, to the WebFOCUS Variable Table and then to the Reporting Server. You've achieved a single sign-on environment external from the WebFOCUS sign-on routines. Keep in mind that while this example sends logon credentials on the journey, any other variables could be sent as well. Group IDs, special tokens or any application-specific data could be sent along to Reporting Server. The only difference between handling application specific data versus the Reporting Server logon credentials is that the credentials are passed to the Reporting Server automatically when placed in IBI_REPORT_USER and IBI_REPORT_PASS. For other data, just include an explicit statement in site.wfs telling the WFServlet to pass the variable to the Reporting Server, such as <set> GROUPID (pass). All of this information is documented in the latest version of the WebFOCUS Security and Administration Guide. This version was released along with WebFOCUS 5.2.5 and it includes the definitions of CopySessionVar ToWFVar and the other new plug-ins.

Java and all Java-based marks are trademarks of Sun Microsystems, Inc. in the U.S. and other countries.