Author: nico
Date: 2009-05-20 17:14:45 +0200 (Wed, 20 May 2009)
New Revision: 35330
Added:
CMSContainer/branches/b1_5/CMSContainer_Modules/knownvisitor/src/java/com/finalist/cmsc/knownvisitor/VisitorFilter.java
Removed:
CMSContainer/branches/b1_5/CMSContainer_Modules/knownvisitor-ntlm/src/java/com/finalist/cmsc/knownvisitor/ntlm/NtlmVisitor.java
Modified:
CMSContainer/branches/b1_5/CMSContainer_Modules/knownvisitor-ntlm/src/java/com/finalist/cmsc/knownvisitor/ntlm/NtlmKnownVisitorModule.java
CMSContainer/branches/b1_5/CMSContainer_Modules/knownvisitor-ntlm/src/java/com/finalist/cmsc/knownvisitor/ntlm/NtlmVisitorFilter.java
CMSContainer/branches/b1_5/CMSContainer_Modules/knownvisitor/src/java/com/finalist/cmsc/knownvisitor/KnownVisitorModule.java
CMSContainer/branches/b1_5/CMSContainer_Modules/knownvisitor/src/java/com/finalist/cmsc/knownvisitor/Visitor.java
Log:
CMSC-1408 Make Basic and NTLM authentication optional for knownvisitors
Modified:
CMSContainer/branches/b1_5/CMSContainer_Modules/knownvisitor/src/java/com/finalist/cmsc/knownvisitor/KnownVisitorModule.java
===================================================================
---
CMSContainer/branches/b1_5/CMSContainer_Modules/knownvisitor/src/java/com/finalist/cmsc/knownvisitor/KnownVisitorModule.java
2009-05-20 15:14:29 UTC (rev 35329)
+++
CMSContainer/branches/b1_5/CMSContainer_Modules/knownvisitor/src/java/com/finalist/cmsc/knownvisitor/KnownVisitorModule.java
2009-05-20 15:14:45 UTC (rev 35330)
@@ -1,23 +1,175 @@
-package com.finalist.cmsc.knownvisitor;
-
-import javax.servlet.http.HttpServletRequest;
-
-import org.mmbase.module.Module;
-
-public abstract class KnownVisitorModule extends Module {
-
- private static KnownVisitorModule instance;
-
-
- public abstract Visitor getVisitor(HttpServletRequest request);
-
-
- public static KnownVisitorModule getInstance() {
- return instance;
- }
-
-
- public static void setInstance(KnownVisitorModule module) {
- instance = module;
- }
-}
+package com.finalist.cmsc.knownvisitor;
+
+import java.util.Hashtable;
+import java.util.List;
+
+import javax.naming.*;
+import javax.naming.directory.*;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpSession;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.mmbase.module.Module;
+
+import com.finalist.cmsc.mmbase.PropertiesUtil;
+
+public abstract class KnownVisitorModule extends Module {
+
+ private static final Log log = LogFactory.getLog(KnownVisitorModule.class);
+
+ private static final String SESSION_ATTRIBUTE = "knownVisitor";
+
+ private static final String PROPERTY_ENABLED = "knownvisitor.enabled";
+ private static final String PROPERTY_IPEXCEPTIONS =
"knownvisitor.ipexceptions";
+ private static final String PROPERTY_BASIC_AUTH =
"knownvisitor.basic-authentication";
+
+ private static final String PROPERTY_LDAP_SERVER =
"knownvisitor.ldapserver";
+ private static final String PROPERTY_REALM = "knownvisitor.realm";
+ private static final String PROPERTY_LOGONNAME = "knownvisitor.logonname";
+ private static final String PROPERTY_LOGONPASSWORD =
"knownvisitor.logonpassword";
+ private static final String PROPERTY_BASEDN = "knownvisitor.baseDN";
+
+ private static final String PROPERTY_FIELD_EMAIL =
"knownvisitor.field.email";
+ private static final String PROPERTY_FIELD_REALNAME =
"knownvisitor.field.realname";
+ private static final String PROPERTY_FIELD_USERNAME =
"knownvisitor.field.username";
+
+
+ private static KnownVisitorModule instance;
+
+ public static KnownVisitorModule getInstance() {
+ return instance;
+ }
+
+ public static void setInstance(KnownVisitorModule module) {
+ instance = module;
+ }
+
+
+ public Visitor getVisitor(HttpServletRequest request) {
+ HttpSession ssn = request.getSession(false);
+ return (ssn != null ? (Visitor) ssn.getAttribute(SESSION_ATTRIBUTE) :
null);
+ }
+
+ public void setVisitor(HttpServletRequest request, Visitor visitor) {
+ request.getSession().setAttribute(SESSION_ATTRIBUTE, visitor);
+ }
+
+ public void readLdapInfo(Visitor visitor) {
+ // Assemble a hash with data to use when connecting...
+ String ldapPrincipal = getLdapPrincipal();
+ String ldapPassword = getLdapPassword();
+
+
+ // Make a directory context by connecting with the above details.
+ try {
+ DirContext ctx = ldapLogin(ldapPrincipal, ldapPassword);
+
+ String baseDN = getLdapBaseDN();
+ String query = "(" + getLdapUsernameField() + "=" +
visitor.getIdentifier() + ")";
+
+ NamingEnumeration<SearchResult> answer = ctx.search(baseDN, query,
null);
+ if (answer.hasMoreElements()) {
+ SearchResult result = answer.next();
+ Attribute values =
result.getAttributes().get(getLdapRealnameField());
+ if (values.size() > 0) {
+ visitor.setDisplayName((String) values.get(0));
+ }
+
+ values = result.getAttributes().get(getLdapEmailField());
+ if (values.size() > 0) {
+ visitor.setEmail((String) values.get(0));
+ }
+ }
+ }
+ catch (NamingException e) {
+ log.error("problem reading user from LDAP: ", e);
+ visitor.setDisplayName("LDAP failed");
+ }
+ }
+
+ public DirContext ldapLogin(String ldapPrincipal, String ldapPassword)
throws NamingException {
+ String server = getLdapServer();
+ if (server.indexOf("://") < 0) {
+ // no protocol, fallback to ldap
+ server = "ldap://" + server;
+ }
+
+ Hashtable<String, String> env = new Hashtable<String, String>();
+ env.put(Context.INITIAL_CONTEXT_FACTORY,
"com.sun.jndi.ldap.LdapCtxFactory");
+ env.put(Context.PROVIDER_URL, server);
+
+ env.put(Context.SECURITY_AUTHENTICATION, "simple");
+ env.put(Context.SECURITY_PRINCIPAL, ldapPrincipal);
+ env.put(Context.SECURITY_CREDENTIALS, ldapPassword);
+
+ DirContext ctx = new InitialDirContext(env);
+ return ctx;
+ }
+
+ public boolean offerBasic(HttpServletRequest req) {
+ boolean offerBasic = req.isSecure();
+ if (!offerBasic) {
+ String basic = getBasicAuth();
+ if (StringUtils.isBlank(basic) || "secure".equalsIgnoreCase(basic)) {
+ return false;
+ }
+ else {
+ // basic authentication is not forced to be on secured urls and
the current request is not secured
+ // This does not mean that the url arrived at the webserver was
not secured. The webserver could
+ // proxy the request without using the secured flag.
+ return true;
+ }
+ }
+ return offerBasic;
+ }
+
+ public String getBasicAuth() {
+ return PropertiesUtil.getProperty(PROPERTY_BASIC_AUTH);
+ }
+
+ public boolean isEnabled() {
+ return
Boolean.parseBoolean(PropertiesUtil.getProperty(PROPERTY_ENABLED));
+ }
+
+ public List<String> getIpExceptions() {
+ return PropertiesUtil.getPropertyAsList(PROPERTY_IPEXCEPTIONS);
+ }
+
+ public String getProperty(String key) {
+ return PropertiesUtil.getProperty(key);
+ }
+
+ public String getLdapPassword() {
+ return getProperty(PROPERTY_LOGONPASSWORD);
+ }
+
+ public String getLdapPrincipal() {
+ return getProperty(PROPERTY_LOGONNAME);
+ }
+
+ public String getLdapServer() {
+ return getProperty(PROPERTY_LDAP_SERVER);
+ }
+
+ public String getLdapBaseDN() {
+ return getProperty(PROPERTY_BASEDN);
+ }
+
+ public String getLdapUsernameField() {
+ return getProperty(PROPERTY_FIELD_USERNAME);
+ }
+
+ public String getLdapEmailField() {
+ return getProperty(PROPERTY_FIELD_EMAIL);
+ }
+
+ public String getLdapRealnameField() {
+ return getProperty(PROPERTY_FIELD_REALNAME);
+ }
+
+ public String getRealm() {
+ return getProperty(PROPERTY_REALM);
+ }
+}
Modified:
CMSContainer/branches/b1_5/CMSContainer_Modules/knownvisitor/src/java/com/finalist/cmsc/knownvisitor/Visitor.java
===================================================================
---
CMSContainer/branches/b1_5/CMSContainer_Modules/knownvisitor/src/java/com/finalist/cmsc/knownvisitor/Visitor.java
2009-05-20 15:14:29 UTC (rev 35329)
+++
CMSContainer/branches/b1_5/CMSContainer_Modules/knownvisitor/src/java/com/finalist/cmsc/knownvisitor/Visitor.java
2009-05-20 15:14:45 UTC (rev 35330)
@@ -1,12 +1,37 @@
-package com.finalist.cmsc.knownvisitor;
-
-public abstract class Visitor {
-
- public abstract Object getIdentifier();
-
-
- public abstract String getDisplayName();
-
-
- public abstract String getEmail();
-}
+package com.finalist.cmsc.knownvisitor;
+
+public class Visitor {
+
+ private String identifier;
+ private String displayName;
+ private String email;
+
+ public String getIdentifier() {
+ return identifier;
+ }
+
+
+ public String getDisplayName() {
+ return displayName;
+ }
+
+
+ public void setDisplayName(String displayName) {
+ this.displayName = displayName;
+ }
+
+
+ public void setIdentifier(String identifier) {
+ this.identifier = identifier;
+ }
+
+
+ public String getEmail() {
+ return email;
+ }
+
+
+ public void setEmail(String email) {
+ this.email = email;
+ }
+}
Added:
CMSContainer/branches/b1_5/CMSContainer_Modules/knownvisitor/src/java/com/finalist/cmsc/knownvisitor/VisitorFilter.java
===================================================================
---
CMSContainer/branches/b1_5/CMSContainer_Modules/knownvisitor/src/java/com/finalist/cmsc/knownvisitor/VisitorFilter.java
(rev 0)
+++
CMSContainer/branches/b1_5/CMSContainer_Modules/knownvisitor/src/java/com/finalist/cmsc/knownvisitor/VisitorFilter.java
2009-05-20 15:14:45 UTC (rev 35330)
@@ -0,0 +1,164 @@
+/*
+
+This software is OSI Certified Open Source Software.
+OSI Certified is a certification mark of the Open Source Initiative.
+
+The license (Mozilla version 1.0) can be read at the MMBase site.
+See http://www.MMBase.org/license
+
+*/
+package com.finalist.cmsc.knownvisitor;
+
+import java.io.IOException;
+
+import java.util.*;
+
+import javax.naming.NamingException;
+import javax.servlet.*;
+import javax.servlet.http.*;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.mmbase.util.Encode;
+
+public class VisitorFilter implements Filter {
+
+ private static final Log log = LogFactory.getLog(VisitorFilter.class);
+
+ public void init(FilterConfig filterConfig) {
+ // nothing
+ }
+
+ public void destroy() {
+ // nothing
+ }
+
+ /**
+ * This method simply calls <tt>negotiate( req, resp, false )</tt> and then
+ * <tt>chain.doFilter</tt>. You can override and call negotiate manually
+ * to achive a variety of different behavior.
+ */
+ public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException,
+ ServletException {
+ final HttpServletRequest req = (HttpServletRequest) request;
+ final HttpServletResponse resp = (HttpServletResponse) response;
+
+ if (KnownVisitorModule.getInstance().isEnabled() &&
!alreadyLoggedIn(req)) {
+ List<String> exceptions =
KnownVisitorModule.getInstance().getIpExceptions();
+ if (!exceptions.isEmpty()) {
+
+ List<String> ips = resolveRemoteAddresses(request);
+
+ for (Iterator<String> iterator = ips.iterator();
iterator.hasNext();) {
+ String addr = iterator.next();
+ if (exceptions.contains(addr)) {
+ log.debug("Ip " + addr + " allowed.");
+ chain.doFilter(request, response);
+ return;
+ }
+ }
+ }
+
+ if (!negotiate(req, resp)) {
+ return;
+ }
+ }
+ chain.doFilter(req, resp);
+ }
+
+ private List<String> resolveRemoteAddresses(ServletRequest request) {
+ List<String> ips = new ArrayList<String>();
+ ips.add(request.getRemoteAddr());
+
+ String ip = ((HttpServletRequest) request).getHeader("X-Forwarded-For");
+ if (StringUtils.isBlank(ip)) {
+ // not behind a proxy or mod_proxy
+ log.debug("Incoming ip, remote address = " + request.getRemoteAddr());
+ }
+ else {
+ log.debug("Incoming ip, remote address = " + request.getRemoteAddr()
+ " X-Forwarded-For =" + ip);
+ StringTokenizer token = new StringTokenizer(ip, ",");
+ while(token.hasMoreTokens()) {
+ ips.add(token.nextToken().trim());
+ }
+ }
+ return ips;
+ }
+
+ /**
+ * Negotiate password hashes with MSIE clients using NTLM SSP
+ *
+ * @param req The servlet request
+ * @param resp The servlet response
+ * @return True if the negotiation is complete, otherwise false
+ */
+ protected boolean negotiate(HttpServletRequest req, HttpServletResponse
resp)
+ throws IOException, ServletException {
+ String msg = req.getHeader("Authorization");
+ boolean offerBasic = KnownVisitorModule.getInstance().offerBasic(req);
+ log.debug("Message: " + msg);
+ if (msg != null && offerBasic && msg.startsWith("Basic ")) {
+ log.debug("Message starts with Basic.");
+ String base64str = msg.substring(6);
+ String auth = Encode.decode("BASE64", base64str);
+ int index = auth.indexOf(':');
+ String user = (index != -1) ? auth.substring(0, index) : auth;
+ String password = (index != -1) ? auth.substring(index + 1) : "";
+ index = user.indexOf('\\');
+ if (index == -1)
+ index = user.indexOf('/');
+
+ String domain;
+ if (index == -1) {
+ domain = KnownVisitorModule.getInstance().getRealm();
+ } else {
+ domain = user.substring(0, index);
+ }
+
+ user = (index != -1) ? user.substring(index + 1) : user;
+
+
+ try {
+ log.debug("user " + user + " domain " + domain + " password " +
password);
+ KnownVisitorModule.getInstance().ldapLogin(user, password);
+ }
+ catch (NamingException e) {
+ log.debug("" + e.getMessage(), e);
+ // lets try mmbase authentication now
+ return true;
+ }
+
+ req.getSession().setAttribute("NtlmHttpAuth", user);
+ justLoggedIn(req, user);
+
+ return true;
+ }
+ else {
+ HttpSession ssn = req.getSession(false);
+ if (offerBasic && (ssn == null || ssn.getAttribute("NtlmHttpAuth") ==
null)) {
+ log.debug("Not BASIO authenticated, starting authentication.");
+ String realm = KnownVisitorModule.getInstance().getRealm();
+ if (realm == null) {
+ realm = "CMS Container";
+ }
+ resp.addHeader("WWW-Authenticate", "Basic realm=\"" + realm +
"\"");
+ }
+ resp.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
+ resp.setContentLength(0);
+ resp.flushBuffer();
+ return false;
+ }
+ }
+
+ protected boolean alreadyLoggedIn(HttpServletRequest req) {
+ return KnownVisitorModule.getInstance().getVisitor(req) != null;
+ }
+
+ public void justLoggedIn(HttpServletRequest request, String username) {
+ Visitor visitor = new Visitor();
+ visitor.setIdentifier(username);
+ KnownVisitorModule.getInstance().readLdapInfo(visitor);
+ KnownVisitorModule.getInstance().setVisitor(request, visitor);
+ }
+}
Modified:
CMSContainer/branches/b1_5/CMSContainer_Modules/knownvisitor-ntlm/src/java/com/finalist/cmsc/knownvisitor/ntlm/NtlmKnownVisitorModule.java
===================================================================
---
CMSContainer/branches/b1_5/CMSContainer_Modules/knownvisitor-ntlm/src/java/com/finalist/cmsc/knownvisitor/ntlm/NtlmKnownVisitorModule.java
2009-05-20 15:14:29 UTC (rev 35329)
+++
CMSContainer/branches/b1_5/CMSContainer_Modules/knownvisitor-ntlm/src/java/com/finalist/cmsc/knownvisitor/ntlm/NtlmKnownVisitorModule.java
2009-05-20 15:14:45 UTC (rev 35330)
@@ -1,101 +1,137 @@
-package com.finalist.cmsc.knownvisitor.ntlm;
-
-import java.util.Hashtable;
-
-import javax.naming.*;
-import javax.naming.directory.*;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpSession;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-import com.finalist.cmsc.knownvisitor.KnownVisitorModule;
-import com.finalist.cmsc.knownvisitor.Visitor;
-import com.finalist.cmsc.mmbase.PropertiesUtil;
-
-public class NtlmKnownVisitorModule extends KnownVisitorModule {
- static Log log = LogFactory.getLog(NtlmKnownVisitorModule.class);
-
- public static final String SESSION_ATTRIBUTE = "knownVisitor";
-
- public static final String PROPERTY_ENABLED = "knownvisitor-ntlm.enabled";
- public static final String PROPERTY_DOMAIN_CONTROLLER =
"knownvisitor-ntlm.domaincontroller";
- public static final String PROPERTY_DOMAIN = "knownvisitor-ntlm.domain";
- public static final String PROPERTY_IPEXCEPTIONS =
"knownvisitor-ntlm.ipexceptions";
- public static final String PROPERTY_BASIC_AUTH =
"knownvisitor-ntlm.basic-authentication";
-
- public static final String PROPERTY_FIELD_EMAIL =
"knownvisitor-ntlm.field.email";
- public static final String PROPERTY_FIELD_REALNAME =
"knownvisitor-ntlm.field.realname";
- public static final String PROPERTY_FIELD_USERNAME =
"knownvisitor-ntlm.field.username";
- public static final String PROPERTY_LOGONNAME =
"knownvisitor-ntlm.logonname";
- public static final String PROPERTY_LOGONPASSWORD =
"knownvisitor-ntlm.logonpassword";
- public static final String PROPERTY_SEARCHDN = "knownvisitor-ntlm.searchDN";
-
-
-
-
- public NtlmKnownVisitorModule() {
- // nothing
- }
-
-
- @Override
- public Visitor getVisitor(HttpServletRequest request) {
- HttpSession ssn = request.getSession(false);
- return (ssn != null ? (Visitor)
ssn.getAttribute(NtlmKnownVisitorModule.SESSION_ATTRIBUTE) : null);
- }
-
- public void setVisitor(HttpServletRequest request, Visitor visitor) {
- request.getSession().setAttribute(SESSION_ATTRIBUTE, visitor);
- }
-
-
- @Override
- public void init() {
- KnownVisitorModule.setInstance(this);
- }
-
- public void readLdapInfo(Visitor v) {
- NtlmVisitor visitor = (NtlmVisitor) v;
-
- DirContext ctx;
- String query = "(" + getProperty(PROPERTY_FIELD_USERNAME) + "=" +
visitor.getIdentifier() + ")";
- String searchDN = getProperty(PROPERTY_SEARCHDN);
- String server = getProperty(PROPERTY_DOMAIN_CONTROLLER);
-
- // Assemble a hash with data to use when connecting...
- Hashtable<String, String> env = new Hashtable<String, String>();
- env.put(Context.SECURITY_AUTHENTICATION, "simple");
- env.put(Context.SECURITY_PRINCIPAL, "cn=" +
getProperty(PROPERTY_LOGONNAME) + "," + searchDN);
- env.put(Context.SECURITY_CREDENTIALS,
getProperty(PROPERTY_LOGONPASSWORD));
-
- // Make a directory context by connecting with the above details.
- try {
- ctx = new InitialDirContext(env);
- NamingEnumeration<SearchResult> answer = ctx.search("ldap://" +
server + "/" + searchDN, query, null);
- if (answer.hasMoreElements()) {
- SearchResult result = answer.next();
- Attribute values =
result.getAttributes().get(getProperty(PROPERTY_FIELD_REALNAME));
- if (values.size() > 0) {
- visitor.setDisplayName((String) values.get(0));
- }
-
- values =
result.getAttributes().get(getProperty(PROPERTY_FIELD_EMAIL));
- if (values.size() > 0) {
- visitor.setEmail((String) values.get(0));
- }
- }
- }
- catch (NamingException e) {
- log.error("problem reading user from LDAP: ", e);
- visitor.setDisplayName("LDAP failed");
- }
- }
-
-
- private String getProperty(String key) {
- return PropertiesUtil.getProperty(key);
- }
-
-}
+package com.finalist.cmsc.knownvisitor.ntlm;
+
+import java.util.List;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import com.finalist.cmsc.knownvisitor.KnownVisitorModule;
+import com.finalist.cmsc.mmbase.PropertiesUtil;
+
+public class NtlmKnownVisitorModule extends KnownVisitorModule {
+ static Log log = LogFactory.getLog(NtlmKnownVisitorModule.class);
+
+ private static final String PROPERTY_ENABLED = "knownvisitor-ntlm.enabled";
+ private static final String PROPERTY_IPEXCEPTIONS =
"knownvisitor-ntlm.ipexceptions";
+
+ private static final String PROPERTY_DOMAIN_CONTROLLER =
"knownvisitor-ntlm.domaincontroller";
+ private static final String PROPERTY_DOMAIN = "knownvisitor-ntlm.domain";
+
+ private static final String PROPERTY_FIELD_EMAIL =
"knownvisitor-ntlm.field.email";
+ private static final String PROPERTY_FIELD_REALNAME =
"knownvisitor-ntlm.field.realname";
+ private static final String PROPERTY_FIELD_USERNAME =
"knownvisitor-ntlm.field.username";
+ private static final String PROPERTY_LOGONNAME =
"knownvisitor-ntlm.logonname";
+ private static final String PROPERTY_LOGONPASSWORD =
"knownvisitor-ntlm.logonpassword";
+ private static final String PROPERTY_SEARCHDN =
"knownvisitor-ntlm.searchDN";
+
+ private static final String PROPERTY_BASIC_AUTH =
"knownvisitor-ntlm.basic-authentication";
+ private static final String PROPERTY_NTLM_AUTH =
"knownvisitor-ntlm.ntlm-authentication";
+
+ public NtlmKnownVisitorModule() {
+ // nothing
+ }
+
+ @Override
+ public void init() {
+ KnownVisitorModule.setInstance(this);
+ }
+
+ public String getDomainController() {
+ return getProperty(PROPERTY_DOMAIN_CONTROLLER);
+ }
+
+ public String getDomain() {
+ return getProperty(PROPERTY_DOMAIN);
+ }
+
+ public boolean isEnabled() {
+ String property = PropertiesUtil.getProperty(PROPERTY_ENABLED);
+ if (property != null) {
+ return Boolean.parseBoolean(property);
+ }
+ return super.isEnabled();
+ }
+
+ public boolean offerNtlm(HttpServletRequest req) {
+ String property = PropertiesUtil.getProperty(PROPERTY_NTLM_AUTH);
+ if (StringUtils.isNotBlank(property)) {
+ return Boolean.parseBoolean(property);
+ }
+ return false;
+ }
+
+
+ public List<String> getIpExceptions() {
+ List<String> property =
PropertiesUtil.getPropertyAsList(PROPERTY_IPEXCEPTIONS);
+ if (property != null && !property.isEmpty()) {
+ return property;
+ }
+ return super.getIpExceptions();
+ }
+
+ @Override
+ public String getBasicAuth() {
+ return PropertiesUtil.getProperty(PROPERTY_BASIC_AUTH);
+ }
+
+ @Override
+ public String getLdapServer() {
+ String ldapServer = super.getLdapServer();
+ if (StringUtils.isNotBlank(ldapServer)) {
+ return ldapServer;
+ }
+ return getDomainController();
+ }
+
+ public String getLdapPassword() {
+ String property = getProperty(PROPERTY_LOGONPASSWORD);
+ if (StringUtils.isNotBlank(property)) {
+ return property;
+ }
+ return super.getLdapPassword();
+ }
+
+ public String getLdapPrincipal() {
+ String property = getProperty(PROPERTY_LOGONNAME);
+ if (StringUtils.isNotBlank(property)) {
+ return "cn=" + property + "," + getLdapBaseDN();
+ }
+ return super.getLdapPrincipal();
+ }
+
+ public String getLdapBaseDN() {
+ String property = getProperty(PROPERTY_SEARCHDN);
+ if (StringUtils.isNotBlank(property)) {
+ return property;
+ }
+ return super.getLdapBaseDN();
+ }
+
+ public String getLdapUsernameField() {
+ String property = getProperty(PROPERTY_FIELD_USERNAME);
+ if (StringUtils.isNotBlank(property)) {
+ return property;
+ }
+ return super.getLdapUsernameField();
+ }
+
+ public String getLdapEmailField() {
+ String property = getProperty(PROPERTY_FIELD_EMAIL);
+ if (StringUtils.isNotBlank(property)) {
+ return property;
+ }
+ return super.getLdapEmailField();
+ }
+
+ public String getLdapRealnameField() {
+ String property = getProperty(PROPERTY_FIELD_REALNAME);
+ if (StringUtils.isNotBlank(property)) {
+ return property;
+ }
+ return super.getLdapRealnameField();
+ }
+
+}
Deleted:
CMSContainer/branches/b1_5/CMSContainer_Modules/knownvisitor-ntlm/src/java/com/finalist/cmsc/knownvisitor/ntlm/NtlmVisitor.java
===================================================================
---
CMSContainer/branches/b1_5/CMSContainer_Modules/knownvisitor-ntlm/src/java/com/finalist/cmsc/knownvisitor/ntlm/NtlmVisitor.java
2009-05-20 15:14:29 UTC (rev 35329)
+++
CMSContainer/branches/b1_5/CMSContainer_Modules/knownvisitor-ntlm/src/java/com/finalist/cmsc/knownvisitor/ntlm/NtlmVisitor.java
2009-05-20 15:14:45 UTC (rev 35330)
@@ -1,41 +0,0 @@
-package com.finalist.cmsc.knownvisitor.ntlm;
-
-import com.finalist.cmsc.knownvisitor.Visitor;
-
-public class NtlmVisitor extends Visitor {
-
- private String identifier;
- private String displayName;
- private String email;
-
-
- public String getIdentifier() {
- return identifier;
- }
-
-
- public String getDisplayName() {
- return displayName;
- }
-
-
- public void setDisplayName(String displayName) {
- this.displayName = displayName;
- }
-
-
- public void setIdentifier(String identifier) {
- this.identifier = identifier;
- }
-
-
- public String getEmail() {
- return email;
- }
-
-
- public void setEmail(String email) {
- this.email = email;
- }
-
-}
Modified:
CMSContainer/branches/b1_5/CMSContainer_Modules/knownvisitor-ntlm/src/java/com/finalist/cmsc/knownvisitor/ntlm/NtlmVisitorFilter.java
===================================================================
---
CMSContainer/branches/b1_5/CMSContainer_Modules/knownvisitor-ntlm/src/java/com/finalist/cmsc/knownvisitor/ntlm/NtlmVisitorFilter.java
2009-05-20 15:14:29 UTC (rev 35329)
+++
CMSContainer/branches/b1_5/CMSContainer_Modules/knownvisitor-ntlm/src/java/com/finalist/cmsc/knownvisitor/ntlm/NtlmVisitorFilter.java
2009-05-20 15:14:45 UTC (rev 35330)
@@ -1,243 +1,170 @@
-package com.finalist.cmsc.knownvisitor.ntlm;
-
-import java.io.IOException;
-import java.util.*;
-
-import javax.servlet.*;
-import javax.servlet.http.*;
-
-import jcifs.Config;
-import jcifs.UniAddress;
-import jcifs.http.NtlmSsp;
-import jcifs.smb.*;
-import jcifs.util.Base64;
-
-import org.apache.commons.lang.StringUtils;
-import org.mmbase.util.logging.Logger;
-import org.mmbase.util.logging.Logging;
-
-import com.finalist.cmsc.knownvisitor.KnownVisitorModule;
-import com.finalist.cmsc.mmbase.PropertiesUtil;
-
-/**
- * @author Freek Punt, Finalist IT Group
- * @author Jeoffrey Bakker, Finalist IT Group
- */
-public class NtlmVisitorFilter implements Filter {
-
- private static final String realm = "jCIFS";
-
- private static final Logger log =
Logging.getLoggerInstance(NtlmVisitorFilter.class);
-
-
- public void init(FilterConfig filterConfig) {
-
- /*
- * Set jcifs properties we know we want; soTimeout and cachePolicy to
- * 10min.
- */
- Config.setProperty("jcifs.smb.client.soTimeout", "300000");
- Config.setProperty("jcifs.netbios.cachePolicy", "1200");
- }
-
-
- public void destroy() {
- // nothing
- }
-
-
- /**
- * This method simply calls <tt>negotiate( req, resp, false )</tt> and then
- * <tt>chain.doFilter</tt>. You can override and call negotiate manually
- * to achive a variety of different behavior.
- */
- public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException,
- ServletException {
- final HttpServletRequest req = (HttpServletRequest) request;
- final HttpServletResponse resp = (HttpServletResponse) response;
-
- if (isEnabled() && !alreadyLoggedIn(req)) {
- List<String> exceptions = getIpExceptions();
- if (!exceptions.isEmpty()) {
- String clientIp = req.getHeader("X-Forwarded-For");
- if (StringUtils.isBlank(clientIp)) {
- // not behind a proxy or mod_proxy
- clientIp = request.getRemoteAddr();
- }
- if (exceptions.contains(clientIp)) {
- chain.doFilter(req, resp);
- return;
- }
- }
- if (!negotiate(req, resp, false)) {
- return;
- }
- }
-
- chain.doFilter(req, resp);
- }
-
- protected boolean alreadyLoggedIn(HttpServletRequest req) {
- return KnownVisitorModule.getInstance().getVisitor(req) != null;
- }
-
- public void justLoggedIn(HttpServletRequest request,
NtlmPasswordAuthentication ntlm) {
- NtlmVisitor visitor = new NtlmVisitor();
- visitor.setIdentifier(ntlm.getUsername());
- ((NtlmKnownVisitorModule)
KnownVisitorModule.getInstance()).readLdapInfo(visitor);
- ((NtlmKnownVisitorModule)
KnownVisitorModule.getInstance()).setVisitor(request, visitor);
- }
-
- /**
- * Negotiate password hashes with MSIE clients using NTLM SSP
- *
- * @param req
- * The servlet request
- * @param resp
- * The servlet response
- * @param skipAuthentication
- * If true the negotiation is only done if it is initiated by the
- * client (MSIE post requests after successful NTLM SSP
- * authentication). If false and the user has not been
- * authenticated yet the client will be forced to send an
- * authentication (server sends
- * HttpServletResponse.SC_UNAUTHORIZED).
- * @return True if the negotiation is complete, otherwise false
- */
- protected boolean negotiate(HttpServletRequest req, HttpServletResponse
resp, boolean skipAuthentication)
- throws IOException, ServletException {
- UniAddress dc;
- String msg;
- NtlmPasswordAuthentication ntlm = null;
- msg = req.getHeader("Authorization");
- boolean offerBasic = offerBasic(req);
-
- log.debug("Message: " + msg);
- if (msg != null && (msg.startsWith("NTLM ") || (offerBasic &&
msg.startsWith("Basic ")))) {
- if (msg.startsWith("NTLM ")) {
- log.debug("Message starts with NTLM.");
- HttpSession ssn = req.getSession();
- byte[] challenge;
-
- dc = UniAddress.getByName(getDomainController(), true);
- challenge = SmbSession.getChallenge(dc);
-
- if ((ntlm = NtlmSsp.authenticate(req, resp, challenge)) == null) {
- return false;
- }
- /* negotiation complete, remove the challenge object */
- log.debug("negotiation complete, remove the challenge object.");
- ssn.removeAttribute("NtlmHttpChal");
- }
- else {
- log.debug("Message starts with Basic.");
- String auth = new String(Base64.decode(msg.substring(6)),
"US-ASCII");
- int index = auth.indexOf(':');
- String user = (index != -1) ? auth.substring(0, index) : auth;
- String password = (index != -1) ? auth.substring(index + 1) : "";
- index = user.indexOf('\\');
- if (index == -1)
- index = user.indexOf('/');
-
- String domain;
- if (index == -1) {
- domain =
PropertiesUtil.getProperty(NtlmKnownVisitorModule.PROPERTY_DOMAIN);
- } else {
- domain = user.substring(0, index);
- }
-
- user = (index != -1) ? user.substring(index + 1) : user;
- ntlm = new NtlmPasswordAuthentication(domain, user, password);
- dc = UniAddress.getByName(getDomainController(), true);
- }
- try {
-
- SmbSession.logon(dc, ntlm);
-
- if (log.isDebugEnabled()) {
- log.debug("NtlmHttpFilter: " + ntlm + " successfully
authenticated against " + dc);
- }
- }
- catch (SmbAuthException sae) {
- if (log.isServiceEnabled()) {
- log.service("NtlmHttpFilter: " + ntlm.getName() + ": 0x"
- + jcifs.util.Hexdump.toHexString(sae.getNtStatus(), 8) +
": " + sae);
- }
- if (sae.getNtStatus() == NtStatus.NT_STATUS_ACCESS_VIOLATION) {
- /*
- * Server challenge no longer valid for externally supplied
- * password hashes.
- */
- HttpSession ssn = req.getSession(false);
- if (ssn != null) {
- ssn.removeAttribute("NtlmHttpAuth");
- }
- }
- // lets try mmbase authentication now
- return true;
- }
- req.getSession().setAttribute("NtlmHttpAuth", ntlm);
- justLoggedIn(req, ntlm);
- }
- else {
- if (!skipAuthentication) {
- HttpSession ssn = req.getSession(false);
- if (ssn == null || (ntlm = (NtlmPasswordAuthentication)
ssn.getAttribute("NtlmHttpAuth")) == null) {
- log.debug("Not NTLM authenticated, starting authentication.");
- resp.setHeader("WWW-Authenticate", "NTLM");
- if (offerBasic) {
- resp.addHeader("WWW-Authenticate", "Basic realm=\"" + realm
+ "\"");
- }
- resp.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
- resp.setContentLength(0);
- resp.flushBuffer();
- return false;
- }
- }
- }
-
- return ntlm != null;
- }
-
-
- private boolean offerBasic(HttpServletRequest req) {
- boolean offerBasic = req.isSecure();
- if (!offerBasic) {
- String basic =
PropertiesUtil.getProperty(NtlmKnownVisitorModule.PROPERTY_BASIC_AUTH);
- if (StringUtils.isBlank(basic) || "secure".equalsIgnoreCase(basic)) {
- return false;
- }
- else {
- // basic authentication is not forced to be on secured urls and
the current request is not secured
- // This does not mean that the url arrived at the webserver was
not secured. The webserver could
- // proxy the request without using the secured flag.
- return true;
- }
- }
- return offerBasic;
- }
-
-
- private boolean isEnabled() {
- return
Boolean.parseBoolean(PropertiesUtil.getProperty(NtlmKnownVisitorModule.PROPERTY_ENABLED));
- }
-
- private String getDomainController() {
- return
PropertiesUtil.getProperty(NtlmKnownVisitorModule.PROPERTY_DOMAIN_CONTROLLER);
- }
-
- private List<String> getIpExceptions() {
- String prop =
PropertiesUtil.getProperty(NtlmKnownVisitorModule.PROPERTY_IPEXCEPTIONS);
- return convertToList(prop);
- }
-
- private static List<String> convertToList(String prop) {
- List<String> list = new ArrayList<String>();
- StringTokenizer tokenizer = new StringTokenizer(prop, ", \t\n\r\f");
- while (tokenizer.hasMoreTokens()) {
- String str = tokenizer.nextToken();
- list.add(str);
- }
- return list;
- }
-}
+package com.finalist.cmsc.knownvisitor.ntlm;
+
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+
+import javax.servlet.*;
+import javax.servlet.http.*;
+
+import jcifs.Config;
+import jcifs.UniAddress;
+import jcifs.http.NtlmSsp;
+import jcifs.smb.*;
+import jcifs.util.Base64;
+
+import org.apache.commons.lang.StringUtils;
+import org.mmbase.util.logging.Logger;
+import org.mmbase.util.logging.Logging;
+
+import com.finalist.cmsc.knownvisitor.*;
+
+/**
+ * @author Freek Punt, Finalist IT Group
+ * @author Jeoffrey Bakker, Finalist IT Group
+ */
+public class NtlmVisitorFilter extends VisitorFilter {
+
+ private static final Logger log =
Logging.getLoggerInstance(NtlmVisitorFilter.class);
+
+ private static final String NTLM_HTTP_AUTH = "NtlmHttpAuth";
+
+
+ public void init(FilterConfig filterConfig) {
+ super.init(filterConfig);
+ /*
+ * Set jcifs properties we know we want; soTimeout and cachePolicy to
+ * 10min.
+ */
+ Config.setProperty("jcifs.smb.client.soTimeout", "300000");
+ Config.setProperty("jcifs.netbios.cachePolicy", "1200");
+ }
+
+ /**
+ * Negotiate password hashes with MSIE clients using NTLM SSP
+ *
+ * @param req The servlet request
+ * @param resp The servlet response
+ * @return True if the negotiation is complete, otherwise false
+ */
+ protected boolean negotiate(HttpServletRequest req, HttpServletResponse
resp)
+ throws IOException, ServletException {
+ String msg = req.getHeader("Authorization");
+ NtlmKnownVisitorModule module = (NtlmKnownVisitorModule)
KnownVisitorModule.getInstance();
+ boolean offerBasic = module.offerBasic(req);
+ boolean offerNtlm = module.offerNtlm(req);
+ log.debug("Message: " + msg);
+
+ NtlmPasswordAuthentication ntlm = null;
+
+ if (msg != null && (offerNtlm && msg.startsWith("NTLM ") || (offerBasic
&& msg.startsWith("Basic ")))) {
+ String domainController = getDomainController();
+ UniAddress dc = UniAddress.getByName(domainController, true);
+ if (msg.startsWith("NTLM ")) {
+ log.debug("Message starts with NTLM.");
+ HttpSession ssn = req.getSession();
+ byte[] challenge = SmbSession.getChallenge(dc);
+
+ if ((ntlm = NtlmSsp.authenticate(req, resp, challenge)) == null) {
+ return false;
+ }
+ /* negotiation complete,*/
+ log.debug("negotiation complete");
+ }
+ else {
+ ntlm = createBasicAuthToken(msg);
+ }
+ try {
+ SmbSession.logon(dc, ntlm);
+ if (log.isDebugEnabled()) {
+ log.debug("NtlmHttpFilter: " + ntlm + " successfully
authenticated against " + dc);
+ }
+ }
+ catch (SmbAuthException sae) {
+ if (log.isServiceEnabled()) {
+ log.service("NtlmHttpFilter: " + ntlm.getName() + ": 0x"
+ + jcifs.util.Hexdump.toHexString(sae.getNtStatus(), 8) +
": " + sae);
+ }
+ if (sae.getNtStatus() == NtStatus.NT_STATUS_ACCESS_VIOLATION) {
+ /*
+ * Server challenge no longer valid for externally supplied
+ * password hashes.
+ */
+ HttpSession ssn = req.getSession(false);
+ if (ssn != null) {
+ ssn.removeAttribute(NTLM_HTTP_AUTH);
+ }
+ }
+ else{
+ if (sae.getNtStatus() != NtStatus.NT_STATUS_LOGON_FAILURE) {
+ log.info("SmbAuthException" + sae.getNtStatus() + " : " +
sae.getMessage());
+ }
+ }
+ sendChallenge(resp, module, offerBasic, offerNtlm);
+ return false;
+ }
+ req.getSession().setAttribute(NTLM_HTTP_AUTH, ntlm);
+ String username = ntlm.getUsername();
+ justLoggedIn(req, username);
+ }
+ else {
+ HttpSession ssn = req.getSession(false);
+ if (ssn == null || (ntlm = (NtlmPasswordAuthentication)
ssn.getAttribute(NTLM_HTTP_AUTH)) == null) {
+ log.debug("Not NTLM authenticated, starting authentication.");
+ sendChallenge(resp, module, offerBasic, offerNtlm);
+ return false;
+ }
+ }
+
+ return ntlm != null;
+ }
+
+ private void sendChallenge(HttpServletResponse resp, NtlmKnownVisitorModule
module,
+ boolean offerBasic, boolean offerNtlm) throws IOException {
+ if (offerNtlm) {
+ resp.setHeader("WWW-Authenticate", "NTLM");
+ }
+ if (offerBasic) {
+ String realm = module.getRealm();
+ if (StringUtils.isBlank(realm)) {
+ realm = "CMS Container";
+ }
+ resp.addHeader("WWW-Authenticate", "Basic realm=\"" + realm + "\"");
+ }
+ resp.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
+ resp.setContentLength(0);
+ resp.flushBuffer();
+ }
+
+ private NtlmPasswordAuthentication createBasicAuthToken(String msg)
+ throws UnsupportedEncodingException {
+ NtlmPasswordAuthentication ntlm;
+ log.debug("Message starts with Basic.");
+ String auth = new String(Base64.decode(msg.substring(6)), "US-ASCII");
+ int index = auth.indexOf(':');
+ String user = (index != -1) ? auth.substring(0, index) : auth;
+ String password = (index != -1) ? auth.substring(index + 1) : "";
+ index = user.indexOf('\\');
+ if (index == -1)
+ index = user.indexOf('/');
+
+ String domain;
+ if (index == -1) {
+ domain = getDomain();
+ } else {
+ domain = user.substring(0, index);
+ }
+
+ user = (index != -1) ? user.substring(index + 1) : user;
+ ntlm = new NtlmPasswordAuthentication(domain, user, password);
+ return ntlm;
+ }
+
+ private String getDomainController() {
+ return ((NtlmKnownVisitorModule)
KnownVisitorModule.getInstance()).getDomainController();
+ }
+
+ private String getDomain() {
+ return ((NtlmKnownVisitorModule)
KnownVisitorModule.getInstance()).getDomain();
+ }
+
+}
_______________________________________________
Cvs mailing list
[email protected]
http://lists.mmbase.org/mailman/listinfo/cvs