]> git.argeo.org Git - lgpl/argeo-commons.git/blob - jackrabbit/ArgeoLoginModule.java
Prepare next development cycle
[lgpl/argeo-commons.git] / jackrabbit / ArgeoLoginModule.java
1 package org.argeo.security.jackrabbit;
2
3 import java.security.Principal;
4 import java.security.acl.Group;
5 import java.util.LinkedHashSet;
6 import java.util.Map;
7 import java.util.Set;
8
9 import javax.jcr.Credentials;
10 import javax.jcr.RepositoryException;
11 import javax.jcr.Session;
12 import javax.jcr.SimpleCredentials;
13 import javax.security.auth.callback.CallbackHandler;
14 import javax.security.auth.login.LoginException;
15
16 import org.apache.jackrabbit.core.security.AnonymousPrincipal;
17 import org.apache.jackrabbit.core.security.authentication.AbstractLoginModule;
18 import org.apache.jackrabbit.core.security.authentication.Authentication;
19 import org.apache.jackrabbit.core.security.principal.AdminPrincipal;
20 import org.argeo.security.SystemAuthentication;
21 import org.springframework.security.GrantedAuthority;
22 import org.springframework.security.context.SecurityContextHolder;
23 import org.springframework.security.providers.anonymous.AnonymousAuthenticationToken;
24
25 /** Jackrabbit login mechanism based on Spring Security */
26 public class ArgeoLoginModule extends AbstractLoginModule {
27 private String adminRole = "ROLE_ADMIN";
28
29 @Override
30 public boolean login() throws LoginException {
31 boolean loginOk = super.login();
32 if (!loginOk) {
33 org.springframework.security.Authentication authen = (org.springframework.security.Authentication) SecurityContextHolder
34 .getContext().getAuthentication();
35 }
36 return loginOk;
37 }
38
39 @Override
40 public boolean commit() throws LoginException {
41 boolean commitOk = super.commit();
42 if (!commitOk) {
43 org.springframework.security.Authentication authen = (org.springframework.security.Authentication) SecurityContextHolder
44 .getContext().getAuthentication();
45 }
46 return commitOk;
47 }
48
49 /**
50 * Returns the Spring {@link org.springframework.security.Authentication}
51 * (which can be null)
52 */
53 @Override
54 protected Principal getPrincipal(Credentials credentials) {
55 org.springframework.security.Authentication authen = SecurityContextHolder
56 .getContext().getAuthentication();
57 return authen;
58 }
59
60 protected Set<Principal> getPrincipals() {
61 // clear already registered Jackrabbit principals
62 // clearPrincipals(AdminPrincipal.class);
63 // clearPrincipals(AnonymousPrincipal.class);
64 // clearPrincipals(GrantedAuthorityPrincipal.class);
65
66 return syncPrincipals();
67 }
68
69 protected Set<Principal> syncPrincipals() {
70 // use linked HashSet instead of HashSet in order to maintain the order
71 // of principals (as in the Subject).
72 org.springframework.security.Authentication authen = (org.springframework.security.Authentication) principal;
73
74 Set<Principal> principals = new LinkedHashSet<Principal>();
75 principals.add(authen);
76
77 if (authen instanceof SystemAuthentication) {
78 principals.add(new AdminPrincipal(authen.getName()));
79 principals.add(new ArgeoSystemPrincipal(authen.getName()));
80 } else if (authen instanceof AnonymousAuthenticationToken) {
81 principals.add(new AnonymousPrincipal());
82 } else {
83 for (GrantedAuthority ga : authen.getAuthorities()) {
84 principals.add(new GrantedAuthorityPrincipal(ga));
85 // FIXME: make it more generic
86 if (adminRole.equals(ga.getAuthority()))
87 principals.add(new AdminPrincipal(authen.getName()));
88 }
89 }
90
91 // remove previous credentials
92 Set<SimpleCredentials> thisCredentials = subject
93 .getPublicCredentials(SimpleCredentials.class);
94 if (thisCredentials != null)
95 thisCredentials.clear();
96 // override credentials since we did not used the one passed to us
97 // credentials = new SimpleCredentials(authen.getName(), authen
98 // .getCredentials().toString().toCharArray());
99
100 return principals;
101 }
102
103 /**
104 * Super implementation removes all {@link Principal}, the Spring
105 * {@link org.springframework.security.Authentication} as well. Here we
106 * simply clear Jackrabbit related {@link Principal}s.
107 */
108 @Override
109 public boolean logout() throws LoginException {
110 clearPrincipals(AdminPrincipal.class);
111 clearPrincipals(ArgeoSystemPrincipal.class);
112 clearPrincipals(AnonymousPrincipal.class);
113 clearPrincipals(GrantedAuthorityPrincipal.class);
114
115 // we resync with Spring Security since the subject may have been reused
116 // in beetween
117 // TODO: check if this is clean
118 // subject.getPrincipals().addAll(syncPrincipals());
119
120 return true;
121 }
122
123 private <T extends Principal> void clearPrincipals(Class<T> clss) {
124 Set<T> principals = subject.getPrincipals(clss);
125 if (principals != null)
126 principals.clear();
127 }
128
129 @SuppressWarnings("rawtypes")
130 @Override
131 protected void doInit(CallbackHandler callbackHandler, Session session,
132 Map options) throws LoginException {
133 }
134
135 @Override
136 protected boolean impersonate(Principal principal, Credentials credentials)
137 throws RepositoryException, LoginException {
138 throw new UnsupportedOperationException(
139 "Impersonation is not yet supported");
140 }
141
142 @Override
143 protected Authentication getAuthentication(final Principal principal,
144 Credentials creds) throws RepositoryException {
145 if (principal instanceof Group) {
146 return null;
147 }
148 return new Authentication() {
149 public boolean canHandle(Credentials credentials) {
150 return principal instanceof org.springframework.security.Authentication;
151 }
152
153 public boolean authenticate(Credentials credentials)
154 throws RepositoryException {
155 return ((org.springframework.security.Authentication) principal)
156 .isAuthenticated();
157 }
158 };
159 }
160
161 }