]> git.argeo.org Git - lgpl/argeo-commons.git/blob - security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/jcr/RemoteJcrAuthenticationProvider.java
Add remember me capabilities to RAP
[lgpl/argeo-commons.git] / security / runtime / org.argeo.security.core / src / main / java / org / argeo / security / jcr / RemoteJcrAuthenticationProvider.java
1 package org.argeo.security.jcr;
2
3 import java.util.ArrayList;
4 import java.util.HashMap;
5 import java.util.List;
6 import java.util.Map;
7
8 import javax.jcr.Credentials;
9 import javax.jcr.Node;
10 import javax.jcr.Repository;
11 import javax.jcr.RepositoryException;
12 import javax.jcr.RepositoryFactory;
13 import javax.jcr.Session;
14 import javax.jcr.SimpleCredentials;
15 import javax.jcr.Value;
16
17 import org.argeo.ArgeoException;
18 import org.argeo.jcr.ArgeoJcrConstants;
19 import org.argeo.jcr.ArgeoNames;
20 import org.argeo.jcr.JcrUtils;
21 import org.argeo.security.NodeAuthenticationToken;
22 import org.springframework.security.Authentication;
23 import org.springframework.security.AuthenticationException;
24 import org.springframework.security.BadCredentialsException;
25 import org.springframework.security.GrantedAuthority;
26 import org.springframework.security.GrantedAuthorityImpl;
27 import org.springframework.security.providers.AuthenticationProvider;
28
29 /** Connects to a JCR repository and delegates authentication to it. */
30 public class RemoteJcrAuthenticationProvider implements AuthenticationProvider,
31 ArgeoNames {
32 private RepositoryFactory repositoryFactory;
33
34 public Authentication authenticate(Authentication authentication)
35 throws AuthenticationException {
36 NodeAuthenticationToken siteAuth = (NodeAuthenticationToken) authentication;
37 String url = siteAuth.getUrl();
38 if (url == null)
39 return null;
40 Session session;
41 Node userProfile;
42
43 try {
44 SimpleCredentials sp = new SimpleCredentials(siteAuth.getName(),
45 siteAuth.getCredentials().toString().toCharArray());
46 // get repository
47 Repository repository = getRepository(url, sp);
48 if (repository == null)
49 return null;
50
51 String workspace = siteAuth.getSecurityWorkspace();
52 session = repository.login(sp, workspace);
53 Node userHome = JcrUtils.getUserHome(session);
54 if (userHome == null || !userHome.hasNode(ArgeoNames.ARGEO_PROFILE))
55 throw new ArgeoException("No profile for user "
56 + siteAuth.getName() + " in security workspace "
57 + siteAuth.getSecurityWorkspace() + " of "
58 + siteAuth.getUrl());
59 userProfile = userHome.getNode(ArgeoNames.ARGEO_PROFILE);
60 } catch (RepositoryException e) {
61 throw new BadCredentialsException(
62 "Cannot authenticate " + siteAuth, e);
63 }
64
65 try {
66 JcrUserDetails.checkAccountStatus(userProfile);
67 // retrieve remote roles
68 List<GrantedAuthority> authoritiesList = new ArrayList<GrantedAuthority>();
69 if (userProfile.hasProperty(ArgeoNames.ARGEO_REMOTE_ROLES)) {
70 Value[] roles = userProfile.getProperty(
71 ArgeoNames.ARGEO_REMOTE_ROLES).getValues();
72 for (int i = 0; i < roles.length; i++)
73 authoritiesList.add(new GrantedAuthorityImpl(roles[i]
74 .getString()));
75 }
76
77 // create authenticated objects
78 GrantedAuthority[] authorities = authoritiesList
79 .toArray(new GrantedAuthority[authoritiesList.size()]);
80 JcrUserDetails userDetails = new JcrUserDetails(userProfile,
81 siteAuth.getCredentials().toString(), authorities);
82 NodeAuthenticationToken authenticated = new NodeAuthenticationToken(
83 siteAuth, authorities);
84 authenticated.setDetails(userDetails);
85 return authenticated;
86 } catch (RepositoryException e) {
87 throw new ArgeoException(
88 "Unexpected exception when authenticating to " + url, e);
89 }
90 }
91
92 protected Repository getRepository(String url, Credentials credentials)
93 throws RepositoryException {
94 Map<String, String> parameters = new HashMap<String, String>();
95 parameters.put(ArgeoJcrConstants.JCR_REPOSITORY_URI, url);
96 return repositoryFactory.getRepository(parameters);
97 }
98
99 @SuppressWarnings("rawtypes")
100 public boolean supports(Class authentication) {
101 return NodeAuthenticationToken.class.isAssignableFrom(authentication);
102 }
103
104 public void setRepositoryFactory(RepositoryFactory repositoryFactory) {
105 this.repositoryFactory = repositoryFactory;
106 }
107
108 }