1 package org
.argeo
.security
.jackrabbit
;
3 import java
.security
.Principal
;
4 import java
.security
.acl
.Group
;
5 import java
.util
.LinkedHashSet
;
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
;
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
;
25 /** Jackrabbit login mechanism based on Spring Security */
26 public class ArgeoLoginModule
extends AbstractLoginModule
{
27 private String adminRole
= "ROLE_ADMIN";
30 public boolean login() throws LoginException
{
31 boolean loginOk
= super.login();
33 org
.springframework
.security
.Authentication authen
= (org
.springframework
.security
.Authentication
) SecurityContextHolder
34 .getContext().getAuthentication();
40 public boolean commit() throws LoginException
{
41 boolean commitOk
= super.commit();
43 org
.springframework
.security
.Authentication authen
= (org
.springframework
.security
.Authentication
) SecurityContextHolder
44 .getContext().getAuthentication();
50 * Returns the Spring {@link org.springframework.security.Authentication}
54 protected Principal
getPrincipal(Credentials credentials
) {
55 org
.springframework
.security
.Authentication authen
= SecurityContextHolder
56 .getContext().getAuthentication();
60 protected Set
<Principal
> getPrincipals() {
61 // clear already registered Jackrabbit principals
62 // clearPrincipals(AdminPrincipal.class);
63 // clearPrincipals(AnonymousPrincipal.class);
64 // clearPrincipals(GrantedAuthorityPrincipal.class);
66 return syncPrincipals();
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
;
74 Set
<Principal
> principals
= new LinkedHashSet
<Principal
>();
75 principals
.add(authen
);
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());
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()));
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());
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.
109 public boolean logout() throws LoginException
{
110 clearPrincipals(AdminPrincipal
.class);
111 clearPrincipals(ArgeoSystemPrincipal
.class);
112 clearPrincipals(AnonymousPrincipal
.class);
113 clearPrincipals(GrantedAuthorityPrincipal
.class);
115 // we resync with Spring Security since the subject may have been reused
117 // TODO: check if this is clean
118 // subject.getPrincipals().addAll(syncPrincipals());
123 private <T
extends Principal
> void clearPrincipals(Class
<T
> clss
) {
124 Set
<T
> principals
= subject
.getPrincipals(clss
);
125 if (principals
!= null)
129 @SuppressWarnings("rawtypes")
131 protected void doInit(CallbackHandler callbackHandler
, Session session
,
132 Map options
) throws LoginException
{
136 protected boolean impersonate(Principal principal
, Credentials credentials
)
137 throws RepositoryException
, LoginException
{
138 throw new UnsupportedOperationException(
139 "Impersonation is not yet supported");
143 protected Authentication
getAuthentication(final Principal principal
,
144 Credentials creds
) throws RepositoryException
{
145 if (principal
instanceof Group
) {
148 return new Authentication() {
149 public boolean canHandle(Credentials credentials
) {
150 return principal
instanceof org
.springframework
.security
.Authentication
;
153 public boolean authenticate(Credentials credentials
)
154 throws RepositoryException
{
155 return ((org
.springframework
.security
.Authentication
) principal
)