KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > enterprise > webservice > JAXWSSystemHandlerDelegateFactory


1 /*
2  * The contents of this file are subject to the terms
3  * of the Common Development and Distribution License
4  * (the License). You may not use this file except in
5  * compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * https://glassfish.dev.java.net/public/CDDLv1.0.html or
9  * glassfish/bootstrap/legal/CDDLv1.0.txt.
10  * See the License for the specific language governing
11  * permissions and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL
14  * Header Notice in each file and include the License file
15  * at glassfish/bootstrap/legal/CDDLv1.0.txt.
16  * If applicable, add the following below the CDDL Header,
17  * with the fields enclosed by brackets [] replaced by
18  * you own identifying information:
19  * "Portions Copyrighted [year] [name of copyright owner]"
20  *
21  * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
22  */

23
24 package com.sun.enterprise.webservice;
25
26 import javax.annotation.PostConstruct;
27 import javax.annotation.PreDestroy;
28
29 import java.util.ArrayList JavaDoc;
30 import java.util.HashSet JavaDoc;
31 import java.util.HashMap JavaDoc;
32 import java.util.List JavaDoc;
33 import java.util.Map JavaDoc;
34 import java.util.Iterator JavaDoc;
35 import java.util.logging.*;
36 import java.lang.reflect.Method JavaDoc;
37 import java.rmi.UnmarshalException JavaDoc;
38 import java.security.PrivilegedActionException JavaDoc;
39 import java.security.PrivilegedExceptionAction JavaDoc;
40
41
42 import javax.xml.namespace.QName JavaDoc;
43 import javax.xml.ws.handler.soap.SOAPHandler;
44
45 import javax.xml.ws.handler.Handler;
46 import javax.xml.ws.handler.HandlerResolver;
47 import javax.xml.ws.handler.PortInfo;
48 import javax.xml.ws.Service;
49
50 import javax.security.auth.Subject JavaDoc;
51
52 import com.sun.enterprise.security.jauth.*;
53 import com.sun.enterprise.security.SecurityContext;
54 import com.sun.enterprise.security.wss.WebServiceSecurity;
55
56 import com.sun.xml.ws.spi.runtime.Invoker;
57 import com.sun.xml.ws.spi.runtime.MessageContext;
58 import com.sun.xml.ws.spi.runtime.SOAPMessageContext;
59 import com.sun.xml.ws.spi.runtime.SystemHandlerDelegate;
60 import com.sun.xml.ws.spi.runtime.SystemHandlerDelegateFactory;
61 import com.sun.xml.ws.handler.SHDSOAPMessageContext;
62
63 import com.sun.enterprise.webservice.monitoring.EndpointImpl;
64 import com.sun.enterprise.webservice.monitoring.JAXWSEndpointImpl;
65
66 import com.sun.enterprise.deployment.runtime.common.MessageSecurityBindingDescriptor;
67 import com.sun.enterprise.deployment.ServiceReferenceDescriptor;
68 import com.sun.enterprise.deployment.ServiceRefPortInfo;
69 import com.sun.enterprise.deployment.WebServiceEndpoint;
70
71 import com.sun.enterprise.Switch;
72 import com.sun.ejb.Container;
73 import com.sun.ejb.Invocation;
74 import com.sun.enterprise.InvocationManager;
75
76 import com.sun.logging.*;
77 import com.sun.enterprise.util.i18n.StringManager;
78 /**
79  * A SystemHandlerDelegate is used to inject system level functionality into a
80  * message processing runtime. The methods of this interface are invoked by
81  * the client and enpoint message dispatchers of the message processing
82  * runtime.
83  *
84  * @author WS Development Team
85  */

86 public class JAXWSSystemHandlerDelegateFactory
87     extends SystemHandlerDelegateFactory {
88
89     static Logger _logger = LogDomains.getLogger(LogDomains.SECURITY_LOGGER);
90    
91     static final String JavaDoc CLIENT_AUTH_CONTEXT =
92     "com.sun.enterprise.security.jauth.ClientAuthContext";
93
94     static final String JavaDoc SERVER_AUTH_CONTEXT =
95         "com.sun.enterprise.security.jauth.ServerAuthContext";
96
97     static final Object JavaDoc factory = SystemHandlerDelegateFactory.getFactory();
98
99     // resources...
100
static StringManager localStrings =
101         StringManager.getManager(JAXWSSystemHandlerDelegateFactory.class);
102
103     static Map JavaDoc<QName JavaDoc,ClientDelegate> serviceMap =
104         new HashMap JavaDoc<QName JavaDoc,ClientDelegate>();
105
106     private static ClientDelegateHelper helper = new ClientDelegateHelper();
107
108     // used by SOAPBindingImpl to inject a delegate in the binding.
109
// we inject the same helper delegate in all SOAPbiningImpl objects,
110
// and when invoked, the helper multiplexes to the correct ClientDelegate
111
// (with embedded service specific policy).
112

113     public SystemHandlerDelegate create() {
114     return helper;
115     }
116
117     public boolean isEnabled(MessageContext context) {
118     boolean rvalue = (factory != null);
119     if (rvalue) {
120         rvalue = (helper.getClientDelegate(context) != null);
121     }
122     return rvalue;
123     }
124
125     private JAXWSSystemHandlerDelegateFactory() {
126     }
127
128     public static SystemHandlerDelegate
129     getEjbDelegate(ServerAuthConfig authConfig,
130                WebServiceEndpoint webServiceEndpoint,
131                JAXWSEndpointImpl endpoint) throws RuntimeException JavaDoc {
132
133     try {
134         
135         // login-config takes precedent over message security binding
136
if (webServiceEndpoint != null &&
137         webServiceEndpoint.hasAuthMethod()) {
138         authConfig = null;
139         }
140
141         if (authConfig != null) {
142         return new EjbDelegate(authConfig,endpoint);
143         }
144
145     } catch (Exception JavaDoc e) {
146         _logger.log(Level.SEVERE,"ws.error_server_config",e);
147         if (e instanceof RuntimeException JavaDoc) {
148         throw (RuntimeException JavaDoc) e;
149         } else {
150         throw new RuntimeException JavaDoc(e);
151         }
152     }
153     return null;
154     }
155
156     public static SystemHandlerDelegate
157     getEjbDelegate(WebServiceEndpoint webServiceEndpoint,
158                JAXWSEndpointImpl endpoint) throws RuntimeException JavaDoc {
159
160     MessageSecurityBindingDescriptor binding = null;
161     if (webServiceEndpoint != null) {
162         binding = webServiceEndpoint.getMessageSecurityBinding();
163     }
164
165     try {
166
167         ServerAuthConfig authConfig = ServerAuthConfig.getConfig
168         (com.sun.enterprise.security.jauth.AuthConfig.SOAP,
169          binding,WSSCallbackHandler.getInstance());
170         
171         return JAXWSSystemHandlerDelegateFactory.getEjbDelegate
172         (authConfig,webServiceEndpoint,endpoint);
173
174     } catch (Exception JavaDoc e) {
175          _logger.log(Level.SEVERE,"ws.error_server_config",e);
176         if (e instanceof RuntimeException JavaDoc) {
177         throw (RuntimeException JavaDoc) e;
178         } else {
179         throw new RuntimeException JavaDoc(e);
180         }
181     }
182     }
183
184     public static SystemHandlerDelegate
185         getServletDelegate(WebServiceEndpoint webServiceEndpoint)
186     throws Exception JavaDoc {
187
188     MessageSecurityBindingDescriptor binding = null;
189     if (webServiceEndpoint != null) {
190         binding = webServiceEndpoint.getMessageSecurityBinding();
191     }
192
193     try {
194         
195         ServerAuthConfig authConfig;
196
197         // login-config takes precedent over message security binding,
198
// although login-config should not be specified in servlet
199
// WebServiceEndpoint
200
if (webServiceEndpoint != null &&
201         webServiceEndpoint.hasAuthMethod()) {
202
203         authConfig = null;
204
205         } else {
206
207         authConfig = ServerAuthConfig.getConfig
208             (com.sun.enterprise.security.jauth.AuthConfig.SOAP,
209              binding,WSSCallbackHandler.getInstance());
210
211         }
212
213         if (authConfig != null) {
214         return new ServletDelegate(authConfig);
215         }
216
217     } catch (Exception JavaDoc e) {
218          _logger.log(Level.SEVERE,"ws.error_server_config",e);
219         throw e;
220     }
221     return null;
222     }
223
224     public static void
225     configureClientDelegate(Service service,
226                 ServiceReferenceDescriptor desc) {
227
228     boolean hasConfig = false;
229
230     Map JavaDoc<QName JavaDoc,ClientAuthConfig> portMap =
231         new HashMap JavaDoc<QName JavaDoc,ClientAuthConfig>();
232
233     MessageSecurityBindingDescriptor binding = null;
234
235     Iterator JavaDoc iter = desc.getPortsInfo().iterator();
236
237     // for each declared port, determine the applicable
238
// message-security-binding
239

240     ClientAuthConfig authConfig;
241
242     try {
243
244         while (iter.hasNext()) {
245  
246             ServiceRefPortInfo portInfo =
247             (ServiceRefPortInfo) iter.next();
248
249         binding = portInfo.getMessageSecurityBinding();
250
251         // use portInfo and port in CallbackHandler construction
252

253         if (binding != null) {
254
255             authConfig = ClientAuthConfig.getConfig
256             (com.sun.enterprise.security.jauth.AuthConfig.SOAP,
257             binding,WSSCallbackHandler.getInstance());
258
259             if (portInfo.hasWsdlPort()) {
260                portMap.put(portInfo.getWsdlPort(),authConfig);
261             } else {
262             throw new RuntimeException JavaDoc
263                 ("Service: " + service.getServiceName() +
264                 " portName (i.e. wsdl-Port) not defined");
265             }
266         }
267         }
268      
269         // determine the message-security-binding that would apply
270
// by default to ports without an explicit binding
271

272         authConfig = ClientAuthConfig.getConfig
273         (com.sun.enterprise.security.jauth.AuthConfig.SOAP,
274          null,WSSCallbackHandler.getInstance());
275
276         if (!portMap.isEmpty() || authConfig != null) {
277         portMap.put((QName JavaDoc)null,authConfig);
278         }
279
280         serviceMap.put(service.getServiceName(),
281                new ClientDelegate(portMap));
282     
283     } catch (Exception JavaDoc e) {
284         _logger.log(Level.SEVERE,"ws.error_client_config",e);
285         if (e instanceof RuntimeException JavaDoc) {
286         throw (RuntimeException JavaDoc) e;
287         } else {
288         throw new RuntimeException JavaDoc(e);
289         }
290     }
291     }
292
293     public static void removeClientDelegate(QName JavaDoc serviceName) {
294     serviceMap.remove(serviceName);
295     }
296
297     static boolean portNamesMatch(QName JavaDoc pN1, QName JavaDoc pN2) {
298     boolean rvalue = false;
299     if (pN1 == pN2) {
300         rvalue = true;
301     } else if (pN1 != null && pN2 != null && pN1.equals(pN2)) {
302         rvalue = true;
303     }
304     return rvalue;
305     }
306
307     static SOAPHandler getClientHandler
308         (ServiceReferenceDescriptor descriptor, QName JavaDoc portName) {
309
310     SOAPHandler rvalue = null;
311
312     MessageSecurityBindingDescriptor binding = null;
313      
314     ClientAuthConfig authConfig = null;
315
316     Iterator JavaDoc iter = descriptor.getPortsInfo().iterator();
317
318     // if portinfo(s) are declared try to find the one that matches
319
// the portName
320

321     while (iter.hasNext()) {
322         
323         ServiceRefPortInfo portInfo = (ServiceRefPortInfo) iter.next();
324         
325         QName JavaDoc pN = portInfo.getWsdlPort();
326
327         if (pN != null && portNamesMatch(portName,pN)) {
328
329             binding = portInfo.getMessageSecurityBinding();
330
331             break;
332         }
333     }
334      
335     try {
336
337         authConfig = ClientAuthConfig.getConfig
338         (com.sun.enterprise.security.jauth.AuthConfig.SOAP,
339          binding,WSSCallbackHandler.getInstance());
340
341     } catch (Exception JavaDoc e) {
342         _logger.log(Level.SEVERE,"ws.error_client_config",e);
343         authConfig = null;
344     }
345
346     if (authConfig != null) {
347         rvalue = new ClientHandler(authConfig);
348     }
349     
350     return rvalue;
351     }
352
353     public static HandlerResolverImpl
354     getHandlerResolverImpl(Service service,
355                    ServiceReferenceDescriptor descriptor) {
356     if (factory != null &&
357         (factory instanceof JAXWSSystemHandlerDelegateFactory)) {
358         // If security is configured for some port of the service,
359
// then a ClientDelegate (i.e., a SystemHandlerDelegate) would
360
// be constructed and "associated" with the service,
361
// or with ports of the service.
362
configureClientDelegate(service,descriptor);
363         return null;
364     } else {
365         return new WSSHandlerResolver(descriptor);
366     }
367     }
368     
369     static class ServletDelegate implements SystemHandlerDelegate {
370
371     BaseAuthConfig authConfig;
372
373     ServletDelegate(BaseAuthConfig authConfig) {
374         this.authConfig = authConfig;
375     }
376
377     /**
378      * base implementation - designed for servlet endpoint
379      *
380      * Called by both client and endpoint message dispatchers to activate
381      * injected request message processing. When called by a client side
382      * message dispatcher, this method must be
383      * called just before the message (associated with the MessageContext)
384      * is sent. When called by the message dispatcher at an endpoint, this
385      * method must be called before MustUnderstand processing on the
386      * associated message.
387      *
388      * @param context when called for a SOAP binding, the argument
389      * must be an instanceof com.sun.xml.ws.spi.runtime.SOAPMessageContext,
390      * and when called for a SOAP binding at an endpoint, the Invoker (on
391      * the context) must be available for use by the delegate.
392      *
393      * @return true if processing by the delegate was such that the caller
394      * should continue with its normal message processing. Returns false
395      * when the delegate has established, in the MessageContext,
396      * the response message to be sent. When this method returns false,
397      * the calling message dispatcher must return the response message
398      * without performing MustUnderstand processing and without invoking
399      * the endpoint. Only delegates called by endpoint side message
400      * may return false
401      *
402      * @throws java.lang.Exception when the processing by the delegate
403      * failed without yielding a response message; in which case, the
404      * caller shall determine how to process the error.
405      */

406     public boolean processRequest(MessageContext context)
407         throws Exception JavaDoc {
408
409         assert context instanceof SOAPMessageContext;
410
411         final SOAPMessageContext soapMC =
412             (SOAPMessageContext) context;
413
414         boolean status = true;
415     
416         final ServerAuthContext sAC =
417             (this.authConfig == null ? null :
418              ((ServerAuthConfig)this.authConfig).
419              getAuthContext(soapMC));
420
421         try {
422
423             if (sAC != null) {
424
425             status = false;
426             // proceed to process message sescurity
427
status= WebServiceSecurity.validateRequest(soapMC,sAC);
428
429             if (status) {
430
431                 soapMC.put( SERVER_AUTH_CONTEXT , sAC);
432                 
433                 soapMC.setScope
434                 (SERVER_AUTH_CONTEXT,
435                  MessageContext.Scope.HANDLER);
436
437             }
438             }
439
440         } catch (Exception JavaDoc e) {
441             if (e instanceof AuthException) {
442                 _logger.log(Level.INFO,"ws.error_validate_request", e);
443             } else {
444                _logger.log(Level.SEVERE,"ws.error_validate_request",e);
445             }
446
447             throw e;
448
449         } finally {
450             WebServiceSecurity.auditInvocation(soapMC,status);
451         }
452
453         if (status) {
454
455             // only do doAsPriv if SecurityManager in effect.
456

457             if (System.getSecurityManager() != null &&
458             soapMC instanceof SHDSOAPMessageContext) {
459
460             // on this branch, the endpoint invocation and the
461
// processing of the response will be initiated from
462
// within the system handler delegate. delegate returns
463
// false so that dispatcher will not invoke the
464
// endpoint.
465

466             status = false;
467
468             try {
469
470                 Subject.doAsPrivileged
471                 (SecurityContext.getCurrent().getSubject(),
472                  new PrivilegedExceptionAction JavaDoc() {
473                     public Object JavaDoc run() throws Exception JavaDoc {
474                     Invoker invoker =
475                         ((SHDSOAPMessageContext)soapMC).
476                         getInvoker();
477                     invoker.invoke();
478                     processResponse(soapMC);
479                     return null;
480                     }
481                 }, null);
482
483             } catch (PrivilegedActionException JavaDoc pae) {
484                 Throwable JavaDoc cause = pae.getCause();
485                 if (cause instanceof AuthException){
486                 _logger.log(Level.SEVERE,
487                         "ws.error_secure_response", cause);
488                 }
489                 Exception JavaDoc e = null;
490                 if (cause instanceof Exception JavaDoc) {
491                 e = (Exception JavaDoc) cause;
492                 } else {
493                 e = new Exception JavaDoc(cause);
494                 }
495                 throw e;
496             }
497             }
498         }
499         return status;
500     }
501     
502     /**
503      * base implementation - generic endpoint
504      *
505      * Called by both client and endpoint message dispatchers to activate
506      * injected response message processing. When called by the message
507      * dispatcher at the client, this method must
508      * be called before MustUnderstand processing on the received message
509      * (associated with the MessageContext). When called by the message
510      * dispatcher at an endpoint, this method must be called after the
511      * endpoint has been invoked, and just before the associated response
512      * message is sent. In the special case where invocation of the
513      * endpoint
514      * caused an Exception to be thrown, this method must not be called.
515      *
516      * @param context when called for a SOAP binding the argument
517      * must be an instanceof com.sun.xml.ws.spi.runtime.SOAPMessageContext.
518      *
519      * @throws java.lang.Exception when the processing by the delegate
520      * failed. In this case, the caller must not send the response message
521      * but shall
522      * otherwise determine how to process the error.
523      */

524     public void processResponse(MessageContext context)
525         throws Exception JavaDoc {
526         
527         assert context instanceof SOAPMessageContext;
528
529         SOAPMessageContext soapMC= (SOAPMessageContext) context;
530
531         ServerAuthContext sAC =
532             (ServerAuthContext) soapMC.get( SERVER_AUTH_CONTEXT );
533
534         if (sAC == null) {
535             return;
536         }
537
538         try {
539
540             WebServiceSecurity.secureResponse(soapMC,sAC);
541
542         } catch (Exception JavaDoc e) {
543
544             if (e instanceof AuthException) {
545             _logger.log(Level.INFO, "ws.error_secure_response", e);
546             } else {
547             _logger.log(Level.SEVERE,"ws.error_secure_response",e);
548             }
549             
550             throw e;
551         }
552     }
553
554               
555     /**
556      * base implementation - generic
557      *
558      * This method must be called by an endpoint message dispatcher after
559      * MustUnderstand processing and before endpoint invocation.
560      *
561      * @param context when called for a SOAP binding the argument
562      * must be an instanceof com.sun.xml.ws.spi.runtime.SOAPMessageContext.
563      */

564     public void preInvokeEndpointHook(MessageContext context) {
565         // do nothing
566
}
567     }
568
569     // this delegate specializes methods of ServletDelagate
570

571     static class EjbDelegate extends ServletDelegate {
572
573     private static WsUtil wsUtil = new WsUtil();
574     
575     JAXWSEndpointImpl endpoint;
576
577     EjbDelegate(BaseAuthConfig authConfig,
578                  JAXWSEndpointImpl endpoint) {
579         super(authConfig);
580         this.endpoint = endpoint;
581     }
582
583     /**
584      * performs ejb authorization check
585      */

586     public boolean processRequest(MessageContext context)
587         throws Exception JavaDoc {
588
589         assert context instanceof SOAPMessageContext;
590
591         SOAPMessageContext soapMC = (SOAPMessageContext) context;
592
593         boolean status = true;
594
595         ServerAuthContext sAC =
596         (this.authConfig == null ? null :
597          ((ServerAuthConfig)this.authConfig).getAuthContext(soapMC));
598     
599         try {
600         
601         if (sAC != null) {
602
603             status = false;
604             // proceed to process message sescurity
605
status = WebServiceSecurity.validateRequest(soapMC,sAC);
606
607             if (status) {
608
609             soapMC.put( SERVER_AUTH_CONTEXT , sAC);
610
611             soapMC.setScope
612                 (SERVER_AUTH_CONTEXT,MessageContext.Scope.HANDLER);
613
614             }
615         }
616
617         } catch (Exception JavaDoc e) {
618         if (e instanceof AuthException) {
619             _logger.log(Level.INFO, "ws.error_validate_request", e);
620         } else {
621             _logger.log(Level.SEVERE, "ws.error_validate_request", e);
622         }
623
624         throw e;
625
626         } finally {
627         WebServiceSecurity.auditInvocation(soapMC,status);
628         }
629     
630         if (status) {
631
632         Switch theSwitch = Switch.getSwitch();
633         InvocationManager invManager= theSwitch.getInvocationManager();
634         Invocation inv= (Invocation) invManager.getCurrentInvocation();
635             
636         Method JavaDoc m = BaseAuthConfig.getMethod(soapMC);
637
638         Exception JavaDoc ie = null;
639         if (m!=null) {
640
641             Container container = (Container) inv.container;
642             
643             try {
644             inv.method = m;
645
646
647             if ( !container.authorize(inv) ) {
648                 ie = new Exception JavaDoc
649                 ("Client not authorized for invocation of "
650                                  + inv.method);
651             } else {
652                 // Record the method on which the successful
653
// authorization check was performed.
654
inv.setWebServiceMethod(inv.method);
655             }
656             } catch(Exception JavaDoc e) {
657             String JavaDoc errorMsg= "Error unmarshalling method for ejb "
658                             + (endpoint != null ?
659                    endpoint.getDescriptor().
660                    getEjbComponentImpl().getName() :
661                    "unable to determine EjbComponentImp.name");
662             ie = new UnmarshalException JavaDoc(errorMsg);
663             ie.initCause(e);
664             }
665
666         } else {
667             inv.setWebServiceMethod(null);
668         }
669         
670         if( ie != null ) {
671             inv.exception = ie;
672             throw ie;
673         }
674         }
675
676         return status;
677     }
678
679     /**
680      * ensure that authorized method is not changed by jaxrpc handlers
681      */

682     public void preInvokeEndpointHook(MessageContext context) {
683        
684         assert context instanceof SOAPMessageContext;
685
686         SOAPMessageContext soapMC = (SOAPMessageContext) context;
687
688         if (endpoint.getDescriptor().hasHandlerChain()) {
689         // some handlers are defined.
690
Switch theSwitch = Switch.getSwitch();
691         InvocationManager invManager= theSwitch.getInvocationManager();
692         Invocation inv= (Invocation) invManager.getCurrentInvocation();
693         Container container = (Container) inv.container;
694             
695         Method JavaDoc m = BaseAuthConfig.getMethod(soapMC);
696         
697         if (m!=null) {
698             try {
699             Method JavaDoc webServiceMethodInPreHandler =
700                 inv.getWebServiceMethod();
701                     
702             if( webServiceMethodInPreHandler != null ) {
703                 // Now that application handlers have run, do
704
// another method lookup and compare the results
705
// with the original one. This ensures that the
706
// application handlers have not changed the
707
// message context in any way that would impact
708
// which method is invoked.
709
if( !webServiceMethodInPreHandler.equals(m) ) {
710                 inv.exception = new UnmarshalException JavaDoc
711                                     ("Original method " +
712                      webServiceMethodInPreHandler +
713                     " does not match post-handler method "+ m);
714                 }
715             }
716             } catch(Exception JavaDoc e) {
717             String JavaDoc errorMsg = "Exception while getting method for "
718                 + ((inv != null ) ?
719                  ((Container) inv.container).getEjbDescriptor().
720                  getName() : "");
721             inv.exception = new UnmarshalException JavaDoc(errorMsg);
722             inv.exception.initCause(e);
723             }
724                 
725             if( inv.exception != null ) {
726             WsUtil.getDefaultLogger().log
727                 (Level.WARNING,"postEjbHandlerError",
728                  inv.exception);
729
730             wsUtil.throwSOAPFaultException
731                 (inv.exception.getMessage(),context);
732             }
733         }
734         }
735     }
736     }
737
738     // this delegate is used on the client side, and should eventually be
739
// injected by the SOAPBindingImpl.
740
//this delegate multiplexes the processing to the correct ClientDelegate.
741

742     static class ClientDelegateHelper implements SystemHandlerDelegate {
743
744     ClientDelegateHelper() {
745     }
746
747     static ClientDelegate getClientDelegate(MessageContext context) {
748
749         ClientDelegate rvalue = null;
750         QName JavaDoc serviceName =
751         (QName JavaDoc)context.get(MessageContext.WSDL_SERVICE);
752         if (serviceName != null) {
753         rvalue = serviceMap.get(serviceName);
754         }
755
756         // the helper should only be included in the binding
757
// when message security is configured for the service;
758
// in which case we should always find a CLientAuthConfig in
759
// the service map (if the helper is invoked)
760

761         if (rvalue == null) {
762         throw new RuntimeException JavaDoc
763             (serviceName == null ?
764              "no WSDL_SERVICE in MessageContext":
765              "no ClientDelegate for service" + serviceName);
766         }
767         return rvalue;
768     }
769
770     /**
771      * does client side processing
772      */

773     public boolean processRequest(MessageContext context)
774         throws Exception JavaDoc {
775         return getClientDelegate(context).processRequest(context);
776     }
777
778     /**
779      * does client side processing
780      */

781     public void processResponse(MessageContext context) throws
782         Exception JavaDoc {
783         getClientDelegate(context).processResponse(context);
784     }
785
786     // no client side tracing
787
public void preInvokeEndpointHook(MessageContext context) {
788         try {
789         getClientDelegate(context).preInvokeEndpointHook(context);
790         } catch (Exception JavaDoc e) {
791         // extinguish exception but if exception would occur
792
// here, it would have alredy occured on processRequest or
793
// ProcessResponse (and this methid would not be called).
794
}
795     }
796     }
797
798     // this delegate is used on the client side, and should eventually be
799
// injected by the SOAPBindingImpl.
800
// This delegate is called by the ClientHelper delegate.
801

802     static class ClientDelegate implements SystemHandlerDelegate {
803
804     private boolean isAppclientContainer;
805     Map JavaDoc<QName JavaDoc,ClientAuthConfig> portMap;
806
807     ClientDelegate(Map JavaDoc<QName JavaDoc,ClientAuthConfig> portMap) {
808
809         this.portMap = portMap;
810
811         int containerType = Switch.getSwitch().getContainerType();
812         if (containerType == Switch.APPCLIENT_CONTAINER) {
813         isAppclientContainer = true;
814         } else {
815         isAppclientContainer = false;
816         }
817     }
818
819     ClientAuthConfig getAuthConfig(MessageContext context) {
820
821         ClientAuthConfig rvalue = null;
822
823         QName JavaDoc portName = (QName JavaDoc)context.get(MessageContext.WSDL_PORT);
824         if (portName != null) {
825         if (portMap.containsKey(portName)) {
826             rvalue = (ClientAuthConfig) portMap.get(portName);
827         } else if (portMap.containsKey(null)) {
828             rvalue = (ClientAuthConfig) portMap.get((QName JavaDoc)null);
829         }
830         } else if (portMap.containsKey((QName JavaDoc)null)) {
831         rvalue = (ClientAuthConfig) portMap.get((QName JavaDoc)null);
832         }
833         return rvalue;
834     }
835
836     /**
837      * does client side request processing
838      */

839     public boolean processRequest(MessageContext context)
840         throws Exception JavaDoc {
841
842         assert context instanceof SOAPMessageContext;
843
844         boolean status = true;
845     
846         SOAPMessageContext soapMC= (SOAPMessageContext) context;
847
848         ClientAuthConfig config = this.getAuthConfig(context);
849  
850         final ClientAuthContext cAC =
851         (config == null ? null : config.getAuthContext(soapMC));
852
853         if (cAC != null) {
854         
855         try {
856
857             status = false;
858             // proceed to process message sescurity
859
WebServiceSecurity.secureRequest(soapMC,cAC,
860                              isAppclientContainer);
861             
862             soapMC.put( CLIENT_AUTH_CONTEXT , cAC);
863
864             soapMC.setScope
865             (CLIENT_AUTH_CONTEXT,MessageContext.Scope.HANDLER);
866             
867             status = true;
868             
869         } catch (Exception JavaDoc e) {
870             if (e instanceof AuthException) {
871             _logger.log(Level.INFO, "ws.error_secure_request", e);
872             } else {
873             _logger.log(Level.SEVERE, "ws.error_secure_request",e);
874             }
875             
876             throw e;
877         }
878         }
879
880         return status;
881     }
882
883     /**
884      * does client side response processing
885      */

886     public void processResponse(MessageContext context) throws
887         Exception JavaDoc {
888
889         assert context instanceof SOAPMessageContext;
890
891         SOAPMessageContext soapMC = (SOAPMessageContext) context;
892
893         ClientAuthContext cAC =
894         (ClientAuthContext) soapMC.get( CLIENT_AUTH_CONTEXT );
895
896         if (cAC == null) {
897         return;
898         }
899
900
901         try {
902         boolean retValue =
903             WebServiceSecurity.validateResponse(soapMC,cAC);
904         } catch(Exception JavaDoc e) {
905         if (e instanceof AuthException) {
906             _logger.log(Level.INFO, "ws.error_validate_response", e);
907         } else {
908             _logger.log(Level.SEVERE, "ws.error_validate_response", e);
909         }
910         
911         throw e;
912         }
913     }
914
915     // no client side tracing
916
public void preInvokeEndpointHook(MessageContext context) {
917     }
918
919     }
920
921     // this following client handler is provided as an alternatve to
922
// SHD injection.
923

924     static class ClientHandler implements
925     SOAPHandler<javax.xml.ws.handler.soap.SOAPMessageContext> {
926
927     ClientAuthConfig config;
928     private boolean isAppclientContainer;
929
930     ClientHandler(ClientAuthConfig config) {
931
932         this.config = config;
933
934         int containerType = Switch.getSwitch().getContainerType();
935         if (containerType == Switch.APPCLIENT_CONTAINER) {
936         isAppclientContainer = true;
937         } else {
938         isAppclientContainer = false;
939         }
940     }
941
942     @PostConstruct
943     public void initMe() {
944         // just here for debugging
945
}
946
947     @PreDestroy
948     public void destroyMe() {
949         config = null;
950     }
951
952     public void close(javax.xml.ws.handler.MessageContext context) {
953     }
954
955     public boolean handleFault
956     (javax.xml.ws.handler.soap.SOAPMessageContext context) {
957         return true;
958     }
959
960     public boolean handleMessage
961     (javax.xml.ws.handler.soap.SOAPMessageContext context) {
962
963         assert context instanceof
964         com.sun.xml.ws.spi.runtime.SOAPMessageContext;
965
966         boolean rvalue = true;
967
968         boolean msgOut =
969         ((Boolean JavaDoc) context.get
970          (javax.xml.ws.handler.
971           MessageContext.MESSAGE_OUTBOUND_PROPERTY)).booleanValue();
972
973         try {
974
975         if (msgOut) {
976
977             ClientAuthContext cAC = config.getAuthContext(context);
978
979             if (cAC != null) {
980         
981             WebServiceSecurity.secureRequest
982                 (context,cAC,isAppclientContainer);
983
984             context.put
985                 (JAXWSSystemHandlerDelegateFactory.
986                  CLIENT_AUTH_CONTEXT,cAC);
987
988             context.setScope
989                 (JAXWSSystemHandlerDelegateFactory.
990                  CLIENT_AUTH_CONTEXT,MessageContext.Scope.HANDLER);
991
992             }
993         } else {
994
995             ClientAuthContext cAC = (ClientAuthContext) context.get
996             (JAXWSSystemHandlerDelegateFactory.
997              CLIENT_AUTH_CONTEXT);
998
999             if (cAC != null) {
1000            rvalue = WebServiceSecurity.validateResponse
1001                (context,cAC);
1002            }
1003        }
1004
1005        } catch(Exception JavaDoc e) {
1006        Level level = (e instanceof AuthException ?
1007                   Level.INFO :
1008                   Level.SEVERE);
1009        String JavaDoc msg = (msgOut ?
1010                  "wss.container_auth_exception" :
1011                  "wss.validate_dispose_failed");
1012        
1013        _logger.log(level,msg,e);
1014
1015        if (e instanceof RuntimeException JavaDoc) {
1016            throw (RuntimeException JavaDoc) e;
1017        } else {
1018            throw new RuntimeException JavaDoc(e);
1019        }
1020        }
1021        return rvalue;
1022    }
1023
1024    public java.util.Set JavaDoc<QName JavaDoc> getHeaders() {
1025        
1026        HashSet JavaDoc<QName JavaDoc> headers = new HashSet JavaDoc<QName JavaDoc>();
1027
1028        QName JavaDoc qNames[] = config.getMechanisms();
1029        for (int i = 0; i < qNames.length; i++) {
1030        headers.add(qNames[i]);
1031        }
1032
1033        return headers;
1034    }
1035    }
1036
1037    /**
1038     * This specialized resolver injects a security handler in every
1039     * handler chain it returns.
1040     */

1041    static class WSSHandlerResolver extends HandlerResolverImpl {
1042    
1043    private Map JavaDoc<PortInfo, List JavaDoc<Handler>> chainMap;
1044
1045    ServiceReferenceDescriptor d;
1046    
1047    public WSSHandlerResolver(ServiceReferenceDescriptor descriptor){
1048        chainMap = new HashMap JavaDoc<PortInfo, List JavaDoc<Handler>>();
1049        d = descriptor;
1050    }
1051
1052    public List JavaDoc<Handler> getHandlerChain(PortInfo info) {
1053        List JavaDoc<Handler> chain = null;
1054        if (chainMap.containsKey(info)) {
1055        chain = chainMap.get(info);
1056        }
1057        else {
1058        chain = new ArrayList JavaDoc<Handler>();
1059        this.setHandlerChain(info,chain);
1060        }
1061        return chain;
1062    }
1063    
1064    public void setHandlerChain(PortInfo info, List JavaDoc<Handler> chain) {
1065
1066            // If Handlers are already configured for this port, then no need to add
1067
// the security handler again - just add this list of handlers
1068
List JavaDoc<Handler> currentList = chainMap.get(info);
1069            if(currentList != null && !currentList.isEmpty()) {
1070                currentList.addAll(chain);
1071                return;
1072            }
1073
1074        Handler secHandler = null;
1075        if (d != null) {
1076        secHandler = JAXWSSystemHandlerDelegateFactory.getClientHandler
1077            (d,info.getPortName());
1078        }
1079
1080        if (chain == null) {
1081        chain = new ArrayList JavaDoc<Handler>();
1082        }
1083
1084        if (secHandler != null) {
1085        chain.add(secHandler);
1086        }
1087
1088        chainMap.put(info, chain);
1089    }
1090    }
1091    
1092}
1093
1094 
1095
1096
Popular Tags