import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.nodetype.NodeType;
+import javax.security.auth.Subject;
+import javax.security.auth.login.LoginException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.argeo.ArgeoException;
+import org.argeo.cms.auth.ArgeoLoginContext;
import org.argeo.cms.i18n.Msg;
import org.argeo.jcr.JcrUtils;
import org.eclipse.rap.rwt.RWT;
import org.eclipse.rap.rwt.client.service.BrowserNavigationListener;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
-import org.springframework.security.core.context.SecurityContextHolder;
/** Manages history and navigation */
abstract class AbstractCmsEntryPoint extends AbstractEntryPoint implements
CmsSession {
private final Log log = LogFactory.getLog(AbstractCmsEntryPoint.class);
+ private Subject subject = new Subject();
+
private Repository repository;
private String workspace;
private Session session;
private BrowserNavigation history;
public AbstractCmsEntryPoint(Repository repository, String workspace) {
- // if (SecurityContextHolder.getContext().getAuthentication() == null) {
- // HttpSession httpSession = RWT.getRequest().getSession();
- // // log.debug("Session: " + httpSession.getId());
- // SecurityContext contextFromSessionObject = (SecurityContext)
- // httpSession
- // .getAttribute(SPRING_SECURITY_CONTEXT_KEY);
- // if (contextFromSessionObject != null)
- // SecurityContextHolder.setContext(contextFromSessionObject);
- // else
- // logAsAnonymous();
- // }
-
this.repository = repository;
this.workspace = workspace;
+
+ // Initial login
+ Subject subject = new Subject();
+ try {
+ new ArgeoLoginContext(KernelHeader.LOGIN_CONTEXT_USER, subject)
+ .login();
+ } catch (LoginException e) {
+ if (log.isTraceEnabled())
+ log.trace("Cannot authenticate user", e);
+ try {
+ new ArgeoLoginContext(KernelHeader.LOGIN_CONTEXT_ANONYMOUS,
+ subject).login();
+ } catch (LoginException eAnonymous) {
+ throw new ArgeoException("Cannot initialize subject",
+ eAnonymous);
+ }
+ }
authChange();
history = RWT.getClient().getService(BrowserNavigation.class);
/** Recreate body UI */
protected abstract void refreshBody();
- /** Log as anonymous */
- protected abstract void logAsAnonymous();
-
/**
* The node to return when no node was found (for authenticated users and
* anonymous)
history.pushState(state, state);
}
+ @Override
+ public Subject getSubject() {
+ return subject;
+ }
+
@Override
public void authChange() {
try {
currentPath = node.getPath();
JcrUtils.logoutQuietly(session);
- if (SecurityContextHolder.getContext().getAuthentication() == null)
- logAsAnonymous();
session = repository.login(workspace);
if (currentPath != null)
node = session.getNode(currentPath);
+++ /dev/null
-package org.argeo.cms;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URL;
-
-import org.eclipse.rap.rwt.service.ResourceLoader;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleContext;
-
-/** {@link ResourceLoader} implementation wrapping an {@link Bundle}. */
-class BundleResourceLoader implements ResourceLoader {
- private final BundleContext bundleContext;
-
- public BundleResourceLoader(BundleContext bundleContext) {
- this.bundleContext = bundleContext;
- }
-
- @Override
- public InputStream getResourceAsStream(String resourceName)
- throws IOException {
- // TODO deal with other bundles
- Bundle bundle = bundleContext.getBundle();
- URL res = bundle.getResource(resourceName);
- if (res == null)
- throw new CmsException("Resource " + resourceName
- + " not found in bundle " + bundle.getSymbolicName());
- return bundleContext.getBundle().getResource(resourceName).openStream();
- }
-
-}
import org.apache.commons.io.IOUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.argeo.cms.auth.LoginRequiredException;
import org.argeo.cms.internal.ImageManagerImpl;
+import org.argeo.cms.util.BundleResourceLoader;
import org.argeo.cms.util.CmsUtils;
import org.argeo.jcr.JcrUtils;
import org.eclipse.gemini.blueprint.context.BundleContextAware;
/** Configures an Argeo CMS RWT application. */
public class CmsApplication implements CmsConstants, ApplicationConfiguration,
BundleContextAware {
- final static Log log = LogFactory.getLog(CmsApplication.class);
+ private final static Log log = LogFactory.getLog(CmsApplication.class);
- // private Map<String, EntryPointFactory> entryPoints = new HashMap<String,
- // EntryPointFactory>();
private Map<String, Map<String, String>> branding = new HashMap<String, Map<String, String>>();
private Map<String, List<String>> styleSheets = new HashMap<String, List<String>>();
private List<String> resources = new ArrayList<String>();
- // private Bundle clientScriptingBundle;
private BundleContext bundleContext;
private Repository repository;
private List<String> roPrincipals = Arrays.asList("anonymous", "everyone");
private List<String> rwPrincipals = Arrays.asList("everyone");
- private CmsLogin cmsLogin;
-
private CmsUiProvider header;
private Map<String, CmsUiProvider> pages = new LinkedHashMap<String, CmsUiProvider>();
}
public void init() throws RepositoryException {
- // if (workspace == null)
- // throw new CmsException(
- // "Workspace must be set when calling initialization."
- // + " Please make sure that read-only and read-write roles"
- // + " have been properly configured:"
- // + " the defaults are open.");
-
Session session = null;
try {
session = JcrUtils.loginOrCreateWorkspace(repository, workspace);
this.workspace = workspace;
}
- public void setCmsLogin(CmsLogin cmsLogin) {
- this.cmsLogin = cmsLogin;
+ public void setCmsLogin(@SuppressWarnings("deprecation") CmsLogin cmsLogin) {
+ // this.cmsLogin = cmsLogin;
+ log.warn("cmsLogin"
+ + " is deprecated and will be removed soon. Adapt your configuration ASAP.");
}
public void setHeader(CmsUiProvider header) {
this.headerHeight = headerHeight;
}
- // public void setEntryPoints(
- // Map<String, EntryPointFactory> entryPointFactories) {
- // this.entryPoints = entryPointFactories;
- // }
-
public void setBranding(Map<String, Map<String, String>> branding) {
this.branding = branding;
}
if (state == null)
throw new CmsException("State cannot be null");
uiProvider.createUi(bodyArea, getNode());
- // if (page == null)
- // throw new CmsException("Page cannot be null");
- // // else if (state.length() == 0)
- // // log.debug("empty state");
- // else if (pages.containsKey(page))
- // pages.get(page).createUi(bodyArea, getNode());
- // else {
- // // try {
- // // RWT.getResponse().sendError(404);
- // // } catch (IOException e) {
- // // log.error("Cannot send 404 code", e);
- // // }
- // throw new CmsException("Unsupported state " + state);
- // }
} catch (RepositoryException e) {
throw new CmsException("Cannot refresh body", e);
}
bodyArea.layout(true, true);
}
- @Override
- protected void logAsAnonymous() {
- cmsLogin.logInAsAnonymous();
- }
-
@Override
protected Node getDefaultNode(Session session)
throws RepositoryException {
if (!session.hasPermission(basePath, "read")) {
if (session.getUserID().equals("anonymous"))
- throw new CmsLoginRequiredException();
+ throw new LoginRequiredException();
else
throw new CmsException("Unauthorized");
}
package org.argeo.cms;
-import javax.security.auth.Subject;
-import javax.security.auth.login.LoginContext;
-import javax.security.auth.login.LoginException;
-
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import org.argeo.ArgeoException;
import org.argeo.cms.auth.ArgeoLoginContext;
-import org.argeo.security.NodeAuthenticationToken;
import org.springframework.security.authentication.AuthenticationManager;
-import org.springframework.security.core.Authentication;
-import org.springframework.security.core.context.SecurityContextHolder;
-/** Gateway for user login, can also generate the related UI. */
+/**
+ * Gateway for user login, can also generate the related UI.
+ *
+ * @deprecated Use {@link ArgeoLoginContext} instead
+ */
+@Deprecated
public class CmsLogin {
private final static Log log = LogFactory.getLog(CmsLogin.class);
- private AuthenticationManager authenticationManager;
-
- // private String systemKey = KernelConstants.DEFAULT_SECURITY_KEY;
- public void logInAsAnonymous() {
- Subject subject = new Subject();
- final LoginContext loginContext;
- try {
- loginContext = new ArgeoLoginContext(
- KernelHeader.LOGIN_CONTEXT_ANONYMOUS, subject);
- loginContext.login();
- } catch (LoginException e1) {
- throw new ArgeoException("Cannot authenticate anonymous", e1);
- }
- }
-
- public void logInWithPassword(String username, char[] password) {
- NodeAuthenticationToken token = new NodeAuthenticationToken(username,
- password);
- Authentication authentication = authenticationManager
- .authenticate(token);
- SecurityContextHolder.getContext().setAuthentication(authentication);
- // HttpSession httpSession = RWT.getRequest().getSession();
- // httpSession.setAttribute(SPRING_SECURITY_CONTEXT_KEY,
- // SecurityContextHolder.getContext());
- if (log.isDebugEnabled())
- log.debug("Authenticated as " + authentication);
+ public CmsLogin() {
+ log.warn("org.argeo.cms.CmsLogin is deprecated and will be removed soon.");
}
+ // private AuthenticationManager authenticationManager;
+ //
+ // public void logInAsAnonymous() {
+ // Subject subject = new Subject();
+ // final LoginContext loginContext;
+ // try {
+ // loginContext = new ArgeoLoginContext(
+ // KernelHeader.LOGIN_CONTEXT_ANONYMOUS, subject);
+ // loginContext.login();
+ // } catch (LoginException e1) {
+ // throw new ArgeoException("Cannot authenticate anonymous", e1);
+ // }
+ // }
+ //
+ // public void logInWithPassword(String username, char[] password) {
+ // NodeAuthenticationToken token = new NodeAuthenticationToken(username,
+ // password);
+ // Authentication authentication = authenticationManager
+ // .authenticate(token);
+ // SecurityContextHolder.getContext().setAuthentication(authentication);
+ // if (log.isDebugEnabled())
+ // log.debug("Authenticated as " + authentication);
+ // }
+ //
public void setAuthenticationManager(
AuthenticationManager authenticationManager) {
- this.authenticationManager = authenticationManager;
+ // this.authenticationManager = authenticationManager;
}
-
- // public void setSystemKey(String systemKey) {
- // this.systemKey = systemKey;
- // }
-
}
+++ /dev/null
-package org.argeo.cms;
-
-/** Throwing this exception triggers redirection to a login page. */
-public class CmsLoginRequiredException extends CmsException {
- private static final long serialVersionUID = 7009402894657958151L;
-
- public CmsLoginRequiredException() {
- super("Login is required");
- }
-
- public CmsLoginRequiredException(String message, Throwable e) {
- super(message, e);
- }
-
- public CmsLoginRequiredException(String message) {
- super(message);
- }
-
-}
package org.argeo.cms;
+import javax.security.auth.Subject;
+
import org.argeo.cms.i18n.Msg;
/** Provides interaction with the CMS system. UNSTABLE API at this stage. */
final ThreadLocal<CmsSession> current = new ThreadLocal<CmsSession>();
+ // NAVIGATION
public void navigateTo(String state);
+ public String getState();
+
+ // SECURITY
public void authChange();
+
+ public Subject getSubject();
+ // SERVICES
public void exception(Throwable e);
public Object local(Msg msg);
- public String getState();
-
public CmsImageManager getImageManager();
}
import javax.security.auth.login.LoginContext;
import javax.security.auth.login.LoginException;
-/** Integrates JAAS with the Argeo platform */
+/**
+ * Integrates JAAS with the Argeo platform, by using the Argeo CMS bundle
+ * classloader as context classloader.
+ */
public class ArgeoLoginContext extends LoginContext {
private static ThreadLocal<ClassLoader> currentContextClassLoader = new ThreadLocal<ClassLoader>() {
@Override
--- /dev/null
+package org.argeo.cms.auth;
+
+import org.argeo.cms.CmsException;
+
+/** Throwing this exception triggers redirection to a login page. */
+public class LoginRequiredException extends CmsException {
+ private static final long serialVersionUID = 7009402894657958151L;
+
+ public LoginRequiredException() {
+ super("Login is required");
+ }
+
+ public LoginRequiredException(String message, Throwable e) {
+ super(message, e);
+ }
+
+ public LoginRequiredException(String message) {
+ super(message);
+ }
+
+}
*/
private final static String SPRING_SECURITY_CONTEXT_KEY = "SPRING_SECURITY_CONTEXT";
- @SuppressWarnings("unused")
private final static Log log = LogFactory.getLog(AbstractLoginModule.class);
private CallbackHandler callbackHandler;
private Subject subject;
Authentication currentAuth = SecurityContextHolder.getContext()
.getAuthentication();
- if (currentAuth == null && Display.getCurrent() != null) {
- // try to load authentication from session
- HttpServletRequest httpRequest = RWT.getRequest();
- HttpSession httpSession = httpRequest.getSession();
- // log.debug(httpSession.getId());
- Object contextFromSessionObject = httpSession
- .getAttribute(SPRING_SECURITY_CONTEXT_KEY);
- if (contextFromSessionObject != null) {
- currentAuth = (Authentication) contextFromSessionObject;
- SecurityContextHolder.getContext().setAuthentication(
- currentAuth);
+ if (currentAuth == null) {
+ // Pre-auth
+ // TODO Do it at Spring Security level?
+ try {
+ // try to load authentication from session
+ HttpServletRequest httpRequest = RWT.getRequest();
+ HttpSession httpSession = httpRequest.getSession();
+ // log.debug(httpSession.getId());
+ Object contextFromSessionObject = httpSession
+ .getAttribute(SPRING_SECURITY_CONTEXT_KEY);
+ if (contextFromSessionObject != null) {
+ currentAuth = (Authentication) contextFromSessionObject;
+ SecurityContextHolder.getContext().setAuthentication(
+ currentAuth);
+ }
+ } catch (Exception e) {
+ if (log.isTraceEnabled())
+ log.trace("Could not get session", e);
+ // silent
}
}
SecurityContext securityContext = SecurityContextHolder
.getContext();
securityContext.setAuthentication(authentication);
- if (Display.getCurrent() != null) {
+ try {
HttpServletRequest httpRequest = RWT.getRequest();
HttpSession httpSession = httpRequest.getSession();
if (httpSession.getAttribute(SPRING_SECURITY_CONTEXT_KEY) == null)
httpSession.setAttribute(SPRING_SECURITY_CONTEXT_KEY,
authentication);
+ } catch (Exception e) {
+ if (log.isTraceEnabled())
+ log.trace("Could not add security context to session",
+ e);
}
return true;
} else {
HttpSession httpSession = httpRequest.getSession();
if (httpSession.getAttribute(SPRING_SECURITY_CONTEXT_KEY) != null)
httpSession.setAttribute(SPRING_SECURITY_CONTEXT_KEY, null);
+ // expire session
+ httpSession.setMaxInactiveInterval(0);
}
return true;
}
protected Authentication processLogin(CallbackHandler callbackHandler)
throws LoginException, UnsupportedCallbackException, IOException,
InterruptedException {
+ if (callbackHandler == null)
+ return null;
+
// ask for username and password
NameCallback nameCallback = new NameCallback("User");
PasswordCallback passwordCallback = new PasswordCallback("Password",
--- /dev/null
+package org.argeo.cms.util;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+
+import org.argeo.cms.CmsException;
+import org.eclipse.rap.rwt.service.ResourceLoader;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+
+/** {@link ResourceLoader} implementation wrapping an {@link Bundle}. */
+public class BundleResourceLoader implements ResourceLoader {
+ private final BundleContext bundleContext;
+
+ public BundleResourceLoader(BundleContext bundleContext) {
+ this.bundleContext = bundleContext;
+ }
+
+ @Override
+ public InputStream getResourceAsStream(String resourceName)
+ throws IOException {
+ // TODO deal with other bundles
+ Bundle bundle = bundleContext.getBundle();
+ URL res = bundle.getResource(resourceName);
+ if (res == null)
+ throw new CmsException("Resource " + resourceName
+ + " not found in bundle " + bundle.getSymbolicName());
+ return bundleContext.getBundle().getResource(resourceName).openStream();
+ }
+
+}
package org.argeo.cms.util;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
import org.argeo.cms.CmsLogin;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.widgets.Control;
/** Open the user menu when clicked */
+@SuppressWarnings("deprecation")
public class OpenUserMenu extends MouseAdapter {
private static final long serialVersionUID = 3634864186295639792L;
- private CmsLogin cmsLogin;
+
+ private final static Log log = LogFactory.getLog(OpenUserMenu.class);
+
+ // private CmsLogin cmsLogin;
@Override
public void mouseDown(MouseEvent e) {
if (e.button == 1) {
- new UserMenu(cmsLogin, (Control) e.getSource());
+ new UserMenu((Control) e.getSource());
}
}
public void setCmsLogin(CmsLogin cmsLogin) {
- this.cmsLogin = cmsLogin;
+ log.warn("org.argeo.cms.CmsLogin is deprecated and will be removed soon");
}
}
\ No newline at end of file
import javax.security.auth.login.LoginException;
import org.argeo.ArgeoException;
-import org.argeo.cms.CmsLogin;
import org.argeo.cms.CmsMsg;
import org.argeo.cms.CmsSession;
import org.argeo.cms.CmsStyles;
/** The site-related user menu */
public class UserMenu extends Shell implements CmsStyles, CallbackHandler {
private static final long serialVersionUID = -5788157651532106301L;
-
- private CmsLogin cmsLogin;
- // private String username = null;
private Text username, password;
- public UserMenu(CmsLogin cmsLogin, Control source) {
+ public UserMenu(Control source) {
super(source.getDisplay(), SWT.NO_TRIM | SWT.BORDER | SWT.ON_TOP);
- this.cmsLogin = cmsLogin;
-
setData(RWT.CUSTOM_VARIANT, CMS_USER_MENU);
String username = SecurityContextHolder.getContext()
close();
dispose();
}
-
});
-
open();
-
}
protected void userUi() {
l.setLayoutData(CmsUtils.fillWidth());
l.setText("<b>" + username + "</b>");
- final CmsSession cmsSession = (CmsSession) getDisplay().getData(
- CmsSession.KEY);
l = new Label(this, SWT.NONE);
l.setData(RWT.CUSTOM_VARIANT, CMS_USER_MENU_ITEM);
l.setText(CmsMsg.logout.lead());
private static final long serialVersionUID = 6444395812777413116L;
public void mouseDown(MouseEvent e) {
- Subject subject = new Subject();
- try {
- new ArgeoLoginContext(KernelHeader.LOGIN_CONTEXT_USER,
- subject).logout();
- new ArgeoLoginContext(KernelHeader.LOGIN_CONTEXT_ANONYMOUS,
- subject).login();
- } catch (LoginException e1) {
- throw new ArgeoException("Cannot authenticate anonymous",
- e1);
- }
- // SecurityContextHolder.getContext().setAuthentication(null);
- // HttpSession httpSession = RWT.getRequest().getSession();
- // httpSession.removeAttribute(SPRING_SECURITY_CONTEXT_KEY);
- close();
- dispose();
- cmsSession.authChange();
+ logout();
}
});
}
gd.widthHint = textWidth;
password.setLayoutData(gd);
- // Listeners
TraverseListener tl = new TraverseListener() {
private static final long serialVersionUID = -1158892811534971856L;
protected void login() {
CmsSession cmsSession = (CmsSession) getDisplay().getData(
CmsSession.KEY);
-
Subject subject = new Subject();
try {
+ //
+ // LOGIN
+ //
new ArgeoLoginContext(KernelHeader.LOGIN_CONTEXT_ANONYMOUS, subject)
.logout();
LoginContext loginContext = new ArgeoLoginContext(
} catch (LoginException e1) {
throw new ArgeoException("Cannot authenticate anonymous", e1);
}
+ close();
+ dispose();
+ cmsSession.authChange();
+ }
- // cmsLogin.logInWithPassword(username, password);
+ protected void logout() {
+ final CmsSession cmsSession = (CmsSession) getDisplay().getData(
+ CmsSession.KEY);
+ Subject subject = new Subject();
+ try {
+ //
+ // LOGOUT
+ //
+ new ArgeoLoginContext(KernelHeader.LOGIN_CONTEXT_USER, subject)
+ .logout();
+ new ArgeoLoginContext(KernelHeader.LOGIN_CONTEXT_ANONYMOUS, subject)
+ .login();
+ } catch (LoginException e1) {
+ throw new ArgeoException("Cannot authenticate anonymous", e1);
+ }
close();
dispose();
- // refreshUi(source.getParent());
cmsSession.authChange();
}
UnsupportedCallbackException {
((NameCallback) callbacks[0]).setName(username.getText());
((PasswordCallback) callbacks[1]).setPassword(password.getTextChars());
- // while (!isDisposed())
- // try {
- // Thread.sleep(500);
- // } catch (InterruptedException e) {
- // // silent
- // }
}
}