parent
898ac4a907
commit
7b4276b6d0
@ -0,0 +1,81 @@ |
||||
This valve is only available for tomcat 5.5 or greater |
||||
|
||||
An up2date documentation can be found here: |
||||
http://wiki.lemonldap.objectweb.org/xwiki/bin/view/NG/DocAppTomcatValve |
||||
|
||||
COMPILATION |
||||
===================================== |
||||
|
||||
Required : |
||||
* ant |
||||
* jre > 1.4 |
||||
* tomcat >= 5.5 |
||||
|
||||
Configure your tomcat home in build.properties files (be crareful for windosw user ... |
||||
path must contains "/" . exemple c:/my hardisk/tomcat/ |
||||
|
||||
|
||||
run ant command. |
||||
|
||||
ValveLemonLDAPNG.jar is created under /dist directory |
||||
|
||||
|
||||
INSTALLATION |
||||
====================================== |
||||
|
||||
|
||||
Copy ValveLemonLDAPNG.jar on <TOMCAT_HOME>/server/lib |
||||
|
||||
Add on your server.xml file a new valve entry like this (in host section) : |
||||
|
||||
<Valve className="org.lemonLDAPNG.SSOValve" userKey="AUTH-USER" roleKey="AUTH-ROLE" roleSeparator="," allows="127.0.0.1"/> |
||||
|
||||
Configure attributes. |
||||
|
||||
userKey : Key in the http header send by lemonLDAP in order to store user login |
||||
|
||||
roleKey : Key in the http header send by lemonLDAP in order to store roles. If lemonLDAP send some roles split by some commas, use |
||||
roleSeparator |
||||
|
||||
*roleSeparator : see above |
||||
|
||||
*allows: You can filter remote IP, IP defined in this attributes are allows (use "," separator for multiple IP). |
||||
Just set the lemonLDAP on this attribute in order to add more security. If this attribute is missed |
||||
all hosts are allowed |
||||
|
||||
|
||||
(*) Optional attributes |
||||
|
||||
QUICK TEST AN DEBUGGING TIPS |
||||
======================================= |
||||
|
||||
|
||||
Download for exemple probe application (great administration tool for tomcat) http://www.lambdaprobe.org |
||||
|
||||
Install valve and configure it. |
||||
|
||||
Send via lemonLDAP user with role = probeuser ... or other user with role = manager |
||||
|
||||
|
||||
Probe doesn't ask authentification, you're logged... |
||||
|
||||
|
||||
|
||||
For debugging, this valve can print some helpfull information in debug level. Configure logging in tomcat |
||||
(see tomcat.apache.org/tomcat-5.5-doc/logging.html ) |
||||
|
||||
|
||||
|
||||
CONTACT |
||||
======================================= |
||||
|
||||
|
||||
swapon666 (at) users.sourceforge.net |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -0,0 +1 @@ |
||||
tomcat.home=C:/Tomcat5.0.28 |
@ -0,0 +1,56 @@ |
||||
<project name="valveLemonLDAPNG" default="package.jar"> |
||||
|
||||
|
||||
<property file="${basedir}/build.properties"/> |
||||
|
||||
<property name="app.label" value="${ant.project.name}"/> |
||||
<property name="app.jar" value="${app.label}.jar" /> |
||||
|
||||
<property name="tomcat.bin" value="${tomcat.home}/bin" /> |
||||
<property name="tomcat.lib.server" value="${tomcat.home}/server/lib" /> |
||||
<property name="tomcat.lib.common" value="${tomcat.home}/common/lib" /> |
||||
|
||||
|
||||
<path id="classpath.compilation" > |
||||
<fileset dir="${tomcat.bin}"> |
||||
<include name="*.jar"/> |
||||
</fileset> |
||||
<fileset dir="${tomcat.lib.server}"> |
||||
<include name="*.jar"/> |
||||
</fileset> |
||||
<fileset dir="${tomcat.lib.common}"> |
||||
<include name="*.jar"/> |
||||
</fileset> |
||||
</path> |
||||
|
||||
<target name="build" depends="init"> |
||||
<javac classpathref="classpath.compilation" |
||||
srcdir="${basedir}/src" |
||||
destdir="${basedir}/build" debug="on" |
||||
source="1.5" |
||||
target="1.5" |
||||
/> |
||||
</target> |
||||
|
||||
<target name="init"> |
||||
<mkdir dir="${basedir}/build"/> |
||||
<mkdir dir="${basedir}/dist"/> |
||||
</target> |
||||
|
||||
<target name="package.jar" depends="build"> |
||||
<delete dir="${basedir}/dist"/> |
||||
<mkdir dir="${basedir}/dist" /> |
||||
<jar destfile="${basedir}/dist/${app.jar}" |
||||
basedir="${basedir}/build" /> |
||||
</target> |
||||
|
||||
|
||||
|
||||
<target name="clean"> |
||||
<delete dir="${basedir}/build"/> |
||||
<delete dir="${basedir}/dist"/> |
||||
</target> |
||||
|
||||
|
||||
|
||||
</project> |
@ -0,0 +1,176 @@ |
||||
package org.lemonLDAPNG; |
||||
|
||||
import java.io.IOException; |
||||
import java.util.ArrayList; |
||||
import java.util.List; |
||||
import java.util.regex.Pattern; |
||||
import java.util.regex.PatternSyntaxException; |
||||
|
||||
import javax.servlet.ServletException; |
||||
import javax.servlet.http.HttpServletRequest; |
||||
|
||||
import org.apache.catalina.connector.Request; |
||||
import org.apache.catalina.connector.Response; |
||||
import org.apache.catalina.realm.GenericPrincipal; |
||||
import org.apache.catalina.valves.ValveBase; |
||||
import org.apache.commons.logging.Log; |
||||
import org.apache.commons.logging.LogFactory; |
||||
import org.apache.tomcat.util.compat.JdkCompat; |
||||
/** |
||||
* SSO Valve for lemonLDAPNG |
||||
* |
||||
* |
||||
* @author PEJAC Pascal |
||||
* |
||||
*/ |
||||
public class SSOValve extends ValveBase { |
||||
private static Log log; |
||||
|
||||
static { |
||||
log = LogFactory.getLog(org.lemonLDAPNG.SSOValve.class); |
||||
} |
||||
|
||||
private static final JdkCompat jdkCompat = JdkCompat.getJdkCompat(); |
||||
|
||||
private static final String info = "org.lemonLDAPNG.SSOValve/1.0"; |
||||
|
||||
private String userKey = null; |
||||
|
||||
private String roleKey = null; |
||||
|
||||
private String roleSeparator = null; |
||||
|
||||
boolean flagAllows = false; |
||||
|
||||
// By default allow all hosts
|
||||
private Pattern allows[] = {Pattern.compile("^.*$")}; |
||||
|
||||
|
||||
public String getInfo() { |
||||
return info; |
||||
} |
||||
|
||||
public void invoke(Request request, Response response) throws IOException, |
||||
ServletException { |
||||
HttpServletRequest httpServletRequest = (HttpServletRequest) request |
||||
.getRequest(); |
||||
// get the remote IP
|
||||
String remoteAdress = request.getRequest().getRemoteAddr(); |
||||
// check if remote adress is allowed in our list
|
||||
for (int j = 0; j < allows.length; j++) { |
||||
if (log.isDebugEnabled()) |
||||
log.debug("Pattern "+allows[j].pattern()+" tested on ip remote "+remoteAdress); |
||||
if (allows[j].matcher(remoteAdress).matches()) { |
||||
|
||||
List roles = new ArrayList(); |
||||
// retrieve user and role
|
||||
String user = httpServletRequest.getHeader(userKey); |
||||
String role = httpServletRequest.getHeader(roleKey); |
||||
if (log.isDebugEnabled()) |
||||
log.debug("Processing WebSSO request for " |
||||
+ request.getMethod() + " " |
||||
+ request.getRequestURI()); |
||||
if (user != null && role != null) { |
||||
if (log.isDebugEnabled()) |
||||
log.debug("Found data User [ " |
||||
+ user + "] with role [ " |
||||
+ role+"]"); |
||||
} |
||||
|
||||
if (roleSeparator != null && role != null) { |
||||
String res[] = role.split(roleSeparator); |
||||
for (int i = 0; i < res.length; i++) { |
||||
roles.add(res[i]); |
||||
} |
||||
} else { |
||||
if (role != null) |
||||
roles.add(role); |
||||
} |
||||
if (user != null) { |
||||
request.setUserPrincipal(new GenericPrincipal(this |
||||
.getContainer().getRealm(), user, "", roles)); |
||||
} |
||||
getNext().invoke(request, response); |
||||
return; |
||||
} |
||||
} |
||||
// error 403 => host not autorized
|
||||
if (flagAllows) response.sendError(403); |
||||
return; |
||||
} |
||||
|
||||
/** |
||||
* get all pattern from host list |
||||
* @param list |
||||
* @return |
||||
*/ |
||||
protected Pattern[] precalculate(String list) { |
||||
if (list == null) |
||||
return new Pattern[0]; |
||||
list = list.trim(); |
||||
if (list.length() < 1) |
||||
return new Pattern[0]; |
||||
list = list + ","; |
||||
ArrayList reList = new ArrayList(); |
||||
do { |
||||
if (list.length() <= 0) |
||||
break; |
||||
int comma = list.indexOf(','); |
||||
if (comma < 0) |
||||
break; |
||||
String pattern = list.substring(0, comma).trim(); |
||||
try { |
||||
reList.add(Pattern.compile(pattern)); |
||||
} catch (PatternSyntaxException e) { |
||||
IllegalArgumentException iae = new IllegalArgumentException(sm |
||||
.getString("requestFilterValve.syntax", pattern)); |
||||
jdkCompat.chainException(iae, e); |
||||
throw iae; |
||||
} |
||||
list = list.substring(comma + 1); |
||||
} while (true); |
||||
Pattern reArray[] = new Pattern[reList.size()]; |
||||
return (Pattern[]) reList.toArray(reArray); |
||||
} |
||||
|
||||
public String getUserKey() { |
||||
return userKey; |
||||
} |
||||
|
||||
public void setUserKey(String userKey) { |
||||
this.userKey = userKey; |
||||
if (log.isDebugEnabled() && userKey != null) |
||||
log.debug("UserKey [" + this.userKey + "]"); |
||||
} |
||||
|
||||
public String getRoleKey() { |
||||
return roleKey; |
||||
} |
||||
|
||||
public void setRoleKey(String roleKey) { |
||||
this.roleKey = roleKey; |
||||
if (log.isDebugEnabled() && roleKey != null) |
||||
log.debug("RoleKey [" + this.roleKey + "]"); |
||||
} |
||||
|
||||
public String getRoleSeparator() { |
||||
return roleSeparator; |
||||
} |
||||
|
||||
public void setRoleSeparator(String roleSeparator) { |
||||
this.roleSeparator = roleSeparator; |
||||
if (log.isDebugEnabled() && roleSeparator != null) |
||||
log.debug("RoleSeparator [" + this.roleSeparator + "]"); |
||||
} |
||||
|
||||
public String getAllows() { |
||||
return ""; |
||||
} |
||||
|
||||
public void setAllows(String allows) { |
||||
// override default allows
|
||||
this.allows = precalculate(allows); |
||||
flagAllows = true; |
||||
} |
||||
|
||||
} |
Loading…
Reference in new issue