import java.util.ArrayList;
import java.util.HashMap;
-import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import javax.jcr.Credentials;
import javax.jcr.Node;
import javax.jcr.Repository;
import javax.jcr.RepositoryException;
import javax.jcr.RepositoryFactory;
import javax.jcr.Session;
import javax.jcr.SimpleCredentials;
+import javax.jcr.Value;
import org.argeo.ArgeoException;
import org.argeo.jcr.ArgeoJcrConstants;
import org.argeo.jcr.ArgeoNames;
-import org.argeo.jcr.ArgeoTypes;
+import org.argeo.jcr.JcrUtils;
import org.argeo.security.SiteAuthenticationToken;
import org.springframework.security.Authentication;
import org.springframework.security.AuthenticationException;
import org.springframework.security.GrantedAuthority;
import org.springframework.security.GrantedAuthorityImpl;
import org.springframework.security.providers.AuthenticationProvider;
+import org.springframework.security.userdetails.UserDetails;
-/** Connects to a JCR repository and delegate authentication to it. */
+/** Connects to a JCR repository and delegates authentication to it. */
public class JcrAuthenticationProvider implements AuthenticationProvider {
- private List<RepositoryFactory> repositoryFactories = new ArrayList<RepositoryFactory>();
- private final String defaultHome;
- private final String userRole;
+ public final static String ROLE_REMOTE_JCR_AUTHENTICATED = "ROLE_REMOTE_JCR_AUTHENTICATED";
- public JcrAuthenticationProvider() {
- this("ROLE_USER", "home");
- }
-
- public JcrAuthenticationProvider(String userRole) {
- this(userRole, "home");
- }
-
- public JcrAuthenticationProvider(String defaultHome, String userRole) {
- super();
- this.defaultHome = defaultHome;
- this.userRole = userRole;
- }
+ private RepositoryFactory repositoryFactory;
public Authentication authenticate(Authentication authentication)
throws AuthenticationException {
return null;
try {
- Map<String, String> parameters = new HashMap<String, String>();
- parameters.put(ArgeoJcrConstants.JCR_REPOSITORY_URI, url);
-
- Repository repository = null;
- for (Iterator<RepositoryFactory> it = repositoryFactories
- .iterator(); it.hasNext();) {
- repository = it.next().getRepository(parameters);
- }
+ SimpleCredentials sp = new SimpleCredentials(siteAuth.getName(),
+ siteAuth.getCredentials().toString().toCharArray());
+ // get repository
+ Repository repository = getRepository(url, sp);
if (repository == null)
return null;
- SimpleCredentials sp = new SimpleCredentials(siteAuth.getName(),
- siteAuth.getCredentials().toString().toCharArray());
String workspace = siteAuth.getWorkspace();
Session session;
if (workspace == null || workspace.trim().equals(""))
session = repository.login(sp);
else
session = repository.login(sp, workspace);
- Node userHome = getUserHome(session);
- GrantedAuthority[] authorities = {};
- return new JcrAuthenticationToken(siteAuth.getPrincipal(),
- siteAuth.getCredentials(), authorities, url, userHome);
+
+ Node userHome = JcrUtils.getUserHome(session);
+
+ // retrieve remote roles
+ Node userProfile = JcrUtils.getUserProfile(session);
+ List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
+ if (userProfile.hasProperty(ArgeoNames.ARGEO_REMOTE_ROLES)) {
+ Value[] roles = userProfile.getProperty(
+ ArgeoNames.ARGEO_REMOTE_ROLES).getValues();
+ for (int i = 0; i < roles.length; i++)
+ authorities.add(new GrantedAuthorityImpl(roles[i]
+ .getString()));
+ }
+ JcrAuthenticationToken authen = new JcrAuthenticationToken(
+ siteAuth.getPrincipal(),
+ siteAuth.getCredentials(),
+ authorities.toArray(new GrantedAuthority[authorities.size()]),
+ url, userHome);
+ authen.setDetails(getUserDetails(userHome, authen));
+
+ return authen;
} catch (RepositoryException e) {
throw new ArgeoException(
"Unexpected exception when authenticating to " + url, e);
}
}
- protected GrantedAuthority[] getGrantedAuthorities(Session session) {
- return new GrantedAuthority[] { new GrantedAuthorityImpl(userRole) };
+ protected Repository getRepository(String url, Credentials credentials)
+ throws RepositoryException {
+ Map<String, String> parameters = new HashMap<String, String>();
+ parameters.put(ArgeoJcrConstants.JCR_REPOSITORY_URI, url);
+ return repositoryFactory.getRepository(parameters);
}
- @SuppressWarnings("rawtypes")
- public boolean supports(Class authentication) {
- return SiteAuthenticationToken.class.isAssignableFrom(authentication);
+ /**
+ * By default, assigns only the role {@value #ROLE_REMOTE_JCR_AUTHENTICATED}
+ * . Should typically be overridden in order to assign more relevant roles.
+ */
+ protected GrantedAuthority[] getGrantedAuthorities(Session session) {
+ return new GrantedAuthority[] { new GrantedAuthorityImpl(
+ ROLE_REMOTE_JCR_AUTHENTICATED) };
}
- protected Node getUserHome(Session session) {
- String userID = "<not yet logged in>";
+ /** Builds user details based on the authentication and the user home. */
+ protected UserDetails getUserDetails(Node userHome, Authentication authen) {
try {
- userID = session.getUserID();
- Node rootNode = session.getRootNode();
- Node homeNode;
- if (!rootNode.hasNode(defaultHome)) {
- homeNode = rootNode.addNode(defaultHome, ArgeoTypes.ARGEO_HOME);
- } else {
- homeNode = rootNode.getNode(defaultHome);
- }
-
- Node userHome;
- if (!homeNode.hasNode(userID)) {
- userHome = homeNode.addNode(userID);
- userHome.addMixin(ArgeoTypes.ARGEO_USER_HOME);
- userHome.setProperty(ArgeoNames.ARGEO_USER_ID, userID);
- } else {
- userHome = homeNode.getNode(userID);
- }
- session.save();
- return userHome;
+ // TODO: loads enabled, locked, etc. from the home node.
+ return new JcrUserDetails(userHome.getPath(), authen.getPrincipal()
+ .toString(), authen.getCredentials().toString(),
+ isEnabled(userHome), true, true, true,
+ authen.getAuthorities());
} catch (Exception e) {
- throw new ArgeoException("Cannot initialize home for user '"
- + userID + "'", e);
+ throw new ArgeoException("Cannot get user details for " + userHome,
+ e);
}
}
- public void setRepositoryFactories(
- List<RepositoryFactory> repositoryFactories) {
- this.repositoryFactories = repositoryFactories;
+ protected Boolean isEnabled(Node userHome) {
+ return true;
}
- public String getDefaultHome() {
- return defaultHome;
+ @SuppressWarnings("rawtypes")
+ public boolean supports(Class authentication) {
+ return SiteAuthenticationToken.class.isAssignableFrom(authentication);
}
- public String getUserRole() {
- return userRole;
+ public void register(RepositoryFactory repositoryFactory,
+ Map<String, String> parameters) {
+ this.repositoryFactory = repositoryFactory;
}
+ public void unregister(RepositoryFactory repositoryFactory,
+ Map<String, String> parameters) {
+ this.repositoryFactory = null;
+ }
}