Active Directory integration

This commit is contained in:
Konstantin Krivopustov 2009-01-11 07:52:00 +00:00
parent 1911739744
commit 7a4e706ef0
15 changed files with 280 additions and 108 deletions

View File

@ -753,7 +753,6 @@
</facet-type>
</autodetection-disabled>
</component>
<component name="FacetManager" />
<component name="IdProvider" IDEtalkID="99EE4594F0AAAC224547C8FE93321E41" />
<component name="InspectionProjectProfileManager">
<option name="PROJECT_PROFILE" value="Project Default" />
@ -1062,12 +1061,10 @@
</library>
<library name="gwt">
<CLASSES>
<root url="jar://$PROJECT_DIR$/../lib/gwt/gwt-user.jar!/" />
<root url="jar://$PROJECT_DIR$/../lib/gwt/gwt-user-1.0.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$PROJECT_DIR$/../lib/gwt/gwt-user.jar!/" />
</SOURCES>
<SOURCES />
</library>
</component>
</project>

View File

@ -0,0 +1,9 @@
cuba.LoginDialog.defaultUser=admin
cuba.LoginDialog.defaultPassword=admin
cuba.UseActiveDirectory=false
cuba.ActiveDirectory.domainController=192.168.1.2
cuba.ActiveDirectory.domain=HAULMONT
cuba.ActiveDirectory.user=admanager
cuba.ActiveDirectory.password=
cuba.ActiveDirectory.domainMap=HAULMONT:192.168.1.2,TEST:192.168.1.1

View File

@ -11,16 +11,12 @@
package com.haulmont.cuba.core.app;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.exception.ExceptionUtils;
import org.apache.commons.lang.StringEscapeUtils;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.*;
import java.net.URI;
import java.util.Map;
import java.util.Collections;
import java.util.ArrayList;
import java.util.List;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import com.haulmont.cuba.core.Locator;
@ -40,6 +36,10 @@ public class ResourceRepository implements ResourceRepositoryMBean
rootPath = URI.create(confUrl).getPath() + "/";
}
public void start() {
loadSystemProperties();
}
public ResourceRepository getImplementation() {
return this;
}
@ -124,4 +124,49 @@ public class ResourceRepository implements ResourceRepositoryMBean
return new String(bytes);
}
public String loadSystemProperties() {
String confUrl = System.getProperty("jboss.server.config.url");
try {
StringBuilder sb = new StringBuilder();
String fileName = URI.create(confUrl).getPath() + "system.properties";
File file = new File(fileName);
if (file.exists()) {
InputStream is = new FileInputStream(fileName);
Properties props;
try {
props = new Properties();
props.load(is);
} finally {
is.close();
}
for (Map.Entry<Object, Object> entry : props.entrySet()) {
if ("".equals(entry.getValue())) {
System.getProperties().remove(entry.getKey());
}
else {
System.getProperties().put(entry.getKey(), entry.getValue());
}
}
sb.append("Properties from ").append(fileName).append(" loaded succesfully\n\n");
}
else {
sb.append("File ").append(fileName).append(" not found\n\n");
}
List<String> strings = new ArrayList<String>(System.getProperties().size());
for (Map.Entry<Object, Object> entry : System.getProperties().entrySet()) {
strings.add(entry.getKey().toString() + "=" + entry.getValue().toString());
}
Collections.sort(strings);
sb.append("Current system properties:\n\n");
for (String s : strings) {
sb.append(StringEscapeUtils.escapeHtml(s)).append("\n");
}
return sb.toString();
} catch (IOException e) {
return ExceptionUtils.getStackTrace(e);
}
}
}

View File

@ -16,6 +16,8 @@ public interface ResourceRepositoryMBean
void create();
void start();
ResourceRepository getImplementation();
String getContent();
@ -25,4 +27,6 @@ public interface ResourceRepositoryMBean
void evictAll();
String getResAsString(String name);
String loadSystemProperties();
}

View File

@ -1,5 +1,5 @@
LoginException.InvalidLoginOrPassword=Invalid login name or password: %s
LoginException.InvalidActiveDirectoryUser=Invalid Active Directory user: %s
LoginException.InvalidLoginOrPassword=Unknown login name or bad password: %s
LoginException.InvalidActiveDirectoryUser=Unknown Active Directory user: %s
LoginException.InvalidProfile=Invalid profile name: %s
NoUserSessionException=User session not found: %s

View File

@ -29,10 +29,12 @@
</facet>
<facet type="gwt" name="GWT">
<configuration>
<setting name="gwtSdkUrl" value="" />
<setting name="gwtScriptOutputStyle" value="DETAILED" />
<setting name="runGwtCompilerOnMake" value="true" />
<setting name="additionalCompilerParameters" value="" />
<setting name="compilerMaxHeapSize" value="128" />
<setting name="compilerOutputPath" value="" />
<setting name="gwtScriptOutputStyle" value="DETAILED" />
<setting name="gwtSdkUrl" value="" />
<setting name="runGwtCompilerOnMake" value="true" />
</configuration>
</facet>
<facet type="gwt" name="GWT">
@ -68,6 +70,5 @@
<orderEntry type="module" module-name="gui" />
<orderEntry type="library" name="gwt" level="project" />
</component>
<component name="libraryTable" />
</module>

View File

@ -23,37 +23,6 @@
<filter>
<filter-name>CubaHttpFilter</filter-name>
<filter-class>com.haulmont.cuba.web.sys.CubaHttpFilter</filter-class>
<init-param>
<param-name>jcifs.http.domainController</param-name>
<param-value>192.168.1.2</param-value>
</init-param>
<init-param>
<param-name>jcifs.smb.client.domain</param-name>
<param-value>HAULMONT</param-value>
</init-param>
<init-param>
<param-name>jcifs.smb.client.username</param-name>
<param-value>admanager</param-value>
</init-param>
<init-param>
<param-name>jcifs.smb.client.password</param-name>
<param-value>&lt;fhcerCtkYfCer25682</param-value>
</init-param>
<!--<init-param>-->
<!--<param-name>jcifs.http.enableBasic</param-name>-->
<!--<param-value>true</param-value>-->
<!--</init-param>-->
<!--<init-param>-->
<!--<param-name>jcifs.http.insecureBasic</param-name>-->
<!--<param-value>true</param-value>-->
<!--</init-param>-->
<init-param>
<param-name>jcifs.util.loglevel</param-name>
<param-value>2</param-value>
</init-param>
</filter>
<filter-mapping>

View File

@ -10,31 +10,28 @@
*/
package com.haulmont.cuba.web;
import com.haulmont.cuba.core.app.ResourceRepositoryService;
import com.haulmont.cuba.core.global.ClientType;
import com.haulmont.cuba.gui.config.ActionsConfig;
import com.haulmont.cuba.gui.config.MenuConfig;
import com.haulmont.cuba.security.global.LoginException;
import com.haulmont.cuba.security.global.UserSession;
import com.haulmont.cuba.security.entity.Profile;
import com.haulmont.cuba.web.log.AppLog;
import com.haulmont.cuba.web.resource.Messages;
import com.haulmont.cuba.core.global.ClientType;
import com.haulmont.cuba.core.app.ResourceRepositoryService;
import com.haulmont.cuba.web.sys.ActiveDirectoryHelper;
import com.itmill.toolkit.Application;
import com.itmill.toolkit.ui.Window;
import com.itmill.toolkit.service.ApplicationContext;
import com.itmill.toolkit.terminal.Terminal;
import com.itmill.toolkit.terminal.ExternalResource;
import com.itmill.toolkit.terminal.gwt.server.WebBrowser;
import com.itmill.toolkit.ui.Window;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.commons.lang.SystemUtils;
import org.jboss.security.SecurityAssociation;
import org.jboss.security.SimplePrincipal;
import javax.servlet.http.HttpServletRequest;
import java.util.Locale;
import java.util.ResourceBundle;
import java.util.List;
import java.io.InputStream;
public class App extends Application implements ConnectionListener, ApplicationContext.TransactionListener
{
@ -51,6 +48,8 @@ public class App extends Application implements ConnectionListener, ApplicationC
private static ThreadLocal<App> currentApp = new ThreadLocal<App>();
private boolean principalIsWrong;
static {
SecurityAssociation.setServer();
}
@ -77,7 +76,7 @@ public class App extends Application implements ConnectionListener, ApplicationC
}
protected LoginWindow createLoginWindow() {
return new LoginWindow(connection);
return new LoginWindow(this, connection);
}
protected AppWindow createAppWindow() {
@ -173,6 +172,20 @@ public class App extends Application implements ConnectionListener, ApplicationC
}
}
if (!connection.isConnected()
&& request.getUserPrincipal() != null
&& !principalIsWrong
&& ActiveDirectoryHelper.useActiveDirectory())
{
String userName = request.getUserPrincipal().getName();
try {
connection.loginActiveDirectory(userName);
principalIsWrong = false;
} catch (LoginException e) {
principalIsWrong = true;
}
}
if (connection.isConnected()) {
UserSession userSession = connection.getSession();
if (userSession != null) {

View File

@ -81,10 +81,9 @@ public class ChangeProfileWindow extends Window
private void fillItems(ListSelect select) {
BasicService bs = ServiceLocator.getBasicService();
UserSession userSession = App.getInstance().getConnection().getSession();
BasicInvocationContext ctx = new BasicInvocationContext()
.setEntityClass(Profile.class)
.setQueryString("select p from sec$Profile p where p.user.id = :userId")
.addQueryParam("userId", userSession.getUserId());
BasicInvocationContext ctx = new BasicInvocationContext().setEntityClass(Profile.class);
ctx.setQueryString("select p from sec$Profile p where p.user.id = :userId")
.addParameter("userId", userSession.getUserId());
List<Profile> list = bs.loadList(ctx);
for (Profile profile : list) {
if (!profile.getName().equals(userSession.getProfile())) {

View File

@ -1,20 +0,0 @@
/*
* Copyright (c) 2008 Haulmont Technology Ltd. All Rights Reserved.
* Haulmont Technology proprietary and confidential.
* Use is subject to license terms.
* Author: Konstantin Krivopustov
* Created: 30.12.2008 11:10:00
*
* $Id$
*/
package com.haulmont.cuba.web;
import org.apache.commons.lang.BooleanUtils;
public class Configuration
{
public static boolean useNtlmAuthentication() {
return BooleanUtils.toBoolean(System.getProperty("cuba.UseNtlmAuthorization"));
}
}

View File

@ -10,23 +10,31 @@
*/
package com.haulmont.cuba.web;
import com.itmill.toolkit.ui.*;
import com.itmill.toolkit.terminal.ExternalResource;
import com.haulmont.cuba.security.global.LoginException;
import org.apache.commons.lang.StringUtils;
import com.haulmont.cuba.web.resource.Messages;
import com.haulmont.cuba.web.sys.ActiveDirectoryHelper;
import com.itmill.toolkit.Application;
import com.itmill.toolkit.service.ApplicationContext;
import com.itmill.toolkit.terminal.ExternalResource;
import com.itmill.toolkit.ui.*;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang.StringUtils;
public class LoginWindow extends Window
import javax.servlet.http.HttpServletRequest;
public class LoginWindow extends Window implements ApplicationContext.TransactionListener
{
private Connection connection;
private TextField loginField;
private TextField passwdField;
public LoginWindow(Connection connection) {
public LoginWindow(App app, Connection connection) {
super("CUBA Login");
this.connection = connection;
app.getContext().addTransactionListener(this);
OrderedLayout layout = new FormLayout();
layout.setSpacing(true);
layout.setMargin(true);
@ -51,29 +59,54 @@ public class LoginWindow extends Window
}
private void initFields() {
String defaultUser = System.getProperty("cuba.LoginDialog.defaultUser");
if (!StringUtils.isBlank(defaultUser))
loginField.setValue(defaultUser);
else
if (ActiveDirectoryHelper.useActiveDirectory()) {
loginField.setValue(null);
passwdField.setValue("");
}
else {
String defaultUser = System.getProperty(Properties.DEF_USER);
if (!StringUtils.isBlank(defaultUser))
loginField.setValue(defaultUser);
else
loginField.setValue("");
String defaultPassw = System.getProperty("cuba.LoginDialog.defaultPassword");
if (!StringUtils.isBlank(defaultPassw))
passwdField.setValue(defaultPassw);
else
passwdField.setValue(null);
String defaultPassw = System.getProperty(Properties.DEF_PASSWORD);
if (!StringUtils.isBlank(defaultPassw))
passwdField.setValue(defaultPassw);
else
passwdField.setValue("");
}
}
private class SubmitListener implements Button.ClickListener
public void transactionStart(Application application, Object transactionData) {
HttpServletRequest request = (HttpServletRequest) transactionData;
if (request.getUserPrincipal() != null
&& ActiveDirectoryHelper.useActiveDirectory()
&& loginField.getValue() == null)
{
loginField.setValue(request.getUserPrincipal().getName());
}
}
public void transactionEnd(Application application, Object transactionData) {
}
protected class SubmitListener implements Button.ClickListener
{
public void buttonClick(Button.ClickEvent event) {
String login = (String) loginField.getValue();
String passwd = DigestUtils.md5Hex((String) passwdField.getValue());
try {
connection.login(login, passwd);
if (ActiveDirectoryHelper.useActiveDirectory()) {
ActiveDirectoryHelper.authenticate(login, (String) passwdField.getValue());
connection.loginActiveDirectory(login);
}
else {
String passwd = DigestUtils.md5Hex((String) passwdField.getValue());
connection.login(login, passwd);
}
open(new ExternalResource(App.getInstance().getURL()));
} catch (LoginException e) {
showNotification(e.getMessage());
showNotification(Messages.getString("loginWindow.loginFailed"), e.getMessage(), Notification.TYPE_ERROR_MESSAGE);
}
}
}

View File

@ -0,0 +1,24 @@
/*
* Copyright (c) 2008 Haulmont Technology Ltd. All Rights Reserved.
* Haulmont Technology proprietary and confidential.
* Use is subject to license terms.
* Author: Konstantin Krivopustov
* Created: 30.12.2008 11:10:00
*
* $Id$
*/
package com.haulmont.cuba.web;
public class Properties
{
public static final String DEF_USER = "cuba.LoginDialog.defaultUser";
public static final String DEF_PASSWORD = "cuba.LoginDialog.defaultPassword";
public static final String USE_AD = "cuba.UseActiveDirectory";
public static final String AD_DOMAIN_CONTROLLER = "cuba.ActiveDirectory.domainController";
public static final String AD_DOMAIN = "cuba.ActiveDirectory.domain";
public static final String AD_DOMAIN_USER = "cuba.ActiveDirectory.user";
public static final String AD_DOMAIN_PASSWORD = "cuba.ActiveDirectory.password";
public static final String AD_DOMAIN_MAP = "cuba.ActiveDirectory.domainMap";
}

View File

@ -26,4 +26,12 @@ changeProfileWindow.label=Warning! All open windows will be closed.
changeProfileWindow.button=Select
logWindow.caption=Application Log
logWindow.refreshBtn=Refresh
logWindow.refreshBtn=Refresh
loginWindow.loginFailed=Login failed
activeDirectory.invalidName=Invalid Active Directory user name: %s
activeDirectory.unknownDomain=Active Directory configuration doesn't contain IP for domain %s
activeDirectory.unknownHost=Active Directory authentication error: unknown host %s
activeDirectory.authenticationError=Active Directory authentication failed: %s
activeDirectory.unknownError=Active Directory authentication error: %s

View File

@ -0,0 +1,70 @@
/*
* Copyright (c) 2008 Haulmont Technology Ltd. All Rights Reserved.
* Haulmont Technology proprietary and confidential.
* Use is subject to license terms.
* Author: Konstantin Krivopustov
* Created: 10.01.2009 13:16:42
*
* $Id$
*/
package com.haulmont.cuba.web.sys;
import com.haulmont.cuba.security.global.LoginException;
import com.haulmont.cuba.web.Properties;
import com.haulmont.cuba.web.resource.Messages;
import jcifs.UniAddress;
import jcifs.smb.NtlmPasswordAuthentication;
import jcifs.smb.SmbAuthException;
import jcifs.smb.SmbException;
import jcifs.smb.SmbSession;
import org.apache.commons.lang.BooleanUtils;
import org.apache.commons.lang.StringUtils;
import java.net.UnknownHostException;
import java.util.HashMap;
import java.util.Map;
public class ActiveDirectoryHelper
{
public static boolean useActiveDirectory() {
return BooleanUtils.toBoolean(System.getProperty(Properties.USE_AD));
}
public static void authenticate(String login, String password) throws LoginException {
int p = login.indexOf('\\');
if (p <= 0)
throw new LoginException(Messages.getString("activeDirectory.invalidName"), login);
String domain = login.substring(0, p);
String user = login.substring(p+1);
String dcIp = getActiveDirectoryDomains().get(domain);
if (StringUtils.isBlank(dcIp))
throw new LoginException(Messages.getString("activeDirectory.unknownDomain"), domain);
try {
UniAddress dc = UniAddress.getByName(dcIp);
NtlmPasswordAuthentication cred = new NtlmPasswordAuthentication(domain, user, password);
SmbSession.logon(dc, cred);
} catch (UnknownHostException e) {
throw new LoginException(Messages.getString("activeDirectory.unknownHost"), dcIp);
} catch (SmbAuthException e) {
throw new LoginException(Messages.getString("activeDirectory.authenticationError"), e.getMessage());
} catch (SmbException e) {
throw new LoginException(Messages.getString("activeDirectory.unknownError"), e.getMessage());
}
}
private static Map<String, String> getActiveDirectoryDomains() {
String s = System.getProperty(Properties.AD_DOMAIN_MAP);
Map<String, String> map = new HashMap<String, String>();
if (!StringUtils.isBlank(s)) {
String[] strings = s.split(",");
for (String str : strings) {
int p = str.indexOf(':');
if (p > 0) {
map.put(str.substring(0, p), str.substring(p+1));
}
}
}
return map;
}
}

View File

@ -10,22 +10,42 @@
*/
package com.haulmont.cuba.web.sys;
import com.haulmont.cuba.web.Configuration;
import com.haulmont.cuba.web.Properties;
import jcifs.http.NtlmHttpFilter;
import jcifs.Config;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.security.Principal;
import org.apache.commons.lang.StringUtils;
public class CubaHttpFilter extends NtlmHttpFilter
{
public void init(FilterConfig filterConfig) throws ServletException {
String s = System.getProperty(Properties.AD_DOMAIN_CONTROLLER);
if (!StringUtils.isBlank(s))
Config.setProperty("jcifs.http.domainController", s);
s = System.getProperty(Properties.AD_DOMAIN);
if (!StringUtils.isBlank(s))
Config.setProperty("jcifs.smb.client.domain", s);
s = System.getProperty(Properties.AD_DOMAIN_USER);
if (!StringUtils.isBlank(s))
Config.setProperty("jcifs.smb.client.username", s);
s = System.getProperty(Properties.AD_DOMAIN_PASSWORD);
if (!StringUtils.isBlank(s))
Config.setProperty("jcifs.smb.client.password", s);
super.init(filterConfig);
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
if (Configuration.useNtlmAuthentication()) {
if (ActiveDirectoryHelper.useActiveDirectory()) {
HttpServletRequest req = (HttpServletRequest)request;
HttpServletResponse resp = (HttpServletResponse)response;