📄 htaccesshandler.java
字号:
// ========================================================================// 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"> <Arg> <New * class="org.mortbay.http.handler.HTAccessHandler"> <Set * name="Default">./etc/htaccess</Set> <Set name="AccessFile">.htaccess</Set> * </New> </Arg> </Call> * */ 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))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -