1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package no.feide.moria.webservices.v2_3;
22
23 import java.util.ArrayList;
24 import java.util.Iterator;
25 import java.util.List;
26 import java.util.Map;
27 import java.util.Properties;
28 import java.util.Set;
29
30 import no.feide.moria.controller.AuthenticationException;
31 import no.feide.moria.controller.AuthorizationException;
32 import no.feide.moria.controller.DirectoryUnavailableException;
33 import no.feide.moria.controller.InoperableStateException;
34 import no.feide.moria.controller.MoriaController;
35 import no.feide.moria.log.MessageLogger;
36 import no.feide.moria.servlet.RequestUtil;
37 import no.feide.moria.servlet.soap.AuthenticationFailedException;
38 import no.feide.moria.servlet.soap.AuthenticationUnavailableException;
39 import no.feide.moria.servlet.soap.AuthorizationFailedException;
40 import no.feide.moria.servlet.soap.IllegalInputException;
41 import no.feide.moria.servlet.soap.InternalException;
42 import no.feide.moria.servlet.soap.UnknownTicketException;
43
44 import org.apache.axis.MessageContext;
45 import org.apache.axis.session.Session;
46 import org.apache.axis.transport.http.AxisHttpSession;
47 import org.apache.log4j.Level;
48
49 /***
50 *
51 */
52 public final class AuthenticationImpl
53 implements Authentication {
54
55 /*** Class wide logger. */
56 private MessageLogger messageLogger;
57
58 /*** Log message for AuthorizationExceptions. */
59 private static final String AUTHZ_EX_MESSAGE = "Authorization failed. Throwing RemoteException to service: ";
60
61 /*** Log message for AuthenticationExceptions. */
62 private static final String AUTHN_EX_MSG = "Authentication failed. Throwing RemoteException to service: ";
63
64 /*** Log message for DirectoryUnavailableExceptions. */
65 private static final String DIR_UNAV_EX_MSG = "Directory unavailable. Throwing RemoteException to service: ";
66
67 /*** Log message for MoriaControllerExceptions. */
68 private static final String MORIACTRL_EX_MESSAGE = "Exception from MoriaController. Throwing RemoteException to service: ";
69
70 /*** Log message for InoperableStateExceptions. */
71 private static final String INOP_STATE_EX_MSG = "Controller in inoperable state. Throwing RemoteException to service: ";
72
73 /*** Log message for UnknownTicketExceptions. */
74 private static final String UNKNOWN_TICKET_EX_MSG = "Ticket is unknown. Throwing RemoteException to service: ";
75
76
77 /***
78 * Default constructor. Initializes the message logger.
79 */
80 public AuthenticationImpl() {
81
82 messageLogger = new MessageLogger(AuthenticationImpl.class);
83 }
84
85
86 /***
87 * @see no.feide.moria.webservices.v2_1.Authentication#initiateAuthentication(java.lang.String[],
88 * java.lang.String, java.lang.String, boolean)
89 */
90 public String initiateAuthentication(final String[] attributes, final String returnURLPrefix, final String returnURLPostfix, final boolean forceInteractiveAuthentication)
91 throws AuthorizationFailedException, IllegalInputException,
92 InternalException {
93
94
95 MessageContext messageContext = MessageContext.getCurrentContext();
96 String servicePrincipal = messageContext.getUsername();
97
98 String urlPrefix = null;
99 Session genericSession = messageContext.getSession();
100
101 if (genericSession instanceof AxisHttpSession) {
102 AxisHttpSession axisHttpSession = (AxisHttpSession) genericSession;
103 Properties properties = (Properties) axisHttpSession.getRep().getServletContext().getAttribute("no.feide.moria.web.config");
104 urlPrefix = (properties.getProperty(RequestUtil.PROP_LOGIN_URL_PREFIX) + "?" + properties.getProperty(RequestUtil.PROP_LOGIN_TICKET_PARAM) + "=");
105 }
106
107 try {
108
109 return urlPrefix + MoriaController.initiateAuthentication(attributes, returnURLPrefix, returnURLPostfix, forceInteractiveAuthentication, servicePrincipal);
110
111 } catch (AuthorizationException e) {
112
113
114 messageLogger.logWarn(AUTHZ_EX_MESSAGE + servicePrincipal, e);
115 throw new AuthorizationFailedException(e.getMessage());
116
117 } catch (no.feide.moria.controller.IllegalInputException e) {
118
119
120 messageLogger.logWarn(MORIACTRL_EX_MESSAGE + servicePrincipal, e);
121 throw new IllegalInputException(e.getMessage());
122
123 } catch (InoperableStateException e) {
124
125
126 messageLogger.logCritical(INOP_STATE_EX_MSG + servicePrincipal, e);
127 throw new InternalException(e.getMessage());
128
129 }
130 }
131
132
133 /***
134 * @see no.feide.moria.webservices.v2_1.Authentication#directNonInteractiveAuthentication(java.lang.String[],
135 * java.lang.String, java.lang.String)
136 */
137 public Attribute[] directNonInteractiveAuthentication(final String[] attributes, final String username, final String password)
138 throws AuthorizationFailedException, AuthenticationFailedException,
139 AuthenticationUnavailableException, IllegalInputException,
140 InternalException {
141
142
143 MessageContext messageContext = MessageContext.getCurrentContext();
144 String servicePrincipal = messageContext.getUsername();
145
146 try {
147 Map returnAttributes = MoriaController.directNonInteractiveAuthentication(attributes, username, password, servicePrincipal);
148 return mapToAttributeArray(returnAttributes, null);
149 } catch (AuthorizationException e) {
150
151
152 messageLogger.logWarn(AUTHZ_EX_MESSAGE + servicePrincipal, e);
153 throw new AuthorizationFailedException(e.getMessage());
154
155 } catch (AuthenticationException e) {
156
157
158 messageLogger.logWarn(AUTHN_EX_MSG + servicePrincipal, e);
159 throw new AuthenticationFailedException(e.getMessage());
160
161 } catch (DirectoryUnavailableException e) {
162
163
164 messageLogger.logWarn(DIR_UNAV_EX_MSG + servicePrincipal, e);
165 throw new AuthenticationUnavailableException(e.getMessage());
166
167 } catch (no.feide.moria.controller.IllegalInputException e) {
168
169
170 messageLogger.logWarn(MORIACTRL_EX_MESSAGE + servicePrincipal, e);
171 throw new IllegalInputException(e.getMessage());
172
173 } catch (InoperableStateException e) {
174
175
176 messageLogger.logCritical(INOP_STATE_EX_MSG + servicePrincipal, e);
177 throw new InternalException(e.getMessage());
178
179 }
180 }
181
182
183 /***
184 * @see no.feide.moria.webservices.v2_1.Authentication#proxyAuthentication(java.lang.String[],
185 * java.lang.String)
186 */
187 public Attribute[] proxyAuthentication(final String[] attributes, final String proxyTicket)
188 throws AuthorizationFailedException, IllegalInputException,
189 InternalException, UnknownTicketException {
190
191
192 MessageContext messageContext = MessageContext.getCurrentContext();
193 String servicePrincipal = messageContext.getUsername();
194
195 try {
196
197 Map returnAttributes = MoriaController.proxyAuthentication(attributes, proxyTicket, servicePrincipal);
198 return mapToAttributeArray(returnAttributes, proxyTicket);
199
200 } catch (AuthorizationException e) {
201
202
203 messageLogger.logWarn(AUTHZ_EX_MESSAGE + servicePrincipal, e);
204 throw new AuthorizationFailedException(e.getMessage());
205
206 } catch (no.feide.moria.controller.IllegalInputException e) {
207
208
209 messageLogger.logWarn(MORIACTRL_EX_MESSAGE + servicePrincipal, e);
210 throw new IllegalInputException(e.getMessage());
211
212 } catch (InoperableStateException e) {
213
214
215 messageLogger.logCritical(INOP_STATE_EX_MSG + servicePrincipal, e);
216 throw new InternalException(e.getMessage());
217
218 } catch (no.feide.moria.controller.UnknownTicketException e) {
219
220
221 messageLogger.logWarn(UNKNOWN_TICKET_EX_MSG + servicePrincipal, e);
222 throw new UnknownTicketException(e.getMessage());
223
224 }
225 }
226
227
228 /***
229 * @see no.feide.moria.webservices.v2_1.Authentication#getProxyTicket(java.lang.String,
230 * java.lang.String)
231 */
232 public String getProxyTicket(final String ticketGrantingTicket, final String proxyServicePrincipal)
233 throws AuthorizationFailedException, IllegalInputException,
234 InternalException, UnknownTicketException {
235
236
237 MessageContext messageContext = MessageContext.getCurrentContext();
238 String servicePrincipal = messageContext.getUsername();
239
240 try {
241
242 return MoriaController.getProxyTicket(ticketGrantingTicket, proxyServicePrincipal, servicePrincipal);
243
244 } catch (AuthorizationException e) {
245
246
247 messageLogger.logWarn(AUTHZ_EX_MESSAGE + servicePrincipal, e);
248 throw new AuthorizationFailedException(e.getMessage());
249
250 } catch (no.feide.moria.controller.IllegalInputException e) {
251
252
253 messageLogger.logWarn(MORIACTRL_EX_MESSAGE + servicePrincipal, e);
254 throw new IllegalInputException(e.getMessage());
255
256 } catch (InoperableStateException e) {
257
258
259 messageLogger.logCritical(INOP_STATE_EX_MSG + servicePrincipal, e);
260 throw new InternalException(e.getMessage());
261
262 } catch (no.feide.moria.controller.UnknownTicketException e) {
263
264
265 messageLogger.logWarn(UNKNOWN_TICKET_EX_MSG + servicePrincipal, e);
266 throw new UnknownTicketException(e.getMessage());
267
268 }
269 }
270
271
272 /***
273 * @see no.feide.moria.webservices.v2_1.Authentication#getUserAttributes(java.lang.String)
274 */
275 public Attribute[] getUserAttributes(final String serviceTicket)
276 throws AuthorizationFailedException, IllegalInputException,
277 InternalException, UnknownTicketException {
278
279
280 MessageContext messageContext = MessageContext.getCurrentContext();
281 String servicePrincipal = messageContext.getUsername();
282
283 try {
284 Map returnAttributes = MoriaController.getUserAttributes(serviceTicket, servicePrincipal);
285
286
287 if (messageLogger.isEnabledFor(Level.DEBUG)) {
288 String attributeNames = "";
289 Set keySet = returnAttributes.keySet();
290 if (keySet != null) {
291 Iterator i = keySet.iterator();
292 while (i.hasNext())
293 attributeNames = attributeNames + i.next() + ", ";
294 if (attributeNames.length() > 0)
295 attributeNames = attributeNames.substring(0, attributeNames.length() - 2);
296 }
297 messageLogger.logDebug("Returned attributes [" + attributeNames + "] to service '" + servicePrincipal + "'", serviceTicket);
298 }
299
300 return mapToAttributeArray(returnAttributes, serviceTicket);
301 } catch (no.feide.moria.controller.IllegalInputException e) {
302
303
304 messageLogger.logWarn(MORIACTRL_EX_MESSAGE + servicePrincipal, e);
305 throw new IllegalInputException(e.getMessage());
306
307 } catch (InoperableStateException e) {
308
309
310 messageLogger.logCritical(INOP_STATE_EX_MSG + servicePrincipal, e);
311 throw new InternalException(e.getMessage());
312
313 } catch (no.feide.moria.controller.UnknownTicketException e) {
314
315
316 messageLogger.logWarn(UNKNOWN_TICKET_EX_MSG + servicePrincipal, e);
317 throw new UnknownTicketException(e.getMessage());
318
319 } catch (AuthorizationException e) {
320
321
322 messageLogger.logWarn("Service not allowed for organization. Throwing RemoteException to service: ", e);
323 throw new AuthorizationFailedException(e.getMessage());
324 }
325
326 }
327
328
329 /***
330 * @see no.feide.moria.webservices.v2_1.Authentication#verifyUserExistence(java.lang.String)
331 */
332 public boolean verifyUserExistence(final String username)
333 throws AuthorizationFailedException, AuthenticationUnavailableException,
334 IllegalInputException, InternalException {
335
336
337 MessageContext messageContext = MessageContext.getCurrentContext();
338 String servicePrincipal = messageContext.getUsername();
339
340 try {
341
342 return MoriaController.verifyUserExistence(username, servicePrincipal);
343
344 } catch (AuthorizationException e) {
345
346
347 messageLogger.logWarn(AUTHZ_EX_MESSAGE + servicePrincipal, e);
348 throw new AuthorizationFailedException(e.getMessage());
349
350 } catch (DirectoryUnavailableException e) {
351
352
353 messageLogger.logWarn(DIR_UNAV_EX_MSG + servicePrincipal, e);
354 throw new AuthenticationUnavailableException(e.getMessage());
355
356 } catch (no.feide.moria.controller.IllegalInputException e) {
357
358
359 messageLogger.logWarn(MORIACTRL_EX_MESSAGE + servicePrincipal, e);
360 throw new IllegalInputException(e.getMessage());
361
362 } catch (InoperableStateException e) {
363
364
365 messageLogger.logCritical(INOP_STATE_EX_MSG + servicePrincipal, e);
366 throw new InternalException(e.getMessage());
367
368 }
369 }
370
371
372 /***
373 * Utility method to convert a <code>Map</code> to an array of
374 * <code>Attribute</code>s.
375 * @param map
376 * The <code>Map</code> to be converted.
377 * @param activeTicketId
378 * Optional variable for logging purposes.
379 * @return Array of <code>Attribute</code> objects.
380 */
381 private Attribute[] mapToAttributeArray(final Map map, final String activeTicketId) {
382
383
384 Iterator iterator = map.keySet().iterator();
385
386
387 List attributeList = new ArrayList();
388
389
390 while (iterator.hasNext()) {
391 Object key = iterator.next();
392 Object value = map.get(key);
393
394 Attribute attribute = new Attribute();
395
396
397 if (key instanceof String) {
398
399 attribute.setName((String) key);
400
401
402
403
404
405
406 if (value instanceof String) {
407
408 attribute.setValues(new String[] {(String) value});
409 attributeList.add(attribute);
410 } else if (value instanceof String[]) {
411 attribute.setValues((String[]) value);
412 attributeList.add(attribute);
413 } else if (value != null) {
414 messageLogger.logInfo("Attribute value not String or String[]. Entry not added to Attribute[]. ", activeTicketId);
415 }
416 } else if (value != null) {
417 messageLogger.logInfo("Attribute key not String. Entry not added to Attribute[]", activeTicketId);
418 }
419 }
420 return (Attribute[]) attributeList.toArray(new Attribute[] {});
421 }
422 }