This commit is contained in:
yfujita 2014-03-02 22:09:24 +09:00
parent 7d06bcf15f
commit afbd7baec3
6 changed files with 377 additions and 1 deletions

View file

@ -0,0 +1,115 @@
package jp.sf.fess.filter;
import java.io.IOException;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import jp.sf.fess.entity.LoginInfo;
import jp.sf.fess.helper.AdRoleHelper;
import jp.sf.fess.util.ComponentUtil;
import org.codelibs.sastruts.core.SSCConstants;
import org.seasar.framework.util.StringUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class AdLoginInfoFilter implements Filter {
private static final Logger logger = LoggerFactory
.getLogger(AdLoginInfoFilter.class);
private long updateInterval = 60 * 60 * 1000L; // 1h
private boolean redirectLoginError;
private boolean useTestUser;
private String testUserName;
@Override
public void init(final FilterConfig filterConfig) throws ServletException {
redirectLoginError = "true".equalsIgnoreCase(filterConfig
.getInitParameter("redirectLoginError"));
final String value = filterConfig.getInitParameter("updateInterval");
if (value != null) {
updateInterval = Long.parseLong(value);
}
useTestUser = "true".equalsIgnoreCase(filterConfig
.getInitParameter("useTestUser"));
testUserName = filterConfig.getInitParameter("testUserName");
}
@Override
public void doFilter(final ServletRequest request,
final ServletResponse response, final FilterChain chain)
throws IOException, ServletException {
if (request instanceof HttpServletRequest) {
final HttpServletRequest httpRequest = (HttpServletRequest) request;
final HttpSession session = httpRequest.getSession();
String userId = httpRequest.getRemoteUser();
if (useTestUser) {
userId = testUserName;
}
if (StringUtil.isEmpty(userId)) {
final String servletPath = ((HttpServletRequest) request)
.getServletPath();
if (redirectLoginError
&& ("/index.do".equals(servletPath) || "/mobile.do"
.equals(servletPath))) {
((HttpServletResponse) response)
.sendRedirect("/n2search/error/badRequest");
return;
}
}
LoginInfo loginInfo = (LoginInfo) session
.getAttribute(SSCConstants.USER_INFO);
if (loginInfo == null) {
loginInfo = new LoginInfo();
loginInfo.setUsername(userId);
updateRoleList(userId, loginInfo);
session.setAttribute(SSCConstants.USER_INFO, loginInfo);
} else {
final long now = System.currentTimeMillis();
if (now - loginInfo.getUpdatedTime() > updateInterval) {
loginInfo.setUsername(userId);
updateRoleList(userId, loginInfo);
loginInfo.setUpdatedTime(now);
}
}
}
chain.doFilter(request, response);
}
@Override
public void destroy() {
}
private void updateRoleList(final String userId, final LoginInfo loginInfo) {
final AdRoleHelper adRoleHelper = ComponentUtil.getAdRoleHelper();
final List<String> roleList = adRoleHelper.getRoleList(userId);
final Set<String> roleSet = new HashSet<>();
for (final String role : roleList) {
roleSet.add(role);
}
loginInfo.setRoleSet(roleSet);
if (logger.isDebugEnabled()) {
logger.debug(loginInfo.toString());
}
}
}

View file

@ -0,0 +1,24 @@
package jp.sf.fess.filter;
import javax.servlet.http.HttpServletRequest;
import jp.sf.fess.entity.LoginInfo;
import org.codelibs.sastruts.core.SSCConstants;
import org.codelibs.sastruts.core.entity.UserInfo;
import org.codelibs.sastruts.core.filter.AuthFilter;
public class AdminAuthFilter extends AuthFilter {
@Override
protected UserInfo getUserInfo(final HttpServletRequest req) {
final Object obj = req.getSession()
.getAttribute(SSCConstants.USER_INFO);
if (obj instanceof LoginInfo) {
final LoginInfo loginInfo = (LoginInfo) obj;
if (loginInfo.isAdministrator()) {
return loginInfo;
}
}
return null;
}
}

View file

@ -0,0 +1,92 @@
package jp.sf.fess.helper;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes;
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class AdRoleHelper {
private static final Logger logger = LoggerFactory
.getLogger(AdRoleHelper.class);
public String domain;
public Properties adProperties;
public void setAdProperties(final Properties adProperties) {
this.adProperties = adProperties;
}
public List<String> getRoleList(final String userId) {
final List<String> rolelist = new ArrayList<String>();
DirContext ctx = null;
try {
ctx = new InitialDirContext(adProperties);
//set search conditions
final String filter = "cn=" + userId;
final SearchControls controls = new SearchControls();
controls.setSearchScope(SearchControls.SUBTREE_SCOPE);
String name = domain;
name = "dc=" + name;
name = name.replace(".", ",dc=");
//search
final NamingEnumeration<SearchResult> rslt = ctx.search(name,
filter, controls);
while (rslt.hasMoreElements()) {
final SearchResult srcrslt = rslt.next();
final Attributes attrs = srcrslt.getAttributes();
//get group attr
final Attribute attr = attrs.get("memberOf");
if (attr == null) {
continue;
}
for (int i = 0; i < attr.size(); i++) {
String strTmp = (String) attr.get(i);
int strStart = 0;
int strEnd = 0;
strStart = strTmp.indexOf("CN=");
strStart += "CN=".length();
strEnd = strTmp.indexOf(',');
strTmp = strTmp.substring(strStart, strEnd);
rolelist.add(strTmp);
}
}
} catch (final Exception e) {
logger.warn("Failed to resolve roles: " + userId, e);
} finally {
if (ctx != null) {
try {
ctx.close();
} catch (final NamingException e) {
// ignored
logger.warn("Failed to close: " + userId, e);
}
}
}
logger.debug("ADGroup:" + rolelist.toString());
return rolelist;
}
}

View file

@ -18,6 +18,7 @@ package jp.sf.fess.util;
import jp.sf.fess.api.WebApiManagerFactory;
import jp.sf.fess.ds.DataStoreFactory;
import jp.sf.fess.helper.AdRoleHelper;
import jp.sf.fess.helper.CrawlingConfigHelper;
import jp.sf.fess.helper.CrawlingSessionHelper;
import jp.sf.fess.helper.DatabaseHelper;
@ -92,6 +93,8 @@ public final class ComponentUtil {
private static final String SYSTEM_HELPER = "systemHelper";
private static final String AD_ROLE_HELPER = "adRoleHelper";
private static final String SOLR_GROUP_MANAGER = "solrGroupManager";
private static final String CRAWLER_PROPERTIES = "crawlerProperties";
@ -214,6 +217,10 @@ public final class ComponentUtil {
return SingletonS2Container.getComponent(DATABASE_HELPER);
}
public static AdRoleHelper getAdRoleHelper() {
return SingletonS2Container.getComponent(AD_ROLE_HELPER);
}
public static IndexUpdater getIndexUpdater() {
return SingletonS2Container.getComponent(INDEX_UPDATER);
}

View file

@ -249,4 +249,46 @@
<component name="userAgentName" class="java.lang.String">
<arg>"Mozilla/5.0 (compatible; Fess/" + @jp.sf.fess.Constants@FESS_VERSION + "; +http://fess.codelibs.org/bot.html)"</arg>
</component>
<component name="adProperties" class="java.util.Properties">
<initMethod name="put">
<arg>@javax.naming.Context@INITIAL_CONTEXT_FACTORY</arg>
<arg>"com.sun.jndi.ldap.LdapCtxFactory"</arg>
</initMethod>
<initMethod name="put">
<arg>@javax.naming.directory.DirContext@PROVIDER_URL</arg>
<arg>"ldap://[host]:[port]"</arg>
</initMethod>
<initMethod name="put">
<arg>@javax.naming.directory.DirContext@SECURITY_PRINCIPAL</arg>
<arg>"[loginId]@[domain]"</arg>
</initMethod>
<initMethod name="put">
<arg>@javax.naming.directory.DirContext@SECURITY_CREDENTIALS</arg>
<arg>"password"</arg>
</initMethod>
<initMethod name="put">
<arg>"com.sun.jndi.ldap.connect.timeout"</arg>
<arg>"10000"</arg>
</initMethod>
<initMethod name="put">
<arg>"com.sun.jndi.ldap.connect.pool"</arg>
<arg>"true"</arg>
</initMethod>
<initMethod name="put">
<arg>"com.sun.jndi.connect.pool.timeout"</arg>
<arg>"30000"</arg>
</initMethod>
<initMethod name="put">
<arg>"com.sun.jndi.connect.pool.debug"</arg>
<arg>"all"</arg>
</initMethod>
</component>
<component name="adRoleHelper" class="jp.sf.fess.helper.AdRoleHelper">
<initMethod name="setAdProperties">
<arg>adProperties</arg>
</initMethod>
</component>
</components>

View file

@ -60,7 +60,7 @@
<filter>
<filter-name>authenticationFilter</filter-name>
<filter-class>org.codelibs.sastruts.core.filter.AuthFilter</filter-class>
<filter-class>jp.sf.fess.filter.AdminAuthFilter</filter-class>
<init-param>
<param-name>urlPatterns</param-name>
<param-value>/fess/admin.*</param-value>
@ -89,6 +89,89 @@
</init-param>
</filter>
<!--
<filter>
<filter-name>adLoginInfoFilter</filter-name>
<filter-class>jp.sf.fess.filter.AdLoginInfoFilter</filter-class>
<init-param>
<param-name>redirectLoginError</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>useTestUser</param-name>
<param-value>false</param-value>
</init-param>
<init-param>
<param-name>testUserName</param-name>
<param-value>testUser</param-value>
</init-param>
</filter>
-->
<!-- SPNEGO -->
<!--
<filter>
<filter-name>SpnegoHttpFilter</filter-name>
<filter-class>net.sourceforge.spnego.SpnegoHttpFilter</filter-class>
<init-param>
<param-name>spnego.allow.basic</param-name>
<param-value>false</param-value>
</init-param>
<init-param>
<param-name>spnego.allow.localhost</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>spnego.allow.unsecure.basic</param-name>
<param-value>false</param-value>
</init-param>
<init-param>
<param-name>spnego.login.client.module</param-name>
<param-value>spnego-client</param-value>
</init-param>
<init-param>
<param-name>spnego.krb5.conf</param-name>
<param-value>krb5.conf</param-value>
</init-param>
<init-param>
<param-name>spnego.login.conf</param-name>
<param-value>login.conf</param-value>
</init-param>
<init-param>
<param-name>spnego.preauth.username</param-name>
<param-value>knldguser</param-value>
</init-param>
<init-param>
<param-name>spnego.preauth.password</param-name>
<param-value>zaq12wsx</param-value>
</init-param>
<init-param>
<param-name>spnego.login.server.module</param-name>
<param-value>spnego-server</param-value>
</init-param>
<init-param>
<param-name>spnego.prompt.ntlm</param-name>
<param-value>false</param-value>
</init-param>
<init-param>
<param-name>spnego.logger.level</param-name>
<param-value>1</param-value>
</init-param>
</filter>
-->
<!--
<filter-mapping>
<filter-name>encodingfilter</filter-name>
@ -135,6 +218,19 @@
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
<!--
<filter-mapping>
<filter-name>SpnegoHttpFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>adLoginInfoFilter</filter-name>
<url-pattern>*.do</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
-->
<servlet>
<servlet-name>action</servlet-name>
<servlet-class>org.codelibs.sastruts.core.servlet.SSCActionServlet</servlet-class>