]> git.argeo.org Git - lgpl/argeo-commons.git/blob - org.argeo.cms/src/org/argeo/cms/auth/NodeUserLoginModule.java
Disable request for basic auth
[lgpl/argeo-commons.git] / org.argeo.cms / src / org / argeo / cms / auth / NodeUserLoginModule.java
1 package org.argeo.cms.auth;
2
3 import java.security.Principal;
4 import java.util.Arrays;
5 import java.util.Collections;
6 import java.util.Iterator;
7 import java.util.List;
8 import java.util.Map;
9 import java.util.Set;
10
11 import javax.naming.InvalidNameException;
12 import javax.naming.ldap.LdapName;
13 import javax.security.auth.Subject;
14 import javax.security.auth.callback.CallbackHandler;
15 import javax.security.auth.login.LoginException;
16 import javax.security.auth.spi.LoginModule;
17 import javax.security.auth.x500.X500Principal;
18
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.osgi.service.useradmin.Authorization;
25
26 public class NodeUserLoginModule implements LoginModule {
27 private Subject subject;
28
29 private final static LdapName ROLE_KERNEL_NAME, ROLE_ADMIN_NAME,
30 ROLE_ANONYMOUS_NAME, ROLE_USER_NAME;
31 private final static List<LdapName> RESERVED_ROLES;
32 private final static X500Principal ROLE_ANONYMOUS_PRINCIPAL;
33 static {
34 try {
35 ROLE_KERNEL_NAME = new LdapName(AuthConstants.ROLE_KERNEL);
36 ROLE_ADMIN_NAME = new LdapName(AuthConstants.ROLE_ADMIN);
37 ROLE_USER_NAME = new LdapName(AuthConstants.ROLE_USER);
38 ROLE_ANONYMOUS_NAME = new LdapName(AuthConstants.ROLE_ANONYMOUS);
39 RESERVED_ROLES = Collections.unmodifiableList(Arrays
40 .asList(new LdapName[] { ROLE_KERNEL_NAME, ROLE_ADMIN_NAME,
41 ROLE_ANONYMOUS_NAME, ROLE_USER_NAME,
42 new LdapName(AuthConstants.ROLE_GROUP_ADMIN),
43 new LdapName(AuthConstants.ROLE_USER_ADMIN) }));
44 ROLE_ANONYMOUS_PRINCIPAL = new X500Principal(
45 ROLE_ANONYMOUS_NAME.toString());
46 } catch (InvalidNameException e) {
47 throw new Error("Cannot initialize login module class", e);
48 }
49 }
50
51 private Authorization authorization;
52
53 @Override
54 public void initialize(Subject subject, CallbackHandler callbackHandler,
55 Map<String, ?> sharedState, Map<String, ?> options) {
56 this.subject = subject;
57 }
58
59 @Override
60 public boolean login() throws LoginException {
61 Iterator<Authorization> auth = subject.getPrivateCredentials(
62 Authorization.class).iterator();
63 if (!auth.hasNext())
64 return false;
65 authorization = auth.next();
66 return true;
67 }
68
69 @Override
70 public boolean commit() throws LoginException {
71 if (authorization == null)
72 throw new LoginException("Authorization should not be null");
73 Set<Principal> principals = subject.getPrincipals();
74 try {
75 String authName = authorization.getName();
76
77 // determine user's principal
78 final LdapName name;
79 final Principal userPrincipal;
80 if (authName == null) {
81 name = ROLE_ANONYMOUS_NAME;
82 userPrincipal = ROLE_ANONYMOUS_PRINCIPAL;
83 principals.add(userPrincipal);
84 principals.add(new AnonymousPrincipal());
85 } else {
86 name = new LdapName(authName);
87 checkUserName(name);
88 userPrincipal = new X500Principal(name.toString());
89 principals.add(userPrincipal);
90 principals.add(new ImpliedByPrincipal(ROLE_USER_NAME,
91 userPrincipal));
92 }
93
94 // Add roles provided by authorization
95 for (String role : authorization.getRoles()) {
96 LdapName roleName = new LdapName(role);
97 if (roleName.equals(name)) {
98 // skip
99 } else {
100 checkImpliedPrincipalName(roleName);
101 principals.add(new ImpliedByPrincipal(roleName.toString(),
102 userPrincipal));
103 if (roleName.equals(ROLE_ADMIN_NAME))
104 principals.add(new AdminPrincipal(
105 SecurityConstants.ADMIN_ID));
106 }
107 }
108
109 return true;
110 } catch (InvalidNameException e) {
111 throw new CmsException("Cannot commit", e);
112 }
113 }
114
115 @Override
116 public boolean abort() throws LoginException {
117 cleanUp();
118 return true;
119 }
120
121 @Override
122 public boolean logout() throws LoginException {
123 if (subject == null)
124 throw new LoginException("Subject should not be null");
125 // Argeo
126 subject.getPrincipals().removeAll(
127 subject.getPrincipals(X500Principal.class));
128 subject.getPrincipals().removeAll(
129 subject.getPrincipals(ImpliedByPrincipal.class));
130 // Jackrabbit
131 subject.getPrincipals().removeAll(
132 subject.getPrincipals(AdminPrincipal.class));
133 subject.getPrincipals().removeAll(
134 subject.getPrincipals(AnonymousPrincipal.class));
135 cleanUp();
136 return true;
137 }
138
139 private void cleanUp() {
140 subject = null;
141 authorization = null;
142 }
143
144 private void checkUserName(LdapName name) {
145 if (RESERVED_ROLES.contains(name))
146 throw new CmsException(name + " is a reserved name");
147 }
148
149 private void checkImpliedPrincipalName(LdapName roleName) {
150 if (ROLE_USER_NAME.equals(roleName)
151 || ROLE_ANONYMOUS_NAME.equals(roleName)
152 || ROLE_KERNEL_NAME.equals(roleName))
153 throw new CmsException(roleName + " cannot be listed as role");
154 }
155 }