alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Jetty example source code file (HTAccessHandler.java)

This example Jetty source code file (HTAccessHandler.java) is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Java - Jetty tags/keywords

arraylist, arraylist, bufferedreader, dummyprincipal, hashmap, hashmap, htaccess, http, io, ioexception, ioexception, principal, request, resource, response, servlet, string, string, stringtokenizer, util

The Jetty HTAccessHandler.java source code

// ========================================================================
// Authors : Van den Broeke Iris, Deville Daniel, Dubois Roger, Greg Wilkins
// Copyright (c) 2001 Deville Daniel. All rights reserved.
// Permission to use, copy, modify and distribute this software
// for non-commercial or commercial purposes and without fee is
// hereby granted provided that this copyright notice appears in
// all copies.
// ========================================================================

package org.mortbay.jetty.security;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.security.Principal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.StringTokenizer;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.mortbay.jetty.Handler;
import org.mortbay.jetty.HttpConnection;
import org.mortbay.jetty.HttpHeaders;
import org.mortbay.jetty.Request;
import org.mortbay.jetty.Response;
import org.mortbay.jetty.handler.ContextHandler;
import org.mortbay.log.Log;
import org.mortbay.log.Logger;
import org.mortbay.resource.Resource;
import org.mortbay.util.StringUtil;
import org.mortbay.util.URIUtil;

/* ------------------------------------------------------------ */
/**
 * Handler to authenticate access using the Apache's .htaccess files.
 * 
 * @author Van den Broeke Iris
 * @author Deville Daniel
 * @author Dubois Roger
 * @author Greg Wilkins
 * @author Konstantin Metlov
 * 
 */
public class HTAccessHandler extends SecurityHandler
{
    private Handler protegee;
    private static Logger log=Log.getLogger(HTAccessHandler.class.getName());

    String _default=null;
    String _accessFile=".htaccess";

    transient HashMap _htCache=new HashMap();
    
    /**
     * DummyPrincipal
     *
     * For use when there is no user realm configured.
     */
    class DummyPrincipal implements Principal
    {
        private String _userName;

        public DummyPrincipal(String name) 
        {
            _userName=name;
        }

        public String getName()
        {
            return _userName;
        }

        public String toString()
        {
            return getName();
        }        
    }


    /* ------------------------------------------------------------ */
    /**
     * {@inheritDoc}
     * 
     * @see org.mortbay.jetty.Handler#handle(java.lang.String,
     *      javax.servlet.http.HttpServletRequest,
     *      javax.servlet.http.HttpServletResponse, int)
     */
    public void handle(String target, HttpServletRequest request, HttpServletResponse response, int dispatch) throws IOException, ServletException
    {
        Request base_request=(request instanceof Request)?(Request)request:HttpConnection.getCurrentConnection().getRequest();
        Response base_response=(response instanceof Response)?(Response)response:HttpConnection.getCurrentConnection().getResponse();

        String pathInContext=target;

        String user=null;
        String password=null;
        boolean IPValid=true;

        if (log.isDebugEnabled())
            log.debug("HTAccessHandler pathInContext="+pathInContext,null,null);

        String credentials=request.getHeader(HttpHeaders.AUTHORIZATION);

        if (credentials!=null)
        {
            credentials=credentials.substring(credentials.indexOf(' ')+1);
            credentials=B64Code.decode(credentials,StringUtil.__ISO_8859_1);
            int i=credentials.indexOf(':');
            user=credentials.substring(0,i);
            password=credentials.substring(i+1);

            if (log.isDebugEnabled())
                log.debug("User="+user+", password="+"******************************".substring(0,password.length()),null,null);
        }

        HTAccess ht=null;

        try
        {
            Resource resource=null;
            String directory=pathInContext.endsWith("/")?pathInContext:URIUtil.parentPath(pathInContext);

            // Look for htAccess resource
            while (directory!=null)
            {
                String htPath=directory+_accessFile;
                resource=((ContextHandler)getProtegee()).getResource(htPath);
                if (log.isDebugEnabled())
                    log.debug("directory="+directory+" resource="+resource,null,null);

                if (resource!=null&&resource.exists()&&!resource.isDirectory())
                    break;
                resource=null;
                directory=URIUtil.parentPath(directory);
            }

            boolean haveHtAccess=true;

            // Try default directory
            if (resource==null&&_default!=null)
            {
                resource=Resource.newResource(_default);
                if (!resource.exists()||resource.isDirectory())
                    haveHtAccess=false;
            }
            if (resource==null)
                haveHtAccess=false;

            // prevent access to htaccess files
            if (pathInContext.endsWith(_accessFile)
                // extra security
                ||pathInContext.endsWith(_accessFile+"~")||pathInContext.endsWith(_accessFile+".bak"))
            {
                response.sendError(HttpServletResponse.SC_FORBIDDEN);
                base_request.setHandled(true);
                return;
            }

            if (haveHtAccess)
            {
                if (log.isDebugEnabled())
                    log.debug("HTACCESS="+resource,null,null);

                ht=(HTAccess)_htCache.get(resource);
                if (ht==null||ht.getLastModified()!=resource.lastModified())
                {
                    ht=new HTAccess(resource);
                    _htCache.put(resource,ht);
                    if (log.isDebugEnabled())
                        log.debug("HTCache loaded "+ht,null,null);
                }

                // See if there is a config problem
                if (ht.isForbidden())
                {
                    log.warn("Mis-configured htaccess: "+ht,null,null);
                    response.sendError(HttpServletResponse.SC_FORBIDDEN);
                    base_request.setHandled(true);
                    return;
                }

                // first see if we need to handle based on method type
                Map methods=ht.getMethods();
                if (methods.size()>0&&!methods.containsKey(request.getMethod()))
                    return; // Nothing to check

                // Check the accesss
                int satisfy=ht.getSatisfy();

                // second check IP address
                IPValid=ht.checkAccess("",request.getRemoteAddr());
                if (log.isDebugEnabled())
                    log.debug("IPValid = "+IPValid,null,null);

                // If IP is correct and satify is ANY then access is allowed
                if (IPValid==true&&satisfy==HTAccess.ANY)
                    return;

                // If IP is NOT correct and satify is ALL then access is
                // forbidden
                if (IPValid==false&&satisfy==HTAccess.ALL)
                {
                    response.sendError(HttpServletResponse.SC_FORBIDDEN);
                    base_request.setHandled(true);
                    return;
                }

                // set required page
                if (!ht.checkAuth(user,password,getUserRealm(),base_request))
                {
                    log.debug("Auth Failed",null,null);
                    response.setHeader(HttpHeaders.WWW_AUTHENTICATE,"basic realm="+ht.getName());
                    response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
                    base_response.complete();
                    base_request.setHandled(true);
                    return;
                }

                // set user
                if (user!=null)
                {
                    base_request.setAuthType(Constraint.__BASIC_AUTH);
                    base_request.setUserPrincipal(getPrincipal(user, getUserRealm()));
                }
            }
            
            if (getHandler()!=null)
            {
                getHandler().handle(target,request,response,dispatch);
            }

        }
        catch (Exception ex)
        {
            log.warn("Exception",ex);
            if (ht!=null)
            {
                response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
                base_request.setHandled(true);
            }
        }
    }
    
    /* ------------------------------------------------------------ */
    /** Get a Principal matching the user.
     * If there is no user realm, and therefore we are using a
     * htpassword file instead, then just return a dummy Principal.
     * @param user
     * @param realm
     * @return
     */
    public Principal getPrincipal (String user, UserRealm realm)
    {
        if (realm==null)
            return new DummyPrincipal(user);
        
        return realm.getPrincipal(user);
    }
    /* ------------------------------------------------------------ */
    /**
     * set functions for the following .xml administration statements.
     * 
     * <Call name="addHandler">   .htaccess
     * </New>  
     * 
     */
    public void setDefault(String dir)
    {
        _default=dir;
    }

    /* ------------------------------------------------------------ */
    public void setAccessFile(String anArg)
    {
        if (anArg==null)
            _accessFile=".htaccess";
        else
            _accessFile=anArg;
    }

    /* ------------------------------------------------------------ */
    /* ------------------------------------------------------------ */
    /* ------------------------------------------------------------ */
    private static class HTAccess
    {
        // private boolean _debug = false;
        static final int ANY=0;
        static final int ALL=1;
        static final String USER="user";
        static final String GROUP="group";
        static final String VALID_USER="valid-user";

        /* ------------------------------------------------------------ */
        String _userFile;
        Resource _userResource;
        HashMap _users=null;
        long _userModified;

        /* ------------------------------------------------------------ */
        String _groupFile;
        Resource _groupResource;
        HashMap _groups=null;
        long _groupModified;

        int _satisfy=0;
        String _type;
        String _name;
        HashMap _methods=new HashMap();
        HashSet _requireEntities=new HashSet();
        String _requireName;
        int _order;
        ArrayList _allowList=new ArrayList();
        ArrayList _denyList=new ArrayList();
        long _lastModified;
        boolean _forbidden=false;

        /* ------------------------------------------------------------ */
        public HTAccess(Resource resource)
        {
            BufferedReader htin=null;
            try
            {
                htin=new BufferedReader(new InputStreamReader(resource.getInputStream()));
                parse(htin);
                _lastModified=resource.lastModified();

                if (_userFile!=null)
                {
                    _userResource=Resource.newResource(_userFile);
                    if (!_userResource.exists())
                    {
                        _forbidden=true;
                        log.warn("Could not find ht user file: "+_userFile,null,null);
                    }
                    else if (log.isDebugEnabled())
                        log.debug("user file: "+_userResource,null,null);
                }

                if (_groupFile!=null)
                {
                    _groupResource=Resource.newResource(_groupFile);
                    if (!_groupResource.exists())
                    {
                        _forbidden=true;
                        log.warn("Could not find ht group file: "+_groupResource,null,null);
                    }
                    else if (log.isDebugEnabled())
                        log.debug("group file: "+_groupResource,null,null);
                }
            }
            catch (IOException e)
            {
                _forbidden=true;
                log.warn("LogSupport.EXCEPTION",e);
            }
        }

        /* ------------------------------------------------------------ */
        public boolean isForbidden()
        {
            return _forbidden;
        }

        /* ------------------------------------------------------------ */
        public HashMap getMethods()
        {
            return _methods;
        }

        /* ------------------------------------------------------------ */
        public long getLastModified()
        {
            return _lastModified;
        }

        /* ------------------------------------------------------------ */
        public Resource getUserResource()
        {
            return _userResource;
        }

        /* ------------------------------------------------------------ */
        public Resource getGroupResource()
        {
            return _groupResource;
        }

        /* ------------------------------------------------------------ */
        public int getSatisfy()
        {
            return (_satisfy);
        }

        /* ------------------------------------------------------------ */
        public String getName()
        {
            return _name;
        }

        /* ------------------------------------------------------------ */
        public String getType()
        {
            return _type;
        }

        /* ------------------------------------------------------------ */
        public boolean checkAccess(String host, String ip)
        {
            String elm;
            boolean alp=false;
            boolean dep=false;

            // if no allows and no deny defined, then return true
            if (_allowList.size()==0&&_denyList.size()==0)
                return (true);

            // looping for allows
            for (int i=0; i<_allowList.size(); i++)
            {
                elm=(String)_allowList.get(i);
                if (elm.equals("all"))
                {
                    alp=true;
                    break;
                }
                else
                {
                    char c=elm.charAt(0);
                    if (c>='0'&&c<='9')
                    {
                        // ip
                        if (ip.startsWith(elm))
                        {
                            alp=true;
                            break;
                        }
                    }
                    else
                    {
                        // hostname
                        if (host.endsWith(elm))
                        {
                            alp=true;
                            break;
                        }
                    }
                }
            }

            // looping for denies
            for (int i=0; i<_denyList.size(); i++)
            {
                elm=(String)_denyList.get(i);
                if (elm.equals("all"))
                {
                    dep=true;
                    break;
                }
                else
                {
                    char c=elm.charAt(0);
                    if (c>='0'&&c<='9')
                    { // ip
                        if (ip.startsWith(elm))
                        {
                            dep=true;
                            break;
                        }
                    }
                    else
                    { // hostname
                        if (host.endsWith(elm))
                        {
                            dep=true;
                            break;
                        }
                    }
                }
            }

            if (_order<0) // deny,allow
                return !dep||alp;
            // mutual failure == allow,deny
            return alp&&!dep;
        }

        /* ------------------------------------------------------------ */
        public boolean checkAuth(String user, String pass, UserRealm realm, Request request)
        {
            if (_requireName==null)
                return true;

            // Authenticate with realm

            Principal principal=realm==null?null:realm.authenticate(user,pass,request);
            if (principal==null)
            {
                // Have to authenticate the user with the password file
                String code=getUserCode(user);
                String salt=code!=null?code.substring(0,2):user;
                String cred=(user!=null&&pass!=null)?UnixCrypt.crypt(pass,salt):null;
                if (code==null||(code.equals("")&&!pass.equals(""))||!code.equals(cred))
                    return false;
            }

            if (_requireName.equalsIgnoreCase(USER))
            {
                if (_requireEntities.contains(user))
                    return true;
            }
            else if (_requireName.equalsIgnoreCase(GROUP))
            {
                ArrayList gps=getUserGroups(user);
                if (gps!=null)
                    for (int g=gps.size(); g-->0;)
                        if (_requireEntities.contains(gps.get(g)))
                            return true;
            }
            else if (_requireName.equalsIgnoreCase(VALID_USER))
            {
                return true;
            }

            return false;
        }

        /* ------------------------------------------------------------ */
        public boolean isAccessLimited()
        {
            if (_allowList.size()>0||_denyList.size()>0)
                return true;
            else
                return false;
        }

        /* ------------------------------------------------------------ */
        public boolean isAuthLimited()
        {
            if (_requireName!=null)
                return true;
            else
                return false;
        }

        /* ------------------------------------------------------------ */
        private String getUserCode(String user)
        {
            if (_userResource==null)
                return null;

            if (_users==null||_userModified!=_userResource.lastModified())
            {
                if (log.isDebugEnabled())
                    log.debug("LOAD "+_userResource,null,null);
                _users=new HashMap();
                BufferedReader ufin=null;
                try
                {
                    ufin=new BufferedReader(new InputStreamReader(_userResource.getInputStream()));
                    _userModified=_userResource.lastModified();
                    String line;
                    while ((line=ufin.readLine())!=null)
                    {
                        line=line.trim();
                        if (line.startsWith("#"))
                            continue;
                        int spos=line.indexOf(':');
                        if (spos<0)
                            continue;
                        String u=line.substring(0,spos).trim();
                        String p=line.substring(spos+1).trim();
                        _users.put(u,p);
                    }
                }
                catch (IOException e)
                {
                    log.warn("LogSupport.EXCEPTION",e);
                }
                finally
                {
                    try
                    {
                        if (ufin!=null)
                            ufin.close();
                    }
                    catch (IOException e2)
                    {
                        log.warn("LogSupport.EXCEPTION",e2);
                    }
                }
            }

            return (String)_users.get(user);
        }

        /* ------------------------------------------------------------ */
        private ArrayList getUserGroups(String group)
        {
            if (_groupResource==null)
                return null;

            if (_groups==null||_groupModified!=_groupResource.lastModified())
            {
                if (log.isDebugEnabled())
                    log.debug("LOAD "+_groupResource,null,null);

                _groups=new HashMap();
                BufferedReader ufin=null;
                try
                {
                    ufin=new BufferedReader(new InputStreamReader(_groupResource.getInputStream()));
                    _groupModified=_groupResource.lastModified();
                    String line;
                    while ((line=ufin.readLine())!=null)
                    {
                        line=line.trim();
                        if (line.startsWith("#")||line.length()==0)
                            continue;

                        StringTokenizer tok=new StringTokenizer(line,": \t");

                        if (!tok.hasMoreTokens())
                            continue;
                        String g=tok.nextToken();
                        if (!tok.hasMoreTokens())
                            continue;
                        while (tok.hasMoreTokens())
                        {
                            String u=tok.nextToken();
                            ArrayList gl=(ArrayList)_groups.get(u);
                            if (gl==null)
                            {
                                gl=new ArrayList();
                                _groups.put(u,gl);
                            }
                            gl.add(g);
                        }
                    }
                }
                catch (IOException e)
                {
                    log.warn("LogSupport.EXCEPTION",e);
                }
                finally
                {
                    try
                    {
                        if (ufin!=null)
                            ufin.close();
                    }
                    catch (IOException e2)
                    {
                        log.warn("LogSupport.EXCEPTION",e2);
                    }
                }
            }

            return (ArrayList)_groups.get(group);
        }

        /* ------------------------------------------------------------ */
        public String toString()
        {
            StringBuffer buf=new StringBuffer();

            buf.append("AuthUserFile=");
            buf.append(_userFile);
            buf.append(", AuthGroupFile=");
            buf.append(_groupFile);
            buf.append(", AuthName=");
            buf.append(_name);
            buf.append(", AuthType=");
            buf.append(_type);
            buf.append(", Methods=");
            buf.append(_methods);
            buf.append(", satisfy=");
            buf.append(_satisfy);
            if (_order<0)
                buf.append(", order=deny,allow");
            else if (_order>0)
                buf.append(", order=allow,deny");
            else
                buf.append(", order=mutual-failure");

            buf.append(", Allow from=");
            buf.append(_allowList);
            buf.append(", deny from=");
            buf.append(_denyList);
            buf.append(", requireName=");
            buf.append(_requireName);
            buf.append(" ");
            buf.append(_requireEntities);

            return buf.toString();
        }

        /* ------------------------------------------------------------ */
        private void parse(BufferedReader htin) throws IOException
        {
            String line;
            while ((line=htin.readLine())!=null)
            {
                line=line.trim();
                if (line.startsWith("#"))
                    continue;
                else if (line.startsWith("AuthUserFile"))
                {
                    _userFile=line.substring(13).trim();
                }
                else if (line.startsWith("AuthGroupFile"))
                {
                    _groupFile=line.substring(14).trim();
                }
                else if (line.startsWith("AuthName"))
                {
                    _name=line.substring(8).trim();
                }
                else if (line.startsWith("AuthType"))
                {
                    _type=line.substring(8).trim();
                }
                // else if (line.startsWith("<Limit")) {
                else if (line.startsWith("<Limit"))
                {
                    int limit=line.length();
                    int endp=line.indexOf('>');
                    StringTokenizer tkns;

                    if (endp<0)
                        endp=limit;
                    tkns=new StringTokenizer(line.substring(6,endp));
                    while (tkns.hasMoreTokens())
                    {
                        _methods.put(tkns.nextToken(),Boolean.TRUE);
                    }

                    while ((line=htin.readLine())!=null)
                    {
                        line=line.trim();
                        if (line.startsWith("#"))
                            continue;
                        else if (line.startsWith("satisfy"))
                        {
                            int pos1=7;
                            limit=line.length();
                            while ((pos1<limit)&&(line.charAt(pos1)<=' '))
                                pos1++;
                            int pos2=pos1;
                            while ((pos2<limit)&&(line.charAt(pos2)>' '))
                                pos2++;
                            String l_string=line.substring(pos1,pos2);
                            if (l_string.equals("all"))
                                _satisfy=1;
                            else if (l_string.equals("any"))
                                _satisfy=0;
                        }
                        else if (line.startsWith("require"))
                        {
                            int pos1=7;
                            limit=line.length();
                            while ((pos1<limit)&&(line.charAt(pos1)<=' '))
                                pos1++;
                            int pos2=pos1;
                            while ((pos2<limit)&&(line.charAt(pos2)>' '))
                                pos2++;
                            _requireName=line.substring(pos1,pos2).toLowerCase();
                            if (USER.equals(_requireName))
                                _requireName=USER;
                            else if (GROUP.equals(_requireName))
                                _requireName=GROUP;
                            else if (VALID_USER.equals(_requireName))
                                _requireName=VALID_USER;

                            pos1=pos2+1;
                            if (pos1<limit)
                            {
                                while ((pos1<limit)&&(line.charAt(pos1)<=' '))
                                    pos1++;

                                tkns=new StringTokenizer(line.substring(pos1));
                                while (tkns.hasMoreTokens())
                                {
                                    _requireEntities.add(tkns.nextToken());
                                }
                            }

                        }
                        else if (line.startsWith("order"))
                        {
                            if (log.isDebugEnabled())
                                log.debug("orderline="+line+"order="+_order,null,null);
                            if (line.indexOf("allow,deny")>0)
                            {
                                log.debug("==>allow+deny",null,null);
                                _order=1;
                            }
                            else if (line.indexOf("deny,allow")>0)
                            {
                                log.debug("==>deny,allow",null,null);
                                _order=-1;
                            }
                            else if (line.indexOf("mutual-failure")>0)
                            {
                                log.debug("==>mutual",null,null);
                                _order=0;
                            }
                            else
                            {
                            }
                        }
                        else if (line.startsWith("allow from"))
                        {
                            int pos1=10;
                            limit=line.length();
                            while ((pos1<limit)&&(line.charAt(pos1)<=' '))
                                pos1++;
                            if (log.isDebugEnabled())
                                log.debug("allow process:"+line.substring(pos1),null,null);
                            tkns=new StringTokenizer(line.substring(pos1));
                            while (tkns.hasMoreTokens())
                            {
                                _allowList.add(tkns.nextToken());
                            }
                        }
                        else if (line.startsWith("deny from"))
                        {
                            int pos1=9;
                            limit=line.length();
                            while ((pos1<limit)&&(line.charAt(pos1)<=' '))
                                pos1++;
                            if (log.isDebugEnabled())
                                log.debug("deny process:"+line.substring(pos1),null,null);

                            tkns=new StringTokenizer(line.substring(pos1));
                            while (tkns.hasMoreTokens())
                            {
                                _denyList.add(tkns.nextToken());
                            }
                        }
                        else if (line.startsWith("</Limit>"))
                            break;
                    }
                }
            }
        }
    }

    /**
     * Getter for property protegee.
     * 
     * @return Returns the protegee.
     */
    protected Handler getProtegee()
    {
        return this.protegee;
    }

    /**
     * Setter for property protegee.
     * 
     * @param protegee
     *            The protegee to set.
     */
    public void setProtegee(Handler protegee)
    {
        this.protegee=protegee;
    }

}

Other Jetty examples (source code examples)

Here is a short list of links related to this Jetty HTAccessHandler.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.