1 /**
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19
20 package org.apache.ws.security;
21
22 import java.lang.reflect.Field;
23 import java.security.AccessController;
24 import java.security.PrivilegedAction;
25 import java.security.PrivilegedExceptionAction;
26 import java.security.Provider;
27 import java.security.Security;
28 import java.util.HashMap;
29 import java.util.Map;
30
31 import javax.xml.namespace.QName;
32
33 import org.apache.ws.security.action.Action;
34 import org.apache.ws.security.processor.Processor;
35 import org.apache.ws.security.util.Loader;
36 import org.apache.ws.security.util.UUIDGenerator;
37 import org.apache.ws.security.validate.Validator;
38 import org.apache.xml.security.utils.XMLUtils;
39
40 /**
41 * WSSConfig <p/> Carries configuration data so the WSS4J spec compliance can be
42 * modified in runtime. Configure an instance of this object only if you need
43 * WSS4J to emulate certain industry clients or previous OASIS specifications
44 * for WS-Security interoperability testing purposes. <p/> The default settings
45 * follow the latest OASIS and changing anything might violate the OASIS specs.
46 * <p/> <b>WARNING: changing the default settings will break the compliance with
47 * the latest specs. Do this only if you know what you are doing.</b> <p/>
48 *
49 * @author Rami Jaamour (rjaamour@parasoft.com)
50 * @author Werner Dittmann (werner@apache.org)
51 */
52 public class WSSConfig {
53
54 private static final org.apache.commons.logging.Log LOG =
55 org.apache.commons.logging.LogFactory.getLog(WSSConfig.class);
56
57 /**
58 * The default collection of actions supported by the toolkit.
59 */
60 private static final Map<Integer, Class<?>> DEFAULT_ACTIONS;
61 static {
62 final Map<Integer, Class<?>> tmp = new HashMap<Integer, Class<?>>();
63 try {
64 tmp.put(
65 Integer.valueOf(WSConstants.UT),
66 org.apache.ws.security.action.UsernameTokenAction.class
67 );
68 tmp.put(
69 Integer.valueOf(WSConstants.ENCR),
70 org.apache.ws.security.action.EncryptionAction.class
71 );
72 tmp.put(
73 Integer.valueOf(WSConstants.SIGN),
74 org.apache.ws.security.action.SignatureAction.class
75 );
76 tmp.put(
77 Integer.valueOf(WSConstants.ST_SIGNED),
78 org.apache.ws.security.action.SAMLTokenSignedAction.class
79 );
80 tmp.put(
81 Integer.valueOf(WSConstants.ST_UNSIGNED),
82 org.apache.ws.security.action.SAMLTokenUnsignedAction.class
83 );
84 tmp.put(
85 Integer.valueOf(WSConstants.TS),
86 org.apache.ws.security.action.TimestampAction.class
87 );
88 tmp.put(
89 Integer.valueOf(WSConstants.UT_SIGN),
90 org.apache.ws.security.action.UsernameTokenSignedAction.class
91 );
92 tmp.put(
93 Integer.valueOf(WSConstants.SC),
94 org.apache.ws.security.action.SignatureConfirmationAction.class
95 );
96 } catch (final Exception ex) {
97 if (LOG.isDebugEnabled()) {
98 LOG.debug(ex.getMessage(), ex);
99 }
100 }
101 DEFAULT_ACTIONS = java.util.Collections.unmodifiableMap(tmp);
102 }
103
104 /**
105 * The default collection of processors supported by the toolkit
106 */
107 private static final Map<QName, Class<?>> DEFAULT_PROCESSORS;
108 static {
109 final Map<QName, Class<?>> tmp = new HashMap<QName, Class<?>>();
110 try {
111 tmp.put(
112 WSSecurityEngine.SAML_TOKEN,
113 org.apache.ws.security.processor.SAMLTokenProcessor.class
114 );
115 tmp.put(
116 WSSecurityEngine.SAML2_TOKEN,
117 org.apache.ws.security.processor.SAMLTokenProcessor.class
118 );
119 tmp.put(
120 WSSecurityEngine.ENCRYPTED_KEY,
121 org.apache.ws.security.processor.EncryptedKeyProcessor.class
122 );
123 tmp.put(
124 WSSecurityEngine.SIGNATURE,
125 org.apache.ws.security.processor.SignatureProcessor.class
126 );
127 tmp.put(
128 WSSecurityEngine.TIMESTAMP,
129 org.apache.ws.security.processor.TimestampProcessor.class
130 );
131 tmp.put(
132 WSSecurityEngine.USERNAME_TOKEN,
133 org.apache.ws.security.processor.UsernameTokenProcessor.class
134 );
135 tmp.put(
136 WSSecurityEngine.REFERENCE_LIST,
137 org.apache.ws.security.processor.ReferenceListProcessor.class
138 );
139 tmp.put(
140 WSSecurityEngine.SIGNATURE_CONFIRMATION,
141 org.apache.ws.security.processor.SignatureConfirmationProcessor.class
142 );
143 tmp.put(
144 WSSecurityEngine.DERIVED_KEY_TOKEN_05_02,
145 org.apache.ws.security.processor.DerivedKeyTokenProcessor.class
146 );
147 tmp.put(
148 WSSecurityEngine.DERIVED_KEY_TOKEN_05_12,
149 tmp.get(WSSecurityEngine.DERIVED_KEY_TOKEN_05_02)
150 );
151 tmp.put(
152 WSSecurityEngine.SECURITY_CONTEXT_TOKEN_05_02,
153 org.apache.ws.security.processor.SecurityContextTokenProcessor.class
154 );
155 tmp.put(
156 WSSecurityEngine.SECURITY_CONTEXT_TOKEN_05_12,
157 tmp.get(WSSecurityEngine.SECURITY_CONTEXT_TOKEN_05_02)
158 );
159 tmp.put(
160 WSSecurityEngine.BINARY_TOKEN,
161 org.apache.ws.security.processor.BinarySecurityTokenProcessor.class
162 );
163 tmp.put(
164 WSSecurityEngine.ENCRYPTED_DATA,
165 org.apache.ws.security.processor.EncryptedDataProcessor.class
166 );
167 } catch (final Exception ex) {
168 if (LOG.isDebugEnabled()) {
169 LOG.debug(ex.getMessage(), ex);
170 }
171 }
172 DEFAULT_PROCESSORS = java.util.Collections.unmodifiableMap(tmp);
173 }
174
175 /**
176 * The default collection of validators supported by the toolkit
177 */
178 private static final Map<QName, Class<?>> DEFAULT_VALIDATORS;
179 static {
180 final Map<QName, Class<?>> tmp = new HashMap<QName, Class<?>>();
181 try {
182 tmp.put(
183 WSSecurityEngine.SAML_TOKEN,
184 org.apache.ws.security.validate.SamlAssertionValidator.class
185 );
186 tmp.put(
187 WSSecurityEngine.SAML2_TOKEN,
188 org.apache.ws.security.validate.SamlAssertionValidator.class
189 );
190 tmp.put(
191 WSSecurityEngine.SIGNATURE,
192 org.apache.ws.security.validate.SignatureTrustValidator.class
193 );
194 tmp.put(
195 WSSecurityEngine.TIMESTAMP,
196 org.apache.ws.security.validate.TimestampValidator.class
197 );
198 tmp.put(
199 WSSecurityEngine.USERNAME_TOKEN,
200 org.apache.ws.security.validate.UsernameTokenValidator.class
201 );
202 } catch (final Exception ex) {
203 if (LOG.isDebugEnabled()) {
204 LOG.debug(ex.getMessage(), ex);
205 }
206 }
207 DEFAULT_VALIDATORS = java.util.Collections.unmodifiableMap(tmp);
208 }
209
210 protected boolean wsiBSPCompliant = true;
211
212 /**
213 * Set the timestamp precision mode. If set to <code>true</code> then use
214 * timestamps with milliseconds, otherwise omit the milliseconds. As per XML
215 * Date/Time specification the default is to include the milliseconds.
216 */
217 protected boolean precisionInMilliSeconds = true;
218
219 protected boolean enableSignatureConfirmation = false;
220
221 /**
222 * If set to true then the timestamp handling will throw an exception if the
223 * timestamp contains an expires element and the semantics are expired.
224 *
225 * If set to false, no exception will be thrown, even if the semantics are
226 * expired.
227 */
228 protected boolean timeStampStrict = true;
229
230 /**
231 * If this value is not null, then username token handling will throw an
232 * exception if the password type of the Username Token does not match this value
233 */
234 protected String requiredPasswordType = null;
235
236 /**
237 * This variable controls whether a UsernameToken with no password element is allowed.
238 * The default value is "false". Set it to "true" to allow deriving keys from UsernameTokens
239 * or to support UsernameTokens for purposes other than authentication.
240 */
241 protected boolean allowUsernameTokenNoPassword = false;
242
243 /**
244 * The time in seconds between creation and expiry for a Timestamp. The default
245 * is 300 seconds (5 minutes).
246 */
247 protected int timeStampTTL = 300;
248
249 /**
250 * The time in seconds in the future within which the Created time of an incoming
251 * Timestamp is valid. The default is 60 seconds.
252 */
253 protected int timeStampFutureTTL = 60;
254
255 /**
256 * The time in seconds between creation and expiry for a UsernameToken Created
257 * element. The default is 300 seconds (5 minutes).
258 */
259 protected int utTTL = 300;
260
261 /**
262 * The time in seconds in the future within which the Created time of an incoming
263 * UsernameToken is valid. The default is 60 seconds.
264 */
265 protected int utFutureTTL = 60;
266
267 /**
268 * This variable controls whether types other than PasswordDigest or PasswordText
269 * are allowed when processing UsernameTokens.
270 *
271 * By default this is set to false so that the user doesn't have to explicitly
272 * reject custom token types in the callback handler.
273 */
274 protected boolean handleCustomPasswordTypes = false;
275
276 /**
277 * This variable controls whether (wsse) namespace qualified password types are
278 * accepted when processing UsernameTokens.
279 *
280 * By default this is set to false.
281 */
282 protected boolean allowNamespaceQualifiedPasswordTypes = false;
283
284 /**
285 * The secret key length to be used for UT_SIGN.
286 */
287 protected int secretKeyLength = WSConstants.WSE_DERIVED_KEY_LEN;
288
289 /**
290 * Whether the password should be treated as a binary value. This
291 * is needed to properly handle password equivalence for UsernameToken
292 * passwords. Binary passwords are Base64 encoded so they can be
293 * treated as strings in most places, but when the password digest
294 * is calculated or a key is derived from the password, the password
295 * will be Base64 decoded before being used. This is most useful for
296 * hashed passwords as password equivalents.
297 *
298 * See https://issues.apache.org/jira/browse/WSS-239
299 */
300 protected boolean passwordsAreEncoded = false;
301
302 /**
303 * The default wsu:Id allocator is a simple "start at 1 and increment up"
304 * thing that is very fast.
305 */
306 public static final WsuIdAllocator DEFAULT_ID_ALLOCATOR = new WsuIdAllocator() {
307 int i;
308 private synchronized String next() {
309 return Integer.toString(++i);
310 }
311 public String createId(String prefix, Object o) {
312 if (prefix == null) {
313 return "_" + next();
314 }
315 return prefix + next();
316 }
317
318 public String createSecureId(String prefix, Object o) {
319 if (prefix == null) {
320 return UUIDGenerator.getUUID();
321 }
322 return prefix + UUIDGenerator.getUUID();
323 }
324 };
325 protected WsuIdAllocator idAllocator = DEFAULT_ID_ALLOCATOR;
326
327 /**
328 * The known actions. This map is of the form <Integer, Class<?>> or
329 * <Integer, Action>.
330 * The known actions are initialized from a set of defaults,
331 * but the list may be modified via the setAction operations.
332 */
333 private final Map<Integer, Object> actionMap =
334 new HashMap<Integer, Object>(DEFAULT_ACTIONS);
335
336 /**
337 * The known processors. This map is of the form <QName, Class<?>> or
338 * <QName, Processor>.
339 * The known processors are initialized from a set of defaults,
340 * but the list may be modified via the setProcessor operations.
341 */
342 private final Map<QName, Object> processorMap =
343 new HashMap<QName, Object>(DEFAULT_PROCESSORS);
344
345 /**
346 * The known validators. This map is of the form <QName, Class<?>> or
347 * <QName, Validator>.
348 * The known validators are initialized from a set of defaults,
349 * but the list may be modified via the setValidator operations.
350 */
351 private final Map<QName, Object> validatorMap =
352 new HashMap<QName, Object>(DEFAULT_VALIDATORS);
353
354 /**
355 * a static boolean flag that determines whether default JCE providers
356 * should be added at the time of construction.
357 *
358 * These providers, and the order in which they are added, can interfere
359 * with some JVMs (such as IBMs).
360 */
361 private static boolean addJceProviders = true;
362
363 /**
364 * a boolean flag to record whether we have already been statically
365 * initialized. This flag prevents repeated and unnecessary calls
366 * to static initialization code at construction time.
367 */
368 private static boolean staticallyInitialized = false;
369
370 /**
371 * Set the value of the internal addJceProviders flag. This flag
372 * turns on (or off) automatic registration of known JCE providers
373 * that provide necessary cryptographic algorithms for use with WSS4J.
374 * By default, this flag is true. You may wish (or need) to initialize
375 * the JCE manually, e.g., in some JVMs.
376 */
377 public static void setAddJceProviders(boolean value) {
378 addJceProviders = value;
379 }
380
381 private static void setXmlSecIgnoreLineBreak() {
382 //really need to make sure ignoreLineBreaks is set to
383 boolean wasSet = false;
384 try {
385 // Don't override if it was set explicitly
386 wasSet = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
387 public Boolean run() {
388 String lineBreakPropName = "org.apache.xml.security.ignoreLineBreaks";
389 if (System.getProperty(lineBreakPropName) == null) {
390 System.setProperty(lineBreakPropName, "true");
391 return false;
392 }
393 return true;
394 }
395 });
396 } catch (Throwable t) { //NOPMD
397 //ignore
398 }
399 org.apache.xml.security.Init.init();
400 if (!wasSet) {
401 try {
402 AccessController.doPrivileged(new PrivilegedExceptionAction<Boolean>() {
403 public Boolean run() throws Exception {
404 Field f = XMLUtils.class.getDeclaredField("ignoreLineBreaks");
405 f.setAccessible(true);
406 f.set(null, Boolean.TRUE);
407 return false;
408 }
409 });
410 } catch (Throwable t) { //NOPMD
411 //ignore
412 }
413 }
414 }
415
416 public static synchronized void init() {
417 if (!staticallyInitialized) {
418 if (addJceProviders) {
419 setXmlSecIgnoreLineBreak();
420 AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
421 public Boolean run() {
422 addXMLDSigRI();
423 addJceProvider("BC", "org.bouncycastle.jce.provider.BouncyCastleProvider");
424 Security.removeProvider("STRTransform");
425 appendJceProvider(
426 "STRTransform", new org.apache.ws.security.transform.STRTransformProvider()
427 );
428
429 return true;
430 }
431 });
432 }
433 staticallyInitialized = true;
434 }
435 }
436
437 private static void addXMLDSigRI() {
438 try {
439 addXMLDSigRIInternal();
440 } catch (Throwable t) {
441 //ignore - may be a NoClassDefFound if XMLDSigRI isn't avail
442 return;
443 }
444 }
445
446 public static void addXMLDSigRIInternal() {
447 addJceProvider("ApacheXMLDSig", SantuarioUtil.getSantuarioProvider());
448 }
449
450 /**
451 * @return a new WSSConfig instance configured with the default values
452 */
453 public static WSSConfig getNewInstance() {
454 init();
455 return new WSSConfig();
456 }
457
458 /**
459 * Checks if we are in WS-I Basic Security Profile compliance mode
460 *
461 * @return whether we are in WS-I Basic Security Profile compliance mode
462 */
463 public boolean isWsiBSPCompliant() {
464 return wsiBSPCompliant;
465 }
466
467 /**
468 * Set the WS-I Basic Security Profile compliance mode. The default is true.
469 *
470 * @param wsiBSPCompliant
471 */
472 public void setWsiBSPCompliant(boolean wsiBSPCompliant) {
473 this.wsiBSPCompliant = wsiBSPCompliant;
474 }
475
476 /**
477 * Checks if we need to use milliseconds in timestamps
478 *
479 * @return whether to use precision in milliseconds for timestamps
480 */
481 public boolean isPrecisionInMilliSeconds() {
482 return precisionInMilliSeconds;
483 }
484
485 /**
486 * Set the precision in milliseconds for timestamps
487 *
488 * @param precisionInMilliSeconds whether to use precision in milliseconds for timestamps
489 */
490 public void setPrecisionInMilliSeconds(boolean precisionInMilliSeconds) {
491 this.precisionInMilliSeconds = precisionInMilliSeconds;
492 }
493
494 /**
495 * @return Returns the enableSignatureConfirmation.
496 */
497 public boolean isEnableSignatureConfirmation() {
498 return enableSignatureConfirmation;
499 }
500
501 /**
502 * @param enableSignatureConfirmation
503 * The enableSignatureConfirmation to set.
504 */
505 public void setEnableSignatureConfirmation(boolean enableSignatureConfirmation) {
506 this.enableSignatureConfirmation = enableSignatureConfirmation;
507 }
508
509 /**
510 * @param handleCustomTypes
511 * whether to handle custom UsernameToken password types or not
512 */
513 public void setHandleCustomPasswordTypes(boolean handleCustomTypes) {
514 this.handleCustomPasswordTypes = handleCustomTypes;
515 }
516
517 /**
518 * @return whether custom UsernameToken password types are allowed or not
519 */
520 public boolean getHandleCustomPasswordTypes() {
521 return handleCustomPasswordTypes;
522 }
523
524 /**
525 * @param allowNamespaceQualifiedTypes
526 * whether (wsse) namespace qualified password types are accepted or not
527 */
528 public void setAllowNamespaceQualifiedPasswordTypes(boolean allowNamespaceQualifiedTypes) {
529 allowNamespaceQualifiedPasswordTypes = allowNamespaceQualifiedTypes;
530 }
531
532 /**
533 * @return whether (wsse) namespace qualified password types are accepted or not
534 */
535 public boolean getAllowNamespaceQualifiedPasswordTypes() {
536 return allowNamespaceQualifiedPasswordTypes;
537 }
538
539 /**
540 * @return Returns if we shall throw an exception on expired request
541 * semantic
542 */
543 public boolean isTimeStampStrict() {
544 return timeStampStrict;
545 }
546
547 /**
548 * @param timeStampStrict
549 * If true throw an exception on expired request semantic
550 */
551 public void setTimeStampStrict(boolean timeStampStrict) {
552 this.timeStampStrict = timeStampStrict;
553 }
554
555 /**
556 * @return the required password type when processing a UsernameToken
557 */
558 public String getRequiredPasswordType() {
559 return requiredPasswordType;
560 }
561
562 /**
563 * @param requiredPasswordType The required password type when processing
564 * a Username Token.
565 */
566 public void setRequiredPasswordType(String requiredPasswordType) {
567 this.requiredPasswordType = requiredPasswordType;
568 }
569
570 /**
571 * @return Returns the TTL of a Timestamp in seconds
572 */
573 public int getTimeStampTTL() {
574 return timeStampTTL;
575 }
576
577 /**
578 * @param timeStampTTL The new value for timeStampTTL
579 */
580 public void setTimeStampTTL(int timeStampTTL) {
581 this.timeStampTTL = timeStampTTL;
582 }
583
584 /**
585 * @return Returns the Future TTL of a Timestamp in seconds
586 */
587 public int getTimeStampFutureTTL() {
588 return timeStampFutureTTL;
589 }
590
591 /**
592 * @param timeStampFutureTTL the new value for timeStampFutureTTL
593 */
594 public void setTimeStampFutureTTL(int timeStampFutureTTL) {
595 this.timeStampFutureTTL = timeStampFutureTTL;
596 }
597
598 /**
599 * Set the secret key length to be used for UT_SIGN.
600 */
601 public void setSecretKeyLength(int length) {
602 secretKeyLength = length;
603 }
604
605 /**
606 * Get the secret key length to be used for UT_SIGN.
607 */
608 public int getSecretKeyLength() {
609 return secretKeyLength;
610 }
611
612 /**
613 * @param passwordsAreEncoded
614 * whether passwords are encoded
615 */
616 public void setPasswordsAreEncoded(boolean passwordsAreEncoded) {
617 this.passwordsAreEncoded = passwordsAreEncoded;
618 }
619
620 /**
621 * @return whether passwords are encoded
622 */
623 public boolean getPasswordsAreEncoded() {
624 return passwordsAreEncoded;
625 }
626
627 /**
628 * @return Returns the WsuIdAllocator used to generate wsu:Id attributes
629 */
630 public WsuIdAllocator getIdAllocator() {
631 return idAllocator;
632 }
633
634 public void setIdAllocator(WsuIdAllocator idAllocator) {
635 this.idAllocator = idAllocator;
636 }
637
638 /**
639 * Associate an action instance with a specific action code.
640 *
641 * This operation allows applications to supply their own
642 * actions for well-known operations.
643 *
644 * Please note that the Action object does NOT get class-loaded per invocation, and so
645 * it is up to the implementing class to ensure that it is thread-safe.
646 */
647 public Class<?> setAction(int code, Action action) {
648 Object result = actionMap.put(Integer.valueOf(code), action);
649 if (result instanceof Class<?>) {
650 return (Class<?>)result;
651 } else if (result instanceof Action) {
652 return result.getClass();
653 }
654 return null;
655 }
656
657 /**
658 * Associate an action instance with a specific action code.
659 *
660 * This operation allows applications to supply their own
661 * actions for well-known operations.
662 */
663 public Class<?> setAction(int code, Class<?> clazz) {
664 Object result = actionMap.put(Integer.valueOf(code), clazz);
665 if (result instanceof Class<?>) {
666 return (Class<?>)result;
667 } else if (result instanceof Action) {
668 return result.getClass();
669 }
670 return null;
671 }
672
673 /**
674 * Lookup action
675 *
676 * @param action
677 * @return An action class to create a security token
678 * @throws WSSecurityException
679 */
680 public Action getAction(int action) throws WSSecurityException {
681 final Object actionObject = actionMap.get(Integer.valueOf(action));
682
683 if (actionObject instanceof Class<?>) {
684 try {
685 return (Action)((Class<?>)actionObject).newInstance();
686 } catch (Throwable t) {
687 if (LOG.isDebugEnabled()) {
688 LOG.debug(t.getMessage(), t);
689 }
690 throw new WSSecurityException(WSSecurityException.FAILURE,
691 "unableToLoadClass", new Object[] { ((Class<?>)actionObject).getName() }, t);
692 }
693 } else if (actionObject instanceof Action) {
694 return (Action)actionObject;
695 }
696 return null;
697 }
698
699 /**
700 * Associate a SOAP processor name with a specified SOAP Security header
701 * element QName. Processors registered under this QName will be
702 * called when processing header elements with the specified type.
703 *
704 * Please note that the Processor object does NOT get class-loaded per invocation, and so
705 * it is up to the implementing class to ensure that it is thread-safe.
706 */
707 public Class<?> setProcessor(QName el, Processor processor) {
708 Object result = processorMap.put(el, processor);
709 if (result instanceof Class<?>) {
710 return (Class<?>)result;
711 } else if (result instanceof Processor) {
712 return result.getClass();
713 }
714 return null;
715 }
716
717 /**
718 * Associate a SOAP processor name with a specified SOAP Security header
719 * element QName. Processors registered under this QName will be
720 * called when processing header elements with the specified type.
721 */
722 public Class<?> setProcessor(QName el, Class<?> clazz) {
723 Object result = processorMap.put(el, clazz);
724 if (result instanceof Class<?>) {
725 return (Class<?>)result;
726 } else if (result instanceof Processor) {
727 return result.getClass();
728 }
729 return null;
730 }
731
732 /**
733 * Associate a SOAP validator name with a specified SOAP Security header
734 * element QName. Validators registered under this QName will be
735 * called when processing header elements with the specified type.
736 *
737 * Please note that the Validator object does NOT get class-loaded per invocation, and so
738 * it is up to the implementing class to ensure that it is thread-safe.
739 */
740 public Class<?> setValidator(QName el, Validator validator) {
741 Object result = validatorMap.put(el, validator);
742 if (result instanceof Class<?>) {
743 return (Class<?>)result;
744 } else if (result instanceof Validator) {
745 return result.getClass();
746 }
747 return null;
748 }
749
750 /**
751 * Associate a SOAP validator name with a specified SOAP Security header
752 * element QName. validator registered under this QName will be
753 * called when processing header elements with the specified type.
754 */
755 public Class<?> setValidator(QName el, Class<?> clazz) {
756 Object result = validatorMap.put(el, clazz);
757 if (result instanceof Class<?>) {
758 return (Class<?>)result;
759 } else if (result instanceof Validator) {
760 return result.getClass();
761 }
762 return null;
763 }
764
765 /**
766 * @return the SOAP Validator associated with the specified
767 * QName. The QName is intended to refer to an element
768 * in a SOAP security header. This operation returns
769 * null if there is no Validator associated with the
770 * specified QName.
771 */
772 public Validator getValidator(QName el) throws WSSecurityException {
773 final Object validatorObject = validatorMap.get(el);
774
775 if (validatorObject instanceof Class<?>) {
776 try {
777 return (Validator)((Class<?>)validatorObject).newInstance();
778 } catch (Throwable t) {
779 if (LOG.isDebugEnabled()) {
780 LOG.debug(t.getMessage(), t);
781 }
782 throw new WSSecurityException(WSSecurityException.FAILURE,
783 "unableToLoadClass", new Object[] { ((Class<?>)validatorObject).getName() }, t);
784 }
785 } else if (validatorObject instanceof Validator) {
786 return (Validator)validatorObject;
787 }
788 return null;
789 }
790
791 /**
792 * @return the SOAP processor associated with the specified
793 * QName. The QName is intended to refer to an element
794 * in a SOAP security header. This operation returns
795 * null if there is no processor associated with the
796 * specified QName.
797 */
798 public Processor getProcessor(QName el) throws WSSecurityException {
799 final Object processorObject = processorMap.get(el);
800
801 if (processorObject instanceof Class<?>) {
802 try {
803 return (Processor)((Class<?>)processorObject).newInstance();
804 } catch (Throwable t) {
805 if (LOG.isDebugEnabled()) {
806 LOG.debug(t.getMessage(), t);
807 }
808 throw new WSSecurityException(WSSecurityException.FAILURE,
809 "unableToLoadClass", new Object[] { ((Class<?>)processorObject).getName() }, t);
810 }
811 } else if (processorObject instanceof Processor) {
812 return (Processor)processorObject;
813 }
814 return null;
815 }
816
817 /**
818 * Add a new JCE security provider to use for WSS4J, of the specified name and class. Return
819 * either the name of the previously loaded provider, the name of the new loaded provider, or
820 * null if there's an exception in loading the provider. Add the provider either after the SUN
821 * provider (see WSS-99), or the IBMJCE provider. Otherwise fall back to the old behaviour of
822 * inserting the provider in position 2.
823 *
824 * @param name
825 * The name string of the provider (this may not be the real name of the provider)
826 * @param className
827 * Name of the class the implements the provider. This class must
828 * be a subclass of <code>java.security.Provider</code>
829 *
830 * @return Returns the actual name of the provider that was loaded
831 */
832 public static String addJceProvider(String name, String className) {
833 Provider currentProvider = Security.getProvider(name);
834 if (currentProvider == null) {
835 try {
836 Class<? extends Provider> clazz = Loader.loadClass(className, false, Provider.class);
837 Provider provider = clazz.newInstance();
838 return addJceProvider(name, provider);
839 } catch (Throwable t) {
840 if (LOG.isDebugEnabled()) {
841 LOG.debug("The provider " + name + " could not be added: " + t.getMessage(), t);
842 }
843 return null;
844 }
845 }
846 return currentProvider.getName();
847 }
848
849 /**
850 * Add a new JCE security provider to use for WSS4J, of the specified name and class. Return
851 * either the name of the previously loaded provider, the name of the new loaded provider, or
852 * null if there's an exception in loading the provider. Add the provider either after the SUN
853 * provider (see WSS-99), or the IBMJCE provider. Otherwise fall back to the old behaviour of
854 * inserting the provider in position 2.
855 *
856 * @param name
857 * The name string of the provider (this may not be the real name of the provider)
858 * @param provider
859 * A subclass of <code>java.security.Provider</code>
860 *
861 * @return Returns the actual name of the provider that was loaded
862 */
863 public static String addJceProvider(String name, Provider provider) {
864 Provider currentProvider = Security.getProvider(name);
865 if (currentProvider == null) {
866 try {
867 //
868 // Install the provider after the SUN provider (see WSS-99)
869 // Otherwise fall back to the old behaviour of inserting
870 // the provider in position 2. For AIX, install it after
871 // the IBMJCE provider.
872 //
873 int ret = 0;
874 Provider[] provs = Security.getProviders();
875 for (int i = 0; i < provs.length; i++) {
876 if ("SUN".equals(provs[i].getName())
877 || "IBMJCE".equals(provs[i].getName())) {
878 ret = Security.insertProviderAt(provider, i + 2);
879 break;
880 }
881 }
882 if (ret == 0) {
883 ret = Security.insertProviderAt(provider, 2);
884 }
885 if (LOG.isDebugEnabled()) {
886 LOG.debug(
887 "The provider " + provider.getName() + " - "
888 + provider.getVersion() + " was added at position: " + ret
889 );
890 }
891 return provider.getName();
892 } catch (Throwable t) {
893 if (LOG.isDebugEnabled()) {
894 LOG.debug("The provider " + name + " could not be added: " + t.getMessage(), t);
895 }
896 return null;
897 }
898 }
899 return currentProvider.getName();
900 }
901
902
903 /**
904 * Add a new JCE security provider to use for WSS4J, of the specified name and class. Return
905 * either the name of the previously loaded provider, the name of the new loaded provider, or
906 * null if there's an exception in loading the provider. Append the provider to the provider
907 * list.
908 *
909 * @param name
910 * The name string of the provider (this may not be the real name of the provider)
911 * @param className
912 * Name of the class the implements the provider. This class must
913 * be a subclass of <code>java.security.Provider</code>
914 *
915 * @return Returns the actual name of the provider that was loaded
916 */
917 public static String appendJceProvider(String name, String className) {
918 Provider currentProvider = Security.getProvider(name);
919 if (currentProvider == null) {
920 try {
921 Class<? extends Provider> clazz = Loader.loadClass(className, false, Provider.class);
922 Provider provider = clazz.newInstance();
923
924 int ret = Security.addProvider(provider);
925 if (LOG.isDebugEnabled()) {
926 LOG.debug(
927 "The provider " + provider.getName()
928 + " was added at position: " + ret
929 );
930 }
931 return provider.getName();
932 } catch (Throwable t) {
933 if (LOG.isDebugEnabled()) {
934 LOG.debug("The provider " + name + " could not be added: " + t.getMessage(), t);
935 }
936 return null;
937 }
938 }
939 return currentProvider.getName();
940 }
941
942 /**
943 * Add a new JCE security provider to use for WSS4J, of the specified name and class. Return
944 * either the name of the previously loaded provider, the name of the new loaded provider, or
945 * null if there's an exception in loading the provider. Append the provider to the provider
946 * list.
947 *
948 * @param name
949 * The name string of the provider (this may not be the real name of the provider)
950 * @param provider
951 * A subclass of <code>java.security.Provider</code>
952 *
953 * @return Returns the actual name of the provider that was loaded
954 */
955 public static String appendJceProvider(String name, Provider provider) {
956 Provider currentProvider = Security.getProvider(name);
957 if (currentProvider == null) {
958 try {
959 int ret = Security.addProvider(provider);
960 if (LOG.isDebugEnabled()) {
961 LOG.debug(
962 "The provider " + provider.getName()
963 + " was added at position: " + ret
964 );
965 }
966 return provider.getName();
967 } catch (Throwable t) {
968 if (LOG.isDebugEnabled()) {
969 LOG.debug("The provider " + name + " could not be added: " + t.getMessage(), t);
970 }
971 return null;
972 }
973 }
974 return currentProvider.getName();
975 }
976
977 public boolean isAllowUsernameTokenNoPassword() {
978 return allowUsernameTokenNoPassword;
979 }
980
981 public void setAllowUsernameTokenNoPassword(boolean allowUsernameTokenNoPassword) {
982 this.allowUsernameTokenNoPassword = allowUsernameTokenNoPassword;
983 }
984
985 public int getUtTTL() {
986 return utTTL;
987 }
988
989 public void setUtTTL(int utTTL) {
990 this.utTTL = utTTL;
991 }
992
993 public int getUtFutureTTL() {
994 return utFutureTTL;
995 }
996
997 public void setUtFutureTTL(int utFutureTTL) {
998 this.utFutureTTL = utFutureTTL;
999 }
1000
1001 }