Package org.apache.tomcat.j2ee

Source Code of org.apache.tomcat.j2ee.J2EEInterceptor

package org.apache.tomcat.j2ee;

import javax.servlet.*;
import javax.servlet.http.*;
import org.apache.tomcat.core.*;
import com.sun.web.server.*;

import com.sun.enterprise.util.JarClassLoader;

import java.net.URL;
import java.net.InetAddress;
import java.io.File;
import java.io.IOException;
import java.security.Principal;
import java.util.*;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.net.ssl.*;
import javax.security.cert.X509Certificate;

import com.sun.enterprise.util.*;
import com.sun.enterprise.*;
import com.sun.enterprise.security.*;
import com.sun.enterprise.security.acl.*;
import com.sun.enterprise.log.*;
import com.sun.enterprise.deployment.WebBundleDescriptor;

import org.apache.tomcat.deployment.*;
import org.apache.tomcat.util.*;

// depends on servlet 2.2
import org.apache.tomcat.facade.*;
import org.apache.tomcat.helper.*;

/**
* Adapter for j2ee.
*
* @author Harish Prabandham
* @author Costin Manolache
*/
public class J2EEInterceptor extends BaseInterceptor {
    InvocationManagerImpl invM;
    private static LocalStringManagerImpl localStrings;
    private static ServerConfiguration config;
   
    private Hashtable accessLogs = new Hashtable();
    private Hashtable errorLogs = new Hashtable();
    private static final String HTTP_ACCESS_LOG = "web.access.log";
    private static final String HTTP_ERROR_LOG = "web.error.log";
    private static final int BUFFER_SIZE = 1024;

    int userNote;
    int passwordNote;
    // auth
    private static int MAX_COUNT = 5;
    private static int SLEEP_TIME = 5000; // milliseconds....

    public J2EEInterceptor() {
  this.invM= (InvocationManagerImpl) Switch.getSwitch().
      getInvocationManager();
  config= ServerConfiguration.getConfiguration();
  // minimize the changes in j2ee ( temp, until properties are moved)
  localStrings = new
      LocalStringManagerImpl(com.sun.web.security.DataConstraint.class);
    }

    public void engineInit( ContextManager cm ) throws TomcatException {
  super.engineInit(cm);
  userNote=cm.getNoteId( ContextManager.REQUEST_NOTE,
             "credentials.user");
  passwordNote=cm.getNoteId( ContextManager.REQUEST_NOTE,
           "credentials.password");

  debug=10;
    }
   
    public void contextInit( Context ctx)
  throws TomcatException
    {
    }

    public int preService(Request request, Response response) {
  Context ctx = request.getContext();
  Handler sw=request.getHandler();
  if( ! (sw instanceof ServletHandler) )
      return 0;
  try {
      invM.preServletInvoke( (ServletContext)ctx.getFacade(),
           ((ServletHandler)sw).getServlet(),
           (HttpServletRequest)request.getFacade(),
           (HttpServletResponse)response.getFacade() );
  } catch(Exception ex ) {
      return -1;
  }
  return 0;
    }
    public int postService(Request request, Response response) {
  Context ctx = request.getContext();
  Handler sw=request.getHandler();
  if( ! (sw instanceof ServletHandler) )
      return 0;
  try {
      invM.postServletInvoke( (ServletContext)ctx.getFacade(),
            ((ServletHandler)sw).getServlet(),
            (HttpServletRequest)request.getFacade(),
            (HttpServletResponse)response.getFacade());
      intLogRequest( request.getContext().getPath(),
         request.requestURI().toString(),
         null);
  } catch(Exception ex ) {
      return -1;
  }
  return 0;
    }
   
    /** Servlet Init  notification
     */
    public void preServletInit( Context ctx, Handler sw )
  throws TomcatException
    {
  if( ! (sw instanceof ServletHandler) )
      return;
  try {
      invM.preInitInvoke( (ServletContext)ctx.getFacade(),
        ((ServletHandler)sw).getServlet());
  } catch(Exception ex ) {
      log("XXX " + invM + " " + ctx + " " + sw );
      throw new TomcatException( "Error in j2ee adapter " , ex );
  }
    }

   
    public void postServletInit( Context ctx, Handler sw )
  throws TomcatException
    {
  if( ! (sw instanceof ServletHandler) )
      return;
  try {
      invM.postInitInvoke( (ServletContext)ctx.getFacade(),
         ((ServletHandler)sw).getServlet());
  } catch(Exception ex ) {
      throw new TomcatException( "Error in j2ee adapter " , ex );
  }
    }

    /** Servlet Destroy  notification
     */
    public void preServletDestroy( Context ctx, Handler sw )
  throws TomcatException
    {
  if( ! (sw instanceof ServletHandler) )
      return;
  try {
      if( sw != null && ctx != null )
    invM.preDestroyInvoke( (ServletContext)ctx.getFacade(),
               ((ServletHandler)sw).getServlet());
      else
    log("XXX J2EEInterceptor: sw, ctx=" +
           sw + " " +ctx);
  } catch(Exception ex ) {
      ex.printStackTrace();
      throw new TomcatException( "Error in j2ee adapter " , ex );
  }
    }

   
    public void postServletDestroy( Context ctx, Handler sw )
  throws TomcatException
    {
  if( ! (sw instanceof ServletHandler) )
      return;
  try {
      if( sw != null && ctx != null )
    invM.postDestroyInvoke( (ServletContext)ctx.getFacade(),
          ((ServletHandler)sw).getServlet());
      else
    log("XXX J2EEInterceptor: sw, ctx=" +
           sw + " " +ctx);
  } catch(Exception ex ) {
      throw new TomcatException( "Error in j2ee adapter " , ex );
  }
    }

    // -------------------- Authentication hooks --------------------
   
    public int authenticate( Request req, Response res ) {
  Context ctx=req.getContext();
 
  // This realm will use only username and password callbacks
  String user=(String)req.getNote( userNote );
  String password=(String)req.getNote( passwordNote );;
  if( debug>0 ) log( "Try to auth " + user + " " + password);

  if( user==null || password == null ) {
      // Need auth, but have no user/pass
      return DECLINED;
  }
  byte authData[]=password.getBytes();
 
  String realm="default"//ctx.getRealmName();
  String authM=null;// ctx.getAuthMethod();

  LoginContext lc = initLoginContext(realm);
  if( lc==null ) {
      log("Authenticate - Can't get LoginContext....");
      return DECLINED;
  }
 
  if(authM != null)
      lc.setAuthenticationMethod(authM);
 
  SecurityContext.setCurrent(null);

  try {
      lc.login(user,authData);
  } catch (LoginException le) {
      // Log the information here
      // le.printStackTrace();
      Log.err.println(le);
      //le.printStackTrace();
      log("Login failed for..: " + user);
      return DECLINED; // or 401 ?
   }

  if(debug>0) {
      log("Login succeeded for..: " + user);
  }

  req.setRemoteUser( user );
  req.setUserPrincipal( getUserPrincipal() );

  return OK;
    }

    public int authorize( Request req, Response response, String roles[] )
    {
  if( roles==null || roles.length==0 ) {
      return OK;
  }
 
  Context ctx=req.getContext();
  WebBundleDescriptor wbd = (WebBundleDescriptor)
      Switch.getSwitch().getDescriptorFor(ctx.getFacade());

  String appName="default";
  if(wbd != null)
      appName=wbd.getApplication().getName();
  if( debug>0) log("appname=" + appName);

  // call back the authenticate hooks
  String user=req.getRemoteUser();
  if( user==null ) {
      // Need auth, but have no user/pass
      if( debug>0) log("no username");
      return DECLINED;
  }
  String userRoles[]=null;

  String realm="default"//ctx.getRealmName();

  Handler h=req.getHandler();
  ServletHandler sw=(ServletHandler)h;
  String mappedRole=null;
  String role=null;
  for( int i=0; i< roles.length ; i++ ) {
      role=roles[i];
      mappedRole=sw.getServletInfo().getSecurityRole( role );
      if( mappedRole==null) mappedRole=role;
     
      if(isUserInRole(appName, mappedRole) ) {
    if( debug>0 ) log("Role match " +
          roles[i] + " " +  mappedRole);
    return OK;
      }
      if( debug>0 ) log("Role match failed " +
            roles[i] + " " + mappedRole);
  }
 
  if( debug>) log("UnAuthorized " +
          role + " " + mappedRole);
   return DECLINED;
  // XXX check transport
    }

   
    // -------------------- Security --------------------

    /*
      J2EE stores the security information in per/thread data
      ( SecurityContext). The web server will respect web.xml -
      including constraints, roles, auth methods.

      In order to access the J2EE realm it will use those methods.
     
      XXX This is based on how the current code works. It may be a
      good idea to make authenticate return the Principal or null,
      drop getUserPrincipal, and pass the Principal to isUserInRole.
      ( this avoids per/thread data - and it's more generic )
     */
     
    private LoginContext initLoginContext(String realm) {
  for(int i=0; i < MAX_COUNT; ++i) {
      try {
    if (debug>0) log("Getting auth for:" + i);
    LoginContext lc= new LoginContext();
    lc.setRealmName(realm);
    return lc;
      } catch(Exception e) {
    e.printStackTrace(Log.err);
    try {
        Thread.sleep(SLEEP_TIME);
    }catch(InterruptedException ie) {
    }
      }
  }
  return null;
    }

    /** Return the current user, as set by authenticate()
     */
    public Principal getUserPrincipal() {
  SecurityContext sc=SecurityContext.getCurrent();
  if( sc==null ) return null;
  return sc.getCallerPrincipal();
    }
   
    /** Check if the current user has the specified role.
     *  The user is set in the thread data.
     *
     *  It will be called with the role specified in web.xml/role-ref
     */
    public boolean isUserInRole(String appName, String rname) {
  RoleMapper rmap = RoleMapper.getRoleMapper( appName );

  if(debug>0) log("Mapping role " + rname + " " + rmap);
  if(rmap != null) {
      for(Enumeration e =
        rmap.getCurrentRoles(); e.hasMoreElements();) {
    Role r = (Role) e.nextElement();
    if( debug>0) log("Try " + r.getName());
    if(r.getName().equals(rname))
        return true;
      }
  }
  return false;
    }

   
    // -------------------- Logging implementation --------------------

    /* Very inefficient - we do a hashtable lookup per context.
       We could use context notes to speed up if needed.
    */
   
    private synchronized void intLogRequest(String ctxPath, String uri,
              String respString ) {  
  Log accessLog = getAccessLog(ctxPath);
  accessLog.println(localStrings.
        getLocalString( "web.security.request.on.at",
            "Request for  {0} on {1} at {2} ",
            new Object[] {uri,
              ctxPath,
              new Date() +
              "." + respString }));
  accessLog.flush();
    }


    private synchronized void intLogError(String ctxPath, String uri,
            String respString)
    {
  Log errorLog = getErrorLog(ctxPath);
  errorLog.println("Error serving Request " + uri +
       " on " + ctxPath + " at " +
       new Date() + ". " + respString);
  errorLog.flush();
    }


    private synchronized Log getLog(String contextName, String propName,
            String defaultValue) {
  try {
      File dir = LogUtil.getLogDirectory(contextName, LogUtil.WEB_LOG);
      String fname = config.getProperty(propName, defaultValue);
      File logFile =  new File(dir, fname);
     
      if(!logFile.exists()) {
    logFile.createNewFile();
      }

      FileLogWriter fwriter = new FileLogWriter(logFile, BUFFER_SIZE);
      return Log.getLog(fwriter);
  } catch(Exception e) {
      e.printStackTrace();
      Log.err.println(e);
      return Log.err;
  }
    }

    private Log getAccessLog(String contextName) {
  Log aLog = (Log) accessLogs.get(contextName);
  if(aLog == null) {
      aLog = getLog(contextName, HTTP_ACCESS_LOG, "access.log");
      accessLogs.put(contextName, aLog);
  }
 
  return aLog;
    }

    private Log getErrorLog(String contextName) {
  Log aLog = (Log) errorLogs.get(contextName);
  if(aLog == null) {
      aLog = getLog(contextName, HTTP_ERROR_LOG, "error.log");
      errorLogs.put(contextName, aLog);
  }
 
  return aLog;
    }
}

TOP

Related Classes of org.apache.tomcat.j2ee.J2EEInterceptor

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.