1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package org.efaps.jaas.xml;
22
23 import java.io.File;
24 import java.io.IOException;
25 import java.util.ArrayList;
26 import java.util.HashMap;
27 import java.util.List;
28 import java.util.Map;
29
30 import javax.security.auth.Subject;
31 import javax.security.auth.callback.Callback;
32 import javax.security.auth.callback.CallbackHandler;
33 import javax.security.auth.callback.NameCallback;
34 import javax.security.auth.callback.PasswordCallback;
35 import javax.security.auth.callback.UnsupportedCallbackException;
36 import javax.security.auth.login.FailedLoginException;
37 import javax.security.auth.login.LoginException;
38 import javax.security.auth.spi.LoginModule;
39
40 import org.apache.commons.digester.Digester;
41 import org.efaps.jaas.ActionCallback;
42 import org.slf4j.Logger;
43 import org.slf4j.LoggerFactory;
44 import org.xml.sax.SAXException;
45
46
47
48
49
50
51 public class XMLUserLoginModule
52 implements LoginModule
53 {
54
55
56
57 private static final Logger LOG = LoggerFactory.getLogger(XMLUserLoginModule.class);
58
59
60
61
62 private ActionCallback.Mode mode = ActionCallback.Mode.UNDEFINED;
63
64
65
66
67
68 private Subject subject = null;
69
70
71
72
73 private CallbackHandler callbackHandler = null;
74
75
76
77
78
79
80 private XMLPersonPrincipal person = null;
81
82
83
84
85 private final Map<String, XMLPersonPrincipal> allPersons = new HashMap<String, XMLPersonPrincipal>();
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109 @Override
110 public final void initialize(final Subject _subject,
111 final CallbackHandler _callbackHandler,
112 final Map < String, ? > _sharedState,
113 final Map < String, ? > _options)
114 {
115 XMLUserLoginModule.LOG.debug("Init");
116 this.subject = _subject;
117 this.callbackHandler = _callbackHandler;
118 readPersons((String) _options.get("xmlFileName"));
119 }
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138 public final boolean login()
139 throws LoginException
140 {
141 boolean ret = false;
142
143 final Callback[] callbacks = new Callback[3];
144 callbacks[0] = new ActionCallback();
145 callbacks[1] = new NameCallback("Username: ");
146 callbacks[2] = new PasswordCallback("Password: ", false);
147
148 String userName = null;
149 String password = null;
150 try {
151 this.callbackHandler.handle(callbacks);
152 this.mode = ((ActionCallback) callbacks[0]).getMode();
153 userName = ((NameCallback) callbacks[1]).getName();
154 if (((PasswordCallback) callbacks[2]).getPassword() != null) {
155 password = new String(((PasswordCallback) callbacks[2]).getPassword());
156 }
157 } catch (final IOException e) {
158 throw new LoginException(e.toString());
159 } catch (final UnsupportedCallbackException e) {
160 throw new LoginException(e.toString());
161 }
162
163 if (this.mode == ActionCallback.Mode.ALL_PERSONS) {
164 ret = true;
165 } else if (this.mode == ActionCallback.Mode.PERSON_INFORMATION) {
166 this.person = this.allPersons.get(userName);
167 if (this.person != null) {
168 if (XMLUserLoginModule.LOG.isDebugEnabled()) {
169 XMLUserLoginModule.LOG.debug("found '" + this.person + "'");
170 }
171 ret = true;
172 }
173 } else {
174 this.person = this.allPersons.get(userName);
175 if (this.person != null) {
176 if ((password == null)
177 || ((password != null)
178 && !password.equals(this.person.getPassword()))) {
179
180 XMLUserLoginModule.LOG.error("person '" + this.person + "' tried to log in with wrong password");
181 this.person = null;
182 throw new FailedLoginException("Username or password is incorrect");
183 }
184 if (XMLUserLoginModule.LOG.isDebugEnabled()) {
185 XMLUserLoginModule.LOG.debug("log in of '" + this.person + "'");
186 }
187 this.mode = ActionCallback.Mode.LOGIN;
188 ret = true;
189 }
190 }
191
192 return ret;
193 }
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218 public final boolean commit()
219 throws LoginException
220 {
221 boolean ret = false;
222
223 if (this.mode == ActionCallback.Mode.ALL_PERSONS) {
224 for (final XMLPersonPrincipal personTmp : this.allPersons.values()) {
225 if (!this.subject.getPrincipals().contains(personTmp)) {
226 if (XMLUserLoginModule.LOG.isDebugEnabled()) {
227 XMLUserLoginModule.LOG.debug("commit person '" + personTmp + "'");
228 }
229 this.subject.getPrincipals().add(personTmp);
230 }
231 }
232 ret = true;
233 } else if (this.person != null) {
234 if (XMLUserLoginModule.LOG.isDebugEnabled()) {
235 XMLUserLoginModule.LOG.debug("commit of '" + this.person + "'");
236 }
237 if (!this.subject.getPrincipals().contains(this.person)) {
238 this.subject.getPrincipals().add(this.person);
239 for (final XMLRolePrincipal principal : this.person.getRoles()) {
240 this.subject.getPrincipals().add(principal);
241 }
242 for (final XMLGroupPrincipal principal : this.person.getGroups()) {
243 this.subject.getPrincipals().add(principal);
244 }
245 }
246 ret = true;
247 }
248
249 return ret;
250 }
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272 public final boolean abort()
273 throws LoginException
274 {
275 boolean ret = false;
276
277 if (this.person != null) {
278 if (XMLUserLoginModule.LOG.isDebugEnabled()) {
279 XMLUserLoginModule.LOG.debug("abort of " + this.person);
280 }
281 this.subject.getPrincipals().remove(this.person);
282 for (final XMLRolePrincipal principal : this.person.getRoles()) {
283 this.subject.getPrincipals().remove(principal);
284 }
285 for (final XMLGroupPrincipal principal : this.person.getGroups()) {
286 this.subject.getPrincipals().remove(principal);
287 }
288 this.person = null;
289 ret = true;
290 }
291 return ret;
292 }
293
294
295
296
297
298
299
300
301 public final boolean logout()
302 {
303 boolean ret = false;
304
305 if (this.person != null) {
306 if (XMLUserLoginModule.LOG.isDebugEnabled()) {
307 XMLUserLoginModule.LOG.debug("logout of " + this.person);
308 }
309 this.subject.getPrincipals().remove(this.person);
310 for (final XMLRolePrincipal principal : this.person.getRoles()) {
311 this.subject.getPrincipals().remove(principal);
312 }
313 for (final XMLGroupPrincipal principal : this.person.getGroups()) {
314 this.subject.getPrincipals().remove(principal);
315 }
316 this.person = null;
317 ret = true;
318 }
319 return ret;
320 }
321
322
323
324
325
326
327
328 @SuppressWarnings("unchecked")
329 private void readPersons(final String _fileName)
330 {
331 try {
332 final File file = new File(_fileName);
333
334 final Digester digester = new Digester();
335 digester.setValidating(false);
336 digester.addObjectCreate("persons", ArrayList.class);
337 digester.addObjectCreate("persons/person", XMLPersonPrincipal.class);
338 digester.addSetNext("persons/person", "add");
339
340 digester.addCallMethod("persons/person/name", "setName", 1);
341 digester.addCallParam("persons/person/name", 0);
342
343 digester.addCallMethod("persons/person/password", "setPassword", 1);
344 digester.addCallParam("persons/person/password", 0);
345
346 digester.addCallMethod("persons/person/firstName", "setFirstName", 1);
347 digester.addCallParam("persons/person/firstName", 0);
348
349 digester.addCallMethod("persons/person/lastName", "setLastName", 1);
350 digester.addCallParam("persons/person/lastName", 0);
351
352 digester.addCallMethod("persons/person/email", "setEmail", 1);
353 digester.addCallParam("persons/person/email", 0);
354
355 digester.addCallMethod("persons/person/organisation", "setOrganisation", 1);
356 digester.addCallParam("persons/person/organisation", 0);
357
358 digester.addCallMethod("persons/person/url", "setUrl", 1);
359 digester.addCallParam("persons/person/url", 0);
360
361 digester.addCallMethod("persons/person/phone", "setPhone", 1);
362 digester.addCallParam("persons/person/phone", 0);
363
364 digester.addCallMethod("persons/person/mobile", "setMobile", 1);
365 digester.addCallParam("persons/person/mobile", 0);
366
367 digester.addCallMethod("persons/person/fax", "setFax", 1);
368 digester.addCallParam("persons/person/fax", 0);
369
370 digester.addCallMethod("persons/person/role", "addRole", 1);
371 digester.addCallParam("persons/person/role", 0);
372
373 digester.addCallMethod("persons/person/group", "addGroup", 1);
374 digester.addCallParam("persons/person/group", 0);
375
376 final List<XMLPersonPrincipal> personList = (List<XMLPersonPrincipal>) digester.parse(file);
377 for (final XMLPersonPrincipal personTmp : personList) {
378 this.allPersons.put(personTmp.getName(), personTmp);
379 }
380 } catch (final IOException e) {
381 XMLUserLoginModule.LOG.error("could not open file '" + _fileName + "'", e);
382 } catch (final SAXException e) {
383 XMLUserLoginModule.LOG.error("could not read file '" + _fileName + "'", e);
384 }
385 }
386 }