1 package org
.argeo
.cms
.auth
;
3 import java
.security
.Principal
;
4 import java
.util
.Arrays
;
5 import java
.util
.Collections
;
10 import javax
.naming
.InvalidNameException
;
11 import javax
.naming
.ldap
.LdapName
;
12 import javax
.security
.auth
.Subject
;
13 import javax
.security
.auth
.callback
.CallbackHandler
;
14 import javax
.security
.auth
.login
.FailedLoginException
;
15 import javax
.security
.auth
.login
.LoginException
;
16 import javax
.security
.auth
.spi
.LoginModule
;
17 import javax
.security
.auth
.x500
.X500Principal
;
19 import org
.apache
.jackrabbit
.core
.security
.AnonymousPrincipal
;
20 import org
.apache
.jackrabbit
.core
.security
.SecurityConstants
;
21 import org
.apache
.jackrabbit
.core
.security
.principal
.AdminPrincipal
;
22 import org
.argeo
.cms
.CmsException
;
23 import org
.argeo
.cms
.internal
.auth
.ImpliedByPrincipal
;
24 import org
.argeo
.node
.NodeConstants
;
25 import org
.osgi
.service
.useradmin
.Authorization
;
27 public class NodeUserLoginModule
implements LoginModule
, AuthConstants
{
28 private Subject subject
;
29 private Map
<String
, Object
> sharedState
= null;
31 private final static LdapName ROLE_ADMIN_NAME
, ROLE_ANONYMOUS_NAME
, ROLE_USER_NAME
;
32 private final static List
<LdapName
> RESERVED_ROLES
;
33 private final static X500Principal ROLE_ANONYMOUS_PRINCIPAL
;
36 // ROLE_KERNEL_NAME = new LdapName(AuthConstants.ROLE_KERNEL);
37 ROLE_ADMIN_NAME
= new LdapName(NodeConstants
.ROLE_ADMIN
);
38 ROLE_USER_NAME
= new LdapName(NodeConstants
.ROLE_USER
);
39 ROLE_ANONYMOUS_NAME
= new LdapName(NodeConstants
.ROLE_ANONYMOUS
);
40 RESERVED_ROLES
= Collections
.unmodifiableList(Arrays
.asList(new LdapName
[] { ROLE_ADMIN_NAME
,
41 ROLE_ANONYMOUS_NAME
, ROLE_USER_NAME
, new LdapName(AuthConstants
.ROLE_GROUP_ADMIN
),
42 new LdapName(NodeConstants
.ROLE_USER_ADMIN
) }));
43 ROLE_ANONYMOUS_PRINCIPAL
= new X500Principal(ROLE_ANONYMOUS_NAME
.toString());
44 } catch (InvalidNameException e
) {
45 throw new Error("Cannot initialize login module class", e
);
49 private Authorization authorization
;
51 @SuppressWarnings("unchecked")
53 public void initialize(Subject subject
, CallbackHandler callbackHandler
, Map
<String
, ?
> sharedState
,
54 Map
<String
, ?
> options
) {
55 this.subject
= subject
;
56 this.sharedState
= (Map
<String
, Object
>) sharedState
;
60 public boolean login() throws LoginException
{
61 authorization
= (Authorization
) sharedState
.get(SHARED_STATE_AUTHORIZATION
);
62 if (authorization
== null)
63 throw new FailedLoginException("No authorization available");
64 // Iterator<Authorization> auth = subject.getPrivateCredentials(
65 // Authorization.class).iterator();
66 // if (!auth.hasNext())
67 // throw new FailedLoginException("No authorization available");
68 // authorization = auth.next();
73 public boolean commit() throws LoginException
{
74 if (authorization
== null)
75 throw new LoginException("Authorization should not be null");
76 // required for display name:
77 subject
.getPrivateCredentials().add(authorization
);
79 Set
<Principal
> principals
= subject
.getPrincipals();
81 String authName
= authorization
.getName();
83 // determine user's principal
85 final Principal userPrincipal
;
86 if (authName
== null) {
87 name
= ROLE_ANONYMOUS_NAME
;
88 userPrincipal
= ROLE_ANONYMOUS_PRINCIPAL
;
89 principals
.add(userPrincipal
);
90 principals
.add(new AnonymousPrincipal());
92 name
= new LdapName(authName
);
94 userPrincipal
= new X500Principal(name
.toString());
95 principals
.add(userPrincipal
);
96 principals
.add(new ImpliedByPrincipal(ROLE_USER_NAME
, userPrincipal
));
99 // Add roles provided by authorization
100 for (String role
: authorization
.getRoles()) {
101 LdapName roleName
= new LdapName(role
);
102 if (roleName
.equals(name
)) {
105 checkImpliedPrincipalName(roleName
);
106 principals
.add(new ImpliedByPrincipal(roleName
.toString(), userPrincipal
));
107 if (roleName
.equals(ROLE_ADMIN_NAME
))
108 principals
.add(new AdminPrincipal(SecurityConstants
.ADMIN_ID
));
113 } catch (InvalidNameException e
) {
114 throw new CmsException("Cannot commit", e
);
119 public boolean abort() throws LoginException
{
125 public boolean logout() throws LoginException
{
127 throw new LoginException("Subject should not be null");
128 // Clean up principals
130 subject
.getPrincipals().removeAll(subject
.getPrincipals(X500Principal
.class));
131 subject
.getPrincipals().removeAll(subject
.getPrincipals(ImpliedByPrincipal
.class));
133 subject
.getPrincipals().removeAll(subject
.getPrincipals(AdminPrincipal
.class));
134 subject
.getPrincipals().removeAll(subject
.getPrincipals(AnonymousPrincipal
.class));
135 // Clean up private credentials
136 subject
.getPrivateCredentials().clear();
141 private void cleanUp() {
143 authorization
= null;
146 private void checkUserName(LdapName name
) {
147 if (RESERVED_ROLES
.contains(name
))
148 throw new CmsException(name
+ " is a reserved name");
151 private void checkImpliedPrincipalName(LdapName roleName
) {
152 if (ROLE_USER_NAME
.equals(roleName
) || ROLE_ANONYMOUS_NAME
.equals(roleName
))
153 throw new CmsException(roleName
+ " cannot be listed as role");