]> git.argeo.org Git - lgpl/argeo-commons.git/blob - security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/jcr/JcrAuthenticationProvider.java
c19e709a1547e91e7fd144c628e6507ce1c23698
[lgpl/argeo-commons.git] / security / runtime / org.argeo.security.core / src / main / java / org / argeo / security / jcr / JcrAuthenticationProvider.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.SiteAuthenticationToken;
22 import org.springframework.security.Authentication;
23 import org.springframework.security.AuthenticationException;
24 import org.springframework.security.GrantedAuthority;
25 import org.springframework.security.GrantedAuthorityImpl;
26 import org.springframework.security.providers.AuthenticationProvider;
27 import org.springframework.security.userdetails.UserDetails;
28
29 /** Connects to a JCR repository and delegates authentication to it. */
30 public class JcrAuthenticationProvider implements AuthenticationProvider {
31 public final static String ROLE_REMOTE_JCR_AUTHENTICATED = "ROLE_REMOTE_JCR_AUTHENTICATED";
32
33 private RepositoryFactory repositoryFactory;
34
35 public Authentication authenticate(Authentication authentication)
36 throws AuthenticationException {
37 if (!(authentication instanceof SiteAuthenticationToken))
38 return null;
39 SiteAuthenticationToken siteAuth = (SiteAuthenticationToken) authentication;
40 String url = siteAuth.getUrl();
41 if (url == null)
42 return null;
43
44 try {
45 SimpleCredentials sp = new SimpleCredentials(siteAuth.getName(),
46 siteAuth.getCredentials().toString().toCharArray());
47 // get repository
48 Repository repository = getRepository(url, sp);
49 if (repository == null)
50 return null;
51
52 String workspace = siteAuth.getWorkspace();
53 Session session;
54 if (workspace == null || workspace.trim().equals(""))
55 session = repository.login(sp);
56 else
57 session = repository.login(sp, workspace);
58
59 Node userHome = JcrUtils.getUserHome(session);
60
61 // retrieve remote roles
62 Node userProfile = JcrUtils.getUserProfile(session);
63 List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
64 if (userProfile.hasProperty(ArgeoNames.ARGEO_REMOTE_ROLES)) {
65 Value[] roles = userProfile.getProperty(
66 ArgeoNames.ARGEO_REMOTE_ROLES).getValues();
67 for (int i = 0; i < roles.length; i++)
68 authorities.add(new GrantedAuthorityImpl(roles[i]
69 .getString()));
70 }
71 JcrAuthenticationToken authen = new JcrAuthenticationToken(
72 siteAuth.getPrincipal(),
73 siteAuth.getCredentials(),
74 authorities.toArray(new GrantedAuthority[authorities.size()]),
75 url, userHome);
76 authen.setDetails(getUserDetails(userHome, authen));
77
78 return authen;
79 } catch (RepositoryException e) {
80 throw new ArgeoException(
81 "Unexpected exception when authenticating to " + url, e);
82 }
83 }
84
85 protected Repository getRepository(String url, Credentials credentials)
86 throws RepositoryException {
87 Map<String, String> parameters = new HashMap<String, String>();
88 parameters.put(ArgeoJcrConstants.JCR_REPOSITORY_URI, url);
89 return repositoryFactory.getRepository(parameters);
90 }
91
92 /**
93 * By default, assigns only the role {@value #ROLE_REMOTE_JCR_AUTHENTICATED}
94 * . Should typically be overridden in order to assign more relevant roles.
95 */
96 protected GrantedAuthority[] getGrantedAuthorities(Session session) {
97 return new GrantedAuthority[] { new GrantedAuthorityImpl(
98 ROLE_REMOTE_JCR_AUTHENTICATED) };
99 }
100
101 /** Builds user details based on the authentication and the user home. */
102 protected UserDetails getUserDetails(Node userHome, Authentication authen) {
103 try {
104 // TODO: loads enabled, locked, etc. from the home node.
105 return new JcrUserDetails(userHome.getPath(), authen.getPrincipal()
106 .toString(), authen.getCredentials().toString(),
107 isEnabled(userHome), true, true, true,
108 authen.getAuthorities());
109 } catch (Exception e) {
110 throw new ArgeoException("Cannot get user details for " + userHome,
111 e);
112 }
113 }
114
115 protected Boolean isEnabled(Node userHome) {
116 return true;
117 }
118
119 @SuppressWarnings("rawtypes")
120 public boolean supports(Class authentication) {
121 return SiteAuthenticationToken.class.isAssignableFrom(authentication);
122 }
123
124 public void register(RepositoryFactory repositoryFactory,
125 Map<String, String> parameters) {
126 this.repositoryFactory = repositoryFactory;
127 }
128
129 public void unregister(RepositoryFactory repositoryFactory,
130 Map<String, String> parameters) {
131 this.repositoryFactory = null;
132 }
133 }