final LoginContext loginContext;
try {
- loginContext = new LoginContext(NodeConstants.LOGIN_CONTEXT_USER,
+ loginContext = new LoginContext(NodeConstants.LOGIN_CONTEXT_ANONYMOUS,
subject);
loginContext.login();
} catch (LoginException e1) {
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.argeo.cms.CmsException;
+import org.argeo.cms.auth.CurrentUser;
import org.argeo.cms.auth.HttpRequestCallbackHandler;
import org.argeo.eclipse.ui.specific.UiContext;
import org.argeo.jcr.JcrUtils;
loginContext.login();
} catch (LoginException e) {
try {
- loginContext = new LoginContext(NodeConstants.LOGIN_CONTEXT_USER);
+ loginContext = new LoginContext(NodeConstants.LOGIN_CONTEXT_ANONYMOUS);
loginContext.login();
} catch (LoginException e1) {
throw new CmsException("Cannot log in as anonymous", e1);
if (loginContext == null)
throw new CmsException("Login context should not be null");
try {
+ CurrentUser.logoutCmsSession(loginContext.getSubject());
loginContext.logout();
- LoginContext anonymousLc = new LoginContext(NodeConstants.LOGIN_CONTEXT_USER);
+ LoginContext anonymousLc = new LoginContext(NodeConstants.LOGIN_CONTEXT_ANONYMOUS);
anonymousLc.login();
authChange(anonymousLc);
} catch (LoginException e) {
import javax.security.auth.login.LoginContext;
import javax.security.auth.login.LoginException;
import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
import org.argeo.cms.CmsException;
import org.argeo.cms.auth.CurrentUser;
if (loginContext == null)
throw new CmsException("Login context should not bet null");
try {
+ CurrentUser.logoutCmsSession(loginContext.getSubject());
loginContext.logout();
} catch (LoginException e) {
throw new CmsException("Cannot log out", e);
--- /dev/null
+package org.argeo.cms.auth;
+
+import java.util.Map;
+
+import javax.security.auth.Subject;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.login.LoginException;
+import javax.security.auth.spi.LoginModule;
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.cms.CmsException;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.service.useradmin.Authorization;
+import org.osgi.service.useradmin.UserAdmin;
+
+/** Anonymous CMS user */
+public class AnonymousLoginModule implements LoginModule {
+ private final static Log log = LogFactory.getLog(AnonymousLoginModule.class);
+
+ private Subject subject;
+ private Map<String, Object> sharedState = null;
+
+ // private state
+ private BundleContext bc;
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public void initialize(Subject subject, CallbackHandler callbackHandler, Map<String, ?> sharedState,
+ Map<String, ?> options) {
+ this.subject = subject;
+ this.sharedState = (Map<String, Object>) sharedState;
+ try {
+ bc = FrameworkUtil.getBundle(AnonymousLoginModule.class).getBundleContext();
+ assert bc != null;
+ } catch (Exception e) {
+ throw new CmsException("Cannot initialize login module", e);
+ }
+ }
+
+ @Override
+ public boolean login() throws LoginException {
+ return true;
+ }
+
+ @Override
+ public boolean commit() throws LoginException {
+ UserAdmin userAdmin = bc.getService(bc.getServiceReference(UserAdmin.class));
+ Authorization authorization = userAdmin.getAuthorization(null);
+ CmsAuthUtils.addAuthorization(subject, authorization,
+ (HttpServletRequest) sharedState.get(CmsAuthUtils.SHARED_STATE_HTTP_REQUEST));
+ if (log.isDebugEnabled())
+ log.debug("Anonymous logged in to CMS: " + subject);
+ return true;
+ }
+
+ @Override
+ public boolean abort() throws LoginException {
+ // authorization = null;
+ return true;
+ }
+
+ @Override
+ public boolean logout() throws LoginException {
+ if (log.isDebugEnabled())
+ log.debug("Logging out anonymous from CMS... " + subject);
+ CmsAuthUtils.cleanUp(subject);
+ return true;
+ }
+}
+++ /dev/null
-package org.argeo.cms.auth;
-
-import org.argeo.node.NodeConstants;
-
-/** Public properties of the CMS Kernel */
-interface AuthConstants {
-
- static final String SHARED_STATE_USERNAME = "javax.security.auth.login.name";
- static final String SHARED_STATE_PASSWORD = "javax.security.auth.login.password";
-
- // LOGIN CONTEXTS
- /**
- * @deprecated Use {@link NodeConstants#LOGIN_CONTEXT_USER} instead
- */
- final static String LOGIN_CONTEXT_USER = NodeConstants.LOGIN_CONTEXT_USER;
- /**
- * @deprecated Use {@link NodeConstants#LOGIN_CONTEXT_ANONYMOUS} instead
- */
-// final static String LOGIN_CONTEXT_ANONYMOUS = NodeConstants.LOGIN_CONTEXT_ANONYMOUS;
- /**
- * @deprecated Use {@link NodeConstants#LOGIN_CONTEXT_DATA_ADMIN} instead
- */
- final static String LOGIN_CONTEXT_DATA_ADMIN = NodeConstants.LOGIN_CONTEXT_DATA_ADMIN;
- /**
- * @deprecated Use {@link NodeConstants#LOGIN_CONTEXT_SINGLE_USER} instead
- */
- final static String LOGIN_CONTEXT_SINGLE_USER = NodeConstants.LOGIN_CONTEXT_SINGLE_USER;
-
- // RESERVED ROLES
- // public final static String ROLE_KERNEL = "OU=node";
- /**
- * @deprecated Use {@link NodeConstants#ROLES_BASEDN} instead
- */
- public final static String ROLES_BASEDN = NodeConstants.ROLES_BASEDN;
- /**
- * @deprecated Use {@link NodeConstants#ROLE_ADMIN} instead
- */
- public final static String ROLE_ADMIN = NodeConstants.ROLE_ADMIN;
- public final static String ROLE_GROUP_ADMIN = "cn=groupAdmin," + NodeConstants.ROLES_BASEDN;
- /**
- * @deprecated Use {@link NodeConstants#ROLE_USER_ADMIN} instead
- */
- public final static String ROLE_USER_ADMIN = NodeConstants.ROLE_USER_ADMIN;
- // Special system groups that cannot be edited:
- // user U anonymous = everyone
- /**
- * @deprecated Use {@link NodeConstants#ROLE_USER} instead
- */
- public final static String ROLE_USER = NodeConstants.ROLE_USER;
- /**
- * @deprecated Use {@link NodeConstants#ROLE_ANONYMOUS} instead
- */
- public final static String ROLE_ANONYMOUS = NodeConstants.ROLE_ANONYMOUS;
-
-}
public AuthenticatingUser(String name, char[] password) {
this.name = name;
credentials = new Hashtable<>();
- credentials.put(AuthConstants.SHARED_STATE_USERNAME, name);
+ credentials.put(CmsAuthUtils.SHARED_STATE_NAME, name);
byte[] pwd = charsToBytes(password);
- credentials.put(AuthConstants.SHARED_STATE_PASSWORD, pwd);
+ credentials.put(CmsAuthUtils.SHARED_STATE_PWD, pwd);
}
@Override
package org.argeo.cms.auth;
import java.security.Principal;
-import java.util.Collection;
import java.util.Set;
import java.util.UUID;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
//import org.apache.jackrabbit.core.security.AnonymousPrincipal;
//import org.apache.jackrabbit.core.security.SecurityConstants;
//import org.apache.jackrabbit.core.security.principal.AdminPrincipal;
import org.argeo.cms.internal.auth.CmsSessionImpl;
import org.argeo.cms.internal.auth.ImpliedByPrincipal;
import org.argeo.cms.internal.http.WebCmsSessionImpl;
+import org.argeo.node.NodeConstants;
import org.argeo.node.security.AnonymousPrincipal;
import org.argeo.node.security.DataAdminPrincipal;
import org.argeo.node.security.NodeSecurityUtils;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.InvalidSyntaxException;
-import org.osgi.framework.ServiceReference;
import org.osgi.service.http.HttpContext;
import org.osgi.service.useradmin.Authorization;
class CmsAuthUtils {
- private final static Log log = LogFactory.getLog(CmsAuthUtils.class);
-
/** Shared HTTP request */
final static String SHARED_STATE_HTTP_REQUEST = "org.argeo.cms.auth.http.request";
/** From org.osgi.service.http.HttpContext */
- final static String SHARED_STATE_AUTHORIZATION = "org.osgi.service.useradmin.authorization";
+ // final static String SHARED_STATE_AUTHORIZATION =
+ // "org.osgi.service.useradmin.authorization";
/** From com.sun.security.auth.module.*LoginModule */
final static String SHARED_STATE_NAME = "javax.security.auth.login.name";
/** From com.sun.security.auth.module.*LoginModule */
// Argeo
subject.getPrincipals().removeAll(subject.getPrincipals(X500Principal.class));
subject.getPrincipals().removeAll(subject.getPrincipals(ImpliedByPrincipal.class));
+ subject.getPrincipals().removeAll(subject.getPrincipals(AnonymousPrincipal.class));
+ subject.getPrincipals().removeAll(subject.getPrincipals(DataAdminPrincipal.class));
+
+ subject.getPrivateCredentials().removeAll(subject.getPrivateCredentials(CmsSessionId.class));
+ subject.getPrivateCredentials().removeAll(subject.getPrivateCredentials(Authorization.class));
// Jackrabbit
// subject.getPrincipals().removeAll(subject.getPrincipals(AdminPrincipal.class));
// subject.getPrincipals().removeAll(subject.getPrincipals(AnonymousPrincipal.class));
}
- // SHARED STATE KEYS
- // compatible with com.sun.security.auth.module.*LoginModule
- // public static final String SHARED_STATE_USERNAME =
- // "javax.security.auth.login.name";
- // public static final String SHARED_STATE_PASSWORD =
- // "javax.security.auth.login.password";
-
private static void registerSessionAuthorization(HttpServletRequest request, Subject subject,
Authorization authorization) {
if (request != null) {
HttpSession httpSession = request.getSession();
String httpSessId = httpSession.getId();
- if (authorization.getName() != null) {
- request.setAttribute(HttpContext.REMOTE_USER, authorization.getName());
- request.setAttribute(HttpContext.AUTHORIZATION, authorization);
-
- CmsSession cmsSession = CmsSessionImpl.getByLocalId(httpSessId);
- if (cmsSession == null)
- cmsSession = new WebCmsSessionImpl(subject, authorization, httpSessId);
- request.setAttribute(CmsSession.class.getName(), cmsSession);
- CmsSessionId nodeSessionId = new CmsSessionId(cmsSession.getUuid());
- if (subject.getPrivateCredentials(CmsSessionId.class).size() == 0)
- subject.getPrivateCredentials().add(nodeSessionId);
- else {
- UUID storedSessionId = subject.getPrivateCredentials(CmsSessionId.class).iterator().next()
- .getUuid();
- // if (storedSessionId.equals(httpSessionId.getValue()))
- throw new CmsException(
- "Subject already logged with session " + storedSessionId + " (not " + nodeSessionId + ")");
+ String remoteUser = authorization.getName() != null ? authorization.getName()
+ : NodeConstants.ROLE_ANONYMOUS;
+ request.setAttribute(HttpContext.REMOTE_USER, remoteUser);
+ request.setAttribute(HttpContext.AUTHORIZATION, authorization);
+
+ CmsSession cmsSession = CmsSessionImpl.getByLocalId(httpSessId);
+ if (cmsSession != null) {
+ if (authorization.getName() != null) {
+ if (cmsSession.getAuthorization().getName() == null) {
+ // FIXME make it more generic
+ ((WebCmsSessionImpl) cmsSession).cleanUp();
+ cmsSession = null;
+ } else if (!authorization.getName().equals(cmsSession.getAuthorization().getName())) {
+ throw new CmsException("Inconsistent user " + authorization.getName()
+ + " for existing CMS session " + cmsSession);
+ }
+ } else {// anonymous
+ if (cmsSession.getAuthorization().getName() != null) {
+ // FIXME make it more generic
+ ((WebCmsSessionImpl) cmsSession).cleanUp();
+ cmsSession = null;
+ }
}
}
+
+ if (cmsSession == null)
+ cmsSession = new WebCmsSessionImpl(subject, authorization, httpSessId);
+ // request.setAttribute(CmsSession.class.getName(), cmsSession);
+ CmsSessionId nodeSessionId = new CmsSessionId(cmsSession.getUuid());
+ if (subject.getPrivateCredentials(CmsSessionId.class).size() == 0)
+ subject.getPrivateCredentials().add(nodeSessionId);
+ else {
+ UUID storedSessionId = subject.getPrivateCredentials(CmsSessionId.class).iterator().next().getUuid();
+ // if (storedSessionId.equals(httpSessionId.getValue()))
+ throw new CmsException(
+ "Subject already logged with session " + storedSessionId + " (not " + nodeSessionId + ")");
+ }
} else {
// TODO desktop, CLI
}
}
- static boolean logoutSession(BundleContext bc, Subject subject) {
- UUID nodeSessionId;
- if (subject.getPrivateCredentials(CmsSessionId.class).size() == 1)
- nodeSessionId = subject.getPrivateCredentials(CmsSessionId.class).iterator().next().getUuid();
- else
- return false;
- Collection<ServiceReference<CmsSession>> srs;
- try {
- srs = bc.getServiceReferences(CmsSession.class, "(" + CmsSession.SESSION_UUID + "=" + nodeSessionId + ")");
- } catch (InvalidSyntaxException e) {
- throw new CmsException("Cannot retrieve CMS session #" + nodeSessionId, e);
- }
-
- if (srs.size() == 0) {
- if (log.isTraceEnabled())
- log.warn("No CMS web session found for http session " + nodeSessionId);
- return false;
- } else if (srs.size() > 1)
- throw new CmsException(srs.size() + " CMS web sessions found for http session " + nodeSessionId);
-
- WebCmsSessionImpl cmsSession = (WebCmsSessionImpl) bc.getService(srs.iterator().next());
- cmsSession.cleanUp();
- subject.getPrivateCredentials().removeAll(subject.getPrivateCredentials(CmsSessionId.class));
- if (log.isDebugEnabled())
- log.debug("Cleaned up " + cmsSession);
- return true;
- }
-
public static <T extends Principal> T getSinglePrincipal(Subject subject, Class<T> clss) {
Set<T> principals = subject.getPrincipals(clss);
if (principals.isEmpty())
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.security.acl.Group;
+import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
+import java.util.UUID;
import javax.security.auth.Subject;
import javax.security.auth.x500.X500Principal;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
import org.argeo.cms.CmsException;
+import org.argeo.cms.internal.http.WebCmsSessionImpl;
import org.argeo.eclipse.ui.specific.UiContext;
import org.argeo.node.NodeConstants;
import org.argeo.node.security.NodeAuthenticated;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceReference;
import org.osgi.service.useradmin.Authorization;
/**
* context.
*/
public final class CurrentUser {
+ private final static Log log = LogFactory.getLog(CurrentUser.class);
+ private final static BundleContext bc = FrameworkUtil.getBundle(CurrentUser.class).getBundleContext();
/*
* CURRENT USER API
*/
return subject.getPrivateCredentials(Authorization.class).iterator().next();
}
+ public static boolean logoutCmsSession(Subject subject) {
+ UUID nodeSessionId;
+ if (subject.getPrivateCredentials(CmsSessionId.class).size() == 1)
+ nodeSessionId = subject.getPrivateCredentials(CmsSessionId.class).iterator().next().getUuid();
+ else
+ return false;
+ Collection<ServiceReference<CmsSession>> srs;
+ try {
+ srs = bc.getServiceReferences(CmsSession.class, "(" + CmsSession.SESSION_UUID + "=" + nodeSessionId + ")");
+ } catch (InvalidSyntaxException e) {
+ throw new CmsException("Cannot retrieve CMS session #" + nodeSessionId, e);
+ }
+
+ if (srs.size() == 0) {
+ // if (log.isTraceEnabled())
+ // log.warn("No CMS web session found for http session " +
+ // nodeSessionId);
+ return false;
+ } else if (srs.size() > 1)
+ throw new CmsException(srs.size() + " CMS web sessions found for http session " + nodeSessionId);
+
+ WebCmsSessionImpl cmsSession = (WebCmsSessionImpl) bc.getService(srs.iterator().next());
+ cmsSession.cleanUp();
+// subject.getPrivateCredentials().removeAll(subject.getPrivateCredentials(CmsSessionId.class));
+ if (log.isDebugEnabled())
+ log.debug("Logged out CMS session " + cmsSession.getUuid());
+ return true;
+ }
+
private CurrentUser() {
}
}
if (sr.size() == 1) {
CmsSession cmsSession = bc.getService(sr.iterator().next());
authorization = cmsSession.getAuthorization();
+ if (authorization.getName() == null)
+ authorization = null;// anonymous is not sufficient
if (log.isTraceEnabled())
log.trace("Retrieved authorization from " + cmsSession);
} else if (sr.size() == 0)
sharedState.put(CmsAuthUtils.SHARED_STATE_HTTP_REQUEST, request);
extractHttpAuth(request);
extractClientCertificate(request);
- if (authorization == null)
+ if (authorization == null) {
return false;
- sharedState.put(CmsAuthUtils.SHARED_STATE_AUTHORIZATION, authorization);
- return true;
+ } else {
+ return true;
+ }
}
@Override
public boolean commit() throws LoginException {
- if(authorization!=null){
- CmsAuthUtils.addAuthorization(subject, authorization,request);
-// CmsAuthUtils.registerSessionAuthorization(bc, request, subject, authorization);
- }
-
- // TODO create CmsSession in another module
-// Authorization authorizationToRegister;
-// if (authorization == null) {
-// authorizationToRegister = (Authorization) sharedState.get(CmsAuthUtils.SHARED_STATE_AUTHORIZATION);
-// }
-// else { // this login module did the authorization
-// CmsAuthUtils.addAuthentication(subject, authorization);
-// authorizationToRegister = authorization;
-// }
-// if (authorizationToRegister == null) {
-// return false;
-// }
-// if (request == null)
-// return false;
-// CmsAuthUtils.registerSessionAuthorization(bc, request, subject, authorizationToRegister);
-
byte[] outToken = (byte[]) sharedState.get(CmsAuthUtils.SHARED_STATE_SPNEGO_OUT_TOKEN);
if (outToken != null) {
response.setHeader(CmsAuthUtils.HEADER_WWW_AUTHENTICATE,
}
if (authorization != null) {
- // CmsAuthUtils.addAuthentication(subject, authorization);
+ CmsAuthUtils.addAuthorization(subject, authorization, request);
cleanUp();
return true;
} else {
@Override
public boolean logout() throws LoginException {
- return CmsAuthUtils.logoutSession(bc, subject);
+ cleanUp();
+ return true;
}
private void extractHttpAuth(final HttpServletRequest httpRequest) {
private CallbackHandler callbackHandler;
private Map<String, Object> sharedState = null;
- // private boolean isAnonymous = false;
private List<String> indexedUserProperties = Arrays
.asList(new String[] { LdapAttrs.uid.name(), LdapAttrs.mail.name(), LdapAttrs.cn.name() });
// private state
private BundleContext bc;
- // private Authorization authorization;
private User authenticatedUser = null;
@SuppressWarnings("unchecked")
this.subject = subject;
try {
bc = FrameworkUtil.getBundle(UserAdminLoginModule.class).getBundleContext();
- assert bc != null;
- // this.subject = subject;
this.callbackHandler = callbackHandler;
this.sharedState = (Map<String, Object>) sharedState;
- // if (options.containsKey("anonymous"))
- // isAnonymous =
- // Boolean.parseBoolean(options.get("anonymous").toString());
} catch (Exception e) {
throw new CmsException("Cannot initialize login module", e);
}
@Override
public boolean login() throws LoginException {
- Authorization sharedAuth = (Authorization) sharedState.get(CmsAuthUtils.SHARED_STATE_AUTHORIZATION);
- if (sharedAuth != null) {
- if (callbackHandler == null && sharedAuth.getName() != null)
- throw new LoginException("Shared authorization should be anonymous");
- return false;
- }
+ // Authorization sharedAuth = (Authorization)
+ // sharedState.get(CmsAuthUtils.SHARED_STATE_AUTHORIZATION);
+ // if (sharedAuth != null) {
+ // if (callbackHandler == null && sharedAuth.getName() != null)
+ // throw new LoginException("Shared authorization should be anonymous");
+ // return false;
+ // }
UserAdmin userAdmin = bc.getService(bc.getServiceReference(UserAdmin.class));
if (callbackHandler == null) {// anonymous
// authorization = userAdmin.getAuthorization(null);
final char[] password;
if (sharedState.containsKey(CmsAuthUtils.SHARED_STATE_NAME)
&& sharedState.containsKey(CmsAuthUtils.SHARED_STATE_PWD)) {
+ // NB: required by Basic http auth
username = (String) sharedState.get(CmsAuthUtils.SHARED_STATE_NAME);
password = (char[]) sharedState.get(CmsAuthUtils.SHARED_STATE_PWD);
// // TODO locale?
password = passwordCallback.getPassword();
else
throw new CredentialNotFoundException("No credentials provided");
- // FIXME move Argeo specific convention from user admin to here
}
// User user = userAdmin.getUser(null, username);
if (!user.hasCredential(null, password))
throw new FailedLoginException("Invalid credentials");
authenticatedUser = user;
- // return false;
-
- // authorization = userAdmin.getAuthorization(user);
- // assert authorization != null;
- //
- // sharedState.put(CmsAuthUtils.SHARED_STATE_AUTHORIZATION,
- // authorization);
return true;
}
@Override
public boolean commit() throws LoginException {
- // if (authorization == null) {
- // return false;
- // // throw new LoginException("Authorization should not be null");
- // } else {
- // CmsAuthUtils.addAuthentication(subject, authorization);
- // return true;
- // }
UserAdmin userAdmin = bc.getService(bc.getServiceReference(UserAdmin.class));
Authorization authorization;
if (callbackHandler == null) {// anonymous
Set<KerberosPrincipal> kerberosPrincipals = subject.getPrincipals(KerberosPrincipal.class);
if (kerberosPrincipals.isEmpty()) {
if (authenticatedUser == null) {
- if(log.isTraceEnabled())
+ if (log.isTraceEnabled())
log.trace("Neither kerberos nor user admin login succeeded. Login failed.");
return false;
} else {
throw new LoginException("Kerberos login " + authenticatingUser.getName()
+ " is inconsistent with user admin login " + authenticatedUser.getName());
}
- authorization = Subject.doAs(subject, new PrivilegedAction<Authorization>() {
+ authorization = Subject.doAs(subject, new PrivilegedAction<Authorization>() {
- @Override
- public Authorization run() {
- Authorization authorization = userAdmin.getAuthorization(authenticatingUser);
- return authorization;
- }
+ @Override
+ public Authorization run() {
+ Authorization authorization = userAdmin.getAuthorization(authenticatingUser);
+ return authorization;
+ }
- });
+ });
if (authorization == null)
- throw new LoginException("User admin found no authorization for authenticated user "+authenticatingUser.getName());
+ throw new LoginException(
+ "User admin found no authorization for authenticated user " + authenticatingUser.getName());
}
// Log and monitor new login
- CmsAuthUtils.addAuthorization(subject, authorization, (HttpServletRequest) sharedState.get(CmsAuthUtils.SHARED_STATE_HTTP_REQUEST));
-// HttpServletRequest request = (HttpServletRequest) sharedState.get(CmsAuthUtils.SHARED_STATE_HTTP_REQUEST);
-// if (request != null) {
-// CmsAuthUtils.registerSessionAuthorization(bc, request, subject, authorization);
-// }
+ CmsAuthUtils.addAuthorization(subject, authorization,
+ (HttpServletRequest) sharedState.get(CmsAuthUtils.SHARED_STATE_HTTP_REQUEST));
if (log.isDebugEnabled())
log.debug("Logged in to CMS: " + subject);
return true;
@Override
public boolean abort() throws LoginException {
- // authorization = null;
return true;
}
public boolean logout() throws LoginException {
if (log.isDebugEnabled())
log.debug("Logging out from CMS... " + subject);
+ // boolean httpSessionLogoutOk = CmsAuthUtils.logoutSession(bc,
+ // subject);
CmsAuthUtils.cleanUp(subject);
return true;
}
package org.argeo.cms.internal.auth;
+import java.security.AccessControlContext;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
import java.security.PrivilegedExceptionAction;
import java.util.Collection;
import java.util.HashMap;
import org.argeo.cms.CmsException;
import org.argeo.cms.auth.CmsSession;
import org.argeo.jcr.JcrUtils;
+import org.argeo.node.security.NodeSecurityUtils;
import org.osgi.framework.BundleContext;
import org.osgi.framework.FrameworkUtil;
import org.osgi.framework.InvalidSyntaxException;
private final static BundleContext bc = FrameworkUtil.getBundle(CmsSessionImpl.class).getBundleContext();
private final static Log log = LogFactory.getLog(CmsSessionImpl.class);
- private final Subject initialSubject;
+ // private final Subject initialSubject;
+ private final AccessControlContext initialContext;
private final UUID uuid;
private final String localSessionId;
private final Authorization authorization;
private final LdapName userDn;
+ private final boolean anonymous;
private ServiceRegistration<CmsSession> serviceRegistration;
private LinkedHashSet<Session> additionalDataSessions = new LinkedHashSet<>();
public CmsSessionImpl(Subject initialSubject, Authorization authorization, String localSessionId) {
- this.initialSubject = initialSubject;
+ this.initialContext = Subject.doAs(initialSubject, new PrivilegedAction<AccessControlContext>() {
+
+ @Override
+ public AccessControlContext run() {
+ return AccessController.getContext();
+ }
+
+ });
+ // this.initialSubject = initialSubject;
this.localSessionId = localSessionId;
this.authorization = authorization;
- try {
- this.userDn = new LdapName(authorization.getName());
- } catch (InvalidNameException e) {
- throw new CmsException("Invalid user name " + authorization.getName(), e);
+ if (authorization.getName() != null)
+ try {
+ this.userDn = new LdapName(authorization.getName());
+ this.anonymous = false;
+ } catch (InvalidNameException e) {
+ throw new CmsException("Invalid user name " + authorization.getName(), e);
+ }
+ else {
+ this.userDn = NodeSecurityUtils.ROLE_ANONYMOUS_NAME;
+ this.anonymous = true;
}
this.uuid = UUID.randomUUID();
// register as service
Hashtable<String, String> props = new Hashtable<>();
- props.put(CmsSession.USER_DN, authorization.getName());
+ props.put(CmsSession.USER_DN, userDn.toString());
props.put(CmsSession.SESSION_UUID, uuid.toString());
props.put(CmsSession.SESSION_LOCAL_ID, localSessionId);
serviceRegistration = bc.registerService(CmsSession.class, this, props);
private Session login(Repository repository, String workspace) {
try {
+ Subject initialSubject = Subject.getSubject(initialContext);
return Subject.doAs(initialSubject, new PrivilegedExceptionAction<Session>() {
@Override
public Session run() throws Exception {
return uuid;
}
- public Subject getInitialSubject() {
- return initialSubject;
- }
-
public String getLocalSessionId() {
return localSessionId;
}
return localSessionId;
}
+ public boolean isAnonymous() {
+ return anonymous;
+ }
+
public String toString() {
return "CMS Session local=" + localSessionId + ", uuid=" + uuid;
}
package org.argeo.cms.internal.http;
import java.io.Serializable;
-import java.security.PrivilegedExceptionAction;
import java.util.LinkedHashMap;
import javax.jcr.Repository;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
-import javax.security.auth.Subject;
-import javax.security.auth.login.LoginContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.jackrabbit.server.SessionProvider;
-import org.argeo.cms.CmsException;
import org.argeo.cms.auth.CmsSession;
import org.argeo.jcr.JcrUtils;
-import org.argeo.node.NodeConstants;
/**
* Implements an open session in view patter: a new JCR session is created for
throws javax.jcr.LoginException, ServletException, RepositoryException {
CmsSession cmsSession = WebCmsSessionImpl.getCmsSession(request);
- if (cmsSession == null)
- return anonymousSession(request, rep, workspace);
+// if (cmsSession == null)
+// return anonymousSession(request, rep, workspace);
if (log.isTraceEnabled()) {
log.debug("Get JCR session from " + cmsSession);
}
return session;
}
- private synchronized Session anonymousSession(HttpServletRequest request, Repository repository, String workspace) {
- // TODO rather log in here as anonymous?
- LoginContext lc = (LoginContext) request.getAttribute(NodeConstants.LOGIN_CONTEXT_USER);
- if (lc == null)
- throw new CmsException("No login context available");
- // optimize
- Session session;
- try {
- session = Subject.doAs(lc.getSubject(), new PrivilegedExceptionAction<Session>() {
- @Override
- public Session run() throws Exception {
- return repository.login(workspace);
- }
- });
- } catch (Exception e) {
- throw new CmsException("Cannot log in to JCR", e);
- }
- return session;
- }
+// private synchronized Session anonymousSession(HttpServletRequest request, Repository repository, String workspace) {
+// // TODO rather log in here as anonymous?
+// LoginContext lc = (LoginContext) request.getAttribute(NodeConstants.LOGIN_CONTEXT_ANONYMOUS);
+// if (lc == null)
+// throw new CmsException("No login context available");
+// // optimize
+// Session session;
+// try {
+// session = Subject.doAs(lc.getSubject(), new PrivilegedExceptionAction<Session>() {
+// @Override
+// public Session run() throws Exception {
+// return repository.login(workspace);
+// }
+// });
+// } catch (Exception e) {
+// throw new CmsException("Cannot log in to JCR", e);
+// }
+// return session;
+// }
public synchronized void releaseSession(Session session) {
if (cmsSessions.containsKey(session)) {
CmsSession cmsSession = cmsSessions.get(session);
cmsSession.releaseDataSession(alias, session);
} else {
- // anonymous
+ log.warn("JCR session "+session+" not found in CMS session list. Logging it out...");
JcrUtils.logoutQuietly(session);
}
}
try {
lc = new LoginContext(NodeConstants.LOGIN_CONTEXT_USER, new HttpRequestCallbackHandler(request, response));
lc.login();
- // return true;
} catch (LoginException e) {
- // CallbackHandler token = extractHttpAuth(request, response);
- // String token = request.getHeader(HttpUtils.HEADER_AUTHORIZATION);
- // if (token != null) {
- // try {
- // lc = new LoginContext(NodeConstants.LOGIN_CONTEXT_USER);
- // lc.login();
- // } catch (LoginException e1) {
- // throw new CmsException("Could not login", e1);
- // }
- // } else {
lc = processUnauthorized(request, response);
if (lc == null)
return false;
- // }
}
-
- // still required by open session in view
- // TODO remove it
- request.setAttribute(NodeConstants.LOGIN_CONTEXT_USER, lc);
return true;
}
protected LoginContext processUnauthorized(HttpServletRequest request, HttpServletResponse response) {
// anonymous
try {
- LoginContext lc = new LoginContext(NodeConstants.LOGIN_CONTEXT_USER);
+ LoginContext lc = new LoginContext(NodeConstants.LOGIN_CONTEXT_ANONYMOUS, new HttpRequestCallbackHandler(request, response));
lc.login();
return lc;
} catch (LoginException e1) {
return null;
}
}
-
- // protected CallbackHandler extractHttpAuth(final HttpServletRequest
- // httpRequest, HttpServletResponse httpResponse) {
- // String authHeader =
- // httpRequest.getHeader(HttpUtils.HEADER_AUTHORIZATION);
- // if (authHeader != null) {
- // StringTokenizer st = new StringTokenizer(authHeader);
- // if (st.hasMoreTokens()) {
- // String basic = st.nextToken();
- // if (basic.equalsIgnoreCase("Basic")) {
- // try {
- // // TODO manipulate char[]
- // String credentials = new String(Base64.decodeBase64(st.nextToken()),
- // "UTF-8");
- // // log.debug("Credentials: " + credentials);
- // int p = credentials.indexOf(":");
- // if (p != -1) {
- // final String login = credentials.substring(0, p).trim();
- // final char[] password = credentials.substring(p +
- // 1).trim().toCharArray();
- // return new CallbackHandler() {
- // public void handle(Callback[] callbacks) {
- // for (Callback cb : callbacks) {
- // if (cb instanceof NameCallback)
- // ((NameCallback) cb).setName(login);
- // else if (cb instanceof PasswordCallback)
- // ((PasswordCallback) cb).setPassword(password);
- // else if (cb instanceof HttpRequestCallback) {
- // ((HttpRequestCallback) cb).setRequest(httpRequest);
- // ((HttpRequestCallback) cb).setResponse(httpResponse);
- // }
- // }
- // }
- // };
- // } else {
- // throw new CmsException("Invalid authentication token");
- // }
- // } catch (Exception e) {
- // throw new CmsException("Couldn't retrieve authentication", e);
- // }
- // } else if (basic.equalsIgnoreCase("Negotiate")) {
- // // FIXME generalise
- // String _targetName;
- // try {
- // _targetName = NodeHttp.DEFAULT_SERVICE + "@"
- // + InetAddress.getLocalHost().getCanonicalHostName();
- // } catch (UnknownHostException e) {
- // throw new CmsException("Cannot determins target name", e);
- // }
- // String spnegoToken = st.nextToken();
- // byte[] authToken = Base64.decodeBase64(spnegoToken);
- // GSSManager manager = GSSManager.getInstance();
- // try {
- //// Oid krb5Oid = new Oid("1.3.6.1.5.5.2"); //
- // http://java.sun.com/javase/6/docs/technotes/guides/security/jgss/jgss-features.html
- //// GSSName gssName = manager.createName(_targetName,
- // GSSName.NT_HOSTBASED_SERVICE, krb5Oid);
- //// GSSCredential serverCreds = manager.createCredential(gssName,
- // GSSCredential.INDEFINITE_LIFETIME,
- //// krb5Oid, GSSCredential.ACCEPT_ONLY);
- // GSSCredential serverCreds = Activator.getAcceptorCredentials();
- // if(serverCreds==null)
- // throw new CmsException("No GSS server credentials available");
- // GSSContext gContext = manager.createContext(serverCreds);
- //
- // if (gContext == null) {
- // log.debug("SpnegoUserRealm: failed to establish GSSContext");
- // } else {
- // while (!gContext.isEstablished()) {
- // byte[] outToken = gContext.acceptSecContext(authToken, 0,
- // authToken.length);
- // String outTokenStr = Base64.encodeBase64String(outToken);
- // httpResponse.setHeader("WWW-Authenticate", "Negotiate " + outTokenStr);
- // }
- // if (gContext.isEstablished()) {
- // String clientName = gContext.getSrcName().toString();
- // String role = clientName.substring(clientName.indexOf('@') + 1);
- //
- // log.debug("SpnegoUserRealm: established a security context");
- // log.debug("Client Principal is: " + gContext.getSrcName());
- // log.debug("Server Principal is: " + gContext.getTargName());
- // log.debug("Client Default Role: " + role);
- //
- // // TODO log in
- // }
- // }
- //
- // } catch (GSSException gsse) {
- // log.warn(gsse, gsse);
- // }
- //
- // }
- // }
- // }
- // return null;
- // }
-
protected void askForWwwAuth(HttpServletRequest request, HttpServletResponse response) {
response.setStatus(401);
// response.setHeader(HttpUtils.HEADER_WWW_AUTHENTICATE, "basic
Subject subject = new Subject();
LoginContext lc;
try {
- lc = new LoginContext(NodeConstants.LOGIN_CONTEXT_USER, subject);
+ lc = new LoginContext(NodeConstants.LOGIN_CONTEXT_ANONYMOUS, subject);
lc.login();
return subject;
} catch (LoginException e) {
// e.getException());
// }
}
+
}
private class RemotingServlet extends JcrRemotingServlet {
+++ /dev/null
-package org.argeo.cms.internal.http;
-
-import java.io.Serializable;
-import java.security.PrivilegedExceptionAction;
-
-import javax.jcr.Repository;
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-import javax.security.auth.Subject;
-import javax.security.auth.login.LoginContext;
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.jackrabbit.server.SessionProvider;
-import org.argeo.cms.CmsException;
-import org.argeo.jcr.JcrUtils;
-import org.argeo.node.NodeConstants;
-
-/**
- * Implements an open session in view patter: a new JCR session is created for
- * each request
- */
-class OpenInViewSessionProvider implements SessionProvider, Serializable {
- private final static Log log = LogFactory.getLog(OpenInViewSessionProvider.class);
-
- private static final long serialVersionUID = 2270957712453841368L;
- private final String alias;
-
- public OpenInViewSessionProvider(String alias) {
- this.alias = alias;
- }
-
- public Session getSession(HttpServletRequest request, Repository rep, String workspace)
- throws javax.jcr.LoginException, ServletException, RepositoryException {
- return login(request, rep, workspace);
- }
-
- protected Session login(HttpServletRequest request, Repository repository, String workspace)
- throws RepositoryException {
- if (log.isTraceEnabled())
- log.trace("Repo " + alias + ", login to workspace " + (workspace == null ? "<default>" : workspace)
- + " in web session " + request.getSession().getId());
- LoginContext lc = (LoginContext) request.getAttribute(NodeConstants.LOGIN_CONTEXT_USER);
- if (lc == null)
- throw new CmsException("No login context available");
- try {
- // LoginContext lc = new
- // LoginContext(NodeConstants.LOGIN_CONTEXT_USER,
- // new HttpRequestCallbackHandler(request));
- // lc.login();
- return Subject.doAs(lc.getSubject(), new PrivilegedExceptionAction<Session>() {
- @Override
- public Session run() throws Exception {
- return repository.login(workspace);
- }
- });
- } catch (Exception e) {
- throw new CmsException("Cannot log in to JCR", e);
- }
- // return repository.login(workspace);
- }
-
- public void releaseSession(Session session) {
- JcrUtils.logoutQuietly(session);
- if (log.isTraceEnabled())
- log.trace("Logged out remote JCR session " + session);
- }
-}
}
public static CmsSession getCmsSession(HttpServletRequest request) {
- CmsSession cmsSession = (CmsSession) request.getAttribute(CmsSession.class.getName());
- if (cmsSession != null)
- return cmsSession;
+// CmsSession cmsSession = (CmsSession) request.getAttribute(CmsSession.class.getName());
+// if (cmsSession != null)
+// return cmsSession;
return CmsSessionImpl.getByLocalId(request.getSession().getId());
}
}
org.argeo.cms.auth.UserAdminLoginModule sufficient;
};
+ANONYMOUS {
+ org.argeo.cms.auth.HttpSessionLoginModule sufficient;
+ org.argeo.cms.auth.AnonymousLoginModule sufficient;
+};
+
DATA_ADMIN {
org.argeo.cms.auth.DataAdminLoginModule requisite;
};
org.argeo.cms.auth.UserAdminLoginModule sufficient;
};
+ANONYMOUS {
+ org.argeo.cms.auth.HttpSessionLoginModule sufficient;
+ org.argeo.cms.auth.AnonymousLoginModule sufficient;
+};
+
DATA_ADMIN {
org.argeo.cms.auth.DataAdminLoginModule requisite;
};
*/
String LOGIN_CONTEXT_NODE = "NODE";
String LOGIN_CONTEXT_USER = "USER";
+ String LOGIN_CONTEXT_ANONYMOUS = "ANONYMOUS";
String LOGIN_CONTEXT_DATA_ADMIN = "DATA_ADMIN";
String LOGIN_CONTEXT_SINGLE_USER = "SINGLE_USER";
+++ /dev/null
-package org.argeo.node.security;
-
-import java.security.Principal;
-
-import javax.naming.ldap.LdapName;
-
-import org.argeo.node.NodeConstants;
-
-/** Marker for logged in users. */
-@Deprecated
-public final class UserPrincipal implements Principal {
- private final String name = NodeConstants.ROLE_USER;
-
- @Override
- public String getName() {
- return name;
- }
-
- @Override
- public int hashCode() {
- return name.hashCode();
- }
-
- @Override
- public boolean equals(Object obj) {
- return this == obj;
- }
-
- @Override
- public String toString() {
- return name.toString();
- }
-
- public LdapName getLdapName(){
- return NodeSecurityUtils.ROLE_USER_NAME;
- }
-
-}