[ Team LiB ] Previous Section Next Section

Recipe 15.9 Using JAAS in a JSP

Problem

You want to use a JSP and JAAS to authenticate clients.

Solution

Create a JavaBean that wraps the functionality of the JAAS API classes that you have included in your web application.

Discussion

Recipe 15.5-Recipe 15.7 cover the JAAS basics, so this recipe focuses on adapting a JSP to the JAAS security API.

The JSP in this recipe uses a JavaBean to perform the login.

The JavaBean in Example 15-13 has two properties (in the form of instance variables): a ServletRequest and a boolean value indicating whether the name and password have passed the login test. The bean passes the ServletRequest to the WebCallbackHandler constructor; the WebCallbackHandler ultimately extracts the username and password from request parameters.

Example 15-13. A JavaBean uses the JAAS API to perform authentication
package com.jspservletcookbook;           

import javax.servlet.ServletRequest;

import javax.security.auth.login.LoginContext;
import javax.security.auth.login.LoginException;

public class LoginBean {

    //private bean instance variables or properties
    private ServletRequest req;
    boolean loginSuccess;
    

  public LoginBean( ){ }//bean's no-args constructor

  public boolean getLoginSuccess( ) throws LoginException {
    
      //the ServletRequest property has to be set before this
      //method is called, because that's where we get the
      //username and password from

      if (req == null)
          throw new IllegalStateException(
          "The ServletRequest cannot be null in getLogin( )");
          
      WebCallbackHandler webcallback = new WebCallbackHandler(req);
      
      try{
    
          LoginContext lcontext = new LoginContext(
          "WebLogin",webcallback);
          
          //Call the LoginContext's login( ) method; if it doesn't
          //throw an exception, the method returns true
          lcontext.login( );
          
          return true;
    
      } catch (LoginException lge){
    
         //login failed because the LoginContext.login( ) method
         //threw a LoginException
         return false;
    
      }

  } //getLoginSuccess
     
  public void setReq(ServletRequest request) {
       
      if (request == null)
          throw new IllegalArgumentException(
          "ServletRequest argument was null in: "+
          getClass( ).getName( ));
                           
      this.req = request;
                 
  } //setReq

} // LoginBean

The bean depends on its ServletRequest property being set properly before the getLoginSuccess( ) method is called. This method performs the login by using the familiar LoginContext class and its login( ) method (that is, familiar if you read Recipe 15.5!).

The Java object using the bean knows that the login succeeded or failed based on the boolean return value of the getLoginSuccess( ) method. The object using the bean in this case is a servlet instance originating from the JSP in Example 15-14.

The JSP includes the jsp:useBean standard action to create an instance of the LoginBean (in a variable named jaasBean). Then the code uses JSTL tags to:

  1. Set the bean's ServletRequest property (named req) to the current request (using c:set).

  2. Find out whether the login succeeded by using the EL syntax to call the bean's getLoginSuccess( ) method.

This recipe combines many Java-related technologies. See Chapter 23 for a description of the JSTL and its associated EL syntax.


Example 15-14. A JSP that logs in users using the JAAS API and a JavaBean
<%@ taglib uri="http://java.sun.com/jstl/core" prefix="c" %>

<html>
<head><title>Authenticating JSP</title></head>
<body>
<h2>Here is your login status...</h2>

<jsp:useBean id="jaasBean" class="com.jspservletcookbook.LoginBean" /> 

<%-- The bean's 'req' property is set using the 'request' property of the Expression 
Language's pageContext implicit object --%>

<c:set target="${jaasBean}" value="${pageContext.request}"
property="req"/>

<c:choose>

    <c:when test="${jaasBean.loginSuccess}">
        Logged in successfully.
        </c:when>

        <c:otherwise>
        Login failed.
        </c:otherwise>
        
</c:choose>

</body>
</html>

The LoginBean has a getLoginSuccess( ) method that returns false if the login fails, and true if it succeeds. With the EL, you can call any of a bean's accessor methods with the terminology:

bean name.bean property name

The bean property name part represents the actual property name, not the name of the method, even though the end result of using this syntax is that the accessor method associated with that property gets called. Therefore, Example 15-14 gets the return value of the getLoginSuccess( ) method by using:

${jaasBean.loginSuccess}

If this expression returns true, the JSP displays the text "Logged in successfully." Otherwise, it shows "Login failed."

Figure 15-8 shows the JSP's browser display when a login fails.

Figure 15-8. A JSP signals a login failure
figs/jsjc_1508.gif

See Also

Recipe 15.6 on creating a JAAS LoginModule; Recipe 15.7 on creating the JAAS configuration file; Recipe 15.8 on using JAAS with a servlet; Chapter 23 on the JSTL; Sun Microsystems' JAAS developer's guide: http://java.sun.com/j2se/1.4.2/docs/guide/security/jaas/JAASLMDevGuide.html; a list of JAAS tutorials and sample programs: http://java.sun.com/j2se/1.4.2/docs/guide/security/jaas/JAASRefGuide.html; the Javadoc relating to JAAS configuration files: http://java.sun.com/j2se/1.4.1/docs/api/javax/security/auth/login/Configuration.html.

    [ Team LiB ] Previous Section Next Section