cxf-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From conflue...@apache.org
Subject [CONF] Apache CXF > Using WS-Policy in CXF projects
Date Mon, 20 Feb 2012 15:43:01 GMT
<html>
<head>
    <base href="https://cwiki.apache.org/confluence">
            <link rel="stylesheet" href="/confluence/s/2042/9/15/_/styles/combined.css?spaceKey=CXF&amp;forWysiwyg=true"
type="text/css">
    </head>
<body style="background: white;" bgcolor="white" class="email-body">
<div id="pageContent">
<div id="notificationFormat">
<div class="wiki-content">
<div class="email">
    <h2><a href="https://cwiki.apache.org/confluence/display/CXF/Using+WS-Policy+in+CXF+projects">Using
WS-Policy in CXF projects</a></h2>
    <h4>Page <b>edited</b> by             <a href="https://cwiki.apache.org/confluence/display/~ashakirin">Andrei
Shakirin</a>
    </h4>
        <br/>
                         <h4>Changes (3)</h4>
                                 
    
<div id="page-diffs">
                    <table class="diff" cellpadding="0" cellspacing="0">
    
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >Briefly, policy interceptors make
following steps: <br># Check message property _PolicyConstants.POLICY_OVERRIDE_. <br></td></tr>
            <tr><td class="diff-changed-lines" ># If _PolicyConstants.POLICY_OVERRIDE_
contains policy, it will be taken for <span class="diff-changed-words"><span class="diff-added-chars"style="background-color:
#dfd;">further </span>processing<span class="diff-added-chars"style="background-color:
#dfd;">.</span></span> <br></td></tr>
            <tr><td class="diff-unchanged" ># If property is empty, policy will
be asked from ServiceModel. Here CXF loads policies attached to WSDL or provided via Spring
configuration.  <br></td></tr>
            <tr><td class="diff-deleted-lines" style="color:#999;background-color:#fdd;text-decoration:line-through;">#
If any policy on step 2 or step 3 is found, _EffectivePolicy_ object will be created. All
interceptors registered for policy assertions in _PolicyInterceptorProviderRegistry_ will
be added to message interceptor chain. <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">#
If any policy on step 2 or step 3 is found, _EffectivePolicy_ will be created. Appropriate
WS-policies will be merged for the current message and built into Neethi _Policy_ object.
<br># All interceptors registered for result policy assertions will be added to message
interceptor chain. <br></td></tr>
            <tr><td class="diff-unchanged" > <br>Additionally, CXF verifies
satisfied policy assertions in _PolicyVerfificationInInterceptor_, _PolicyVerificationInFaultInterceptor_,
_PolicyVerificationOutInterceptor_.  If assertion is not processed and not satisfied in corresponded
interceptor, than In- interceptors throw Fault and Out- interceptors provide appropriate log
messages. <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
    
            </table>
    </div>                            <h4>Full Content</h4>
                    <div class="notificationGreySide">
        <p>WS-Policy provides flexible mechanism to activate desired functionality on
the client or service sides. Article describes how to define policies in custom CXF projects,
implement policy-aware interceptors and explains some aspects of internal CXF design regarding
WS-Policy.</p>

<h1><a name="UsingWS-PolicyinCXFprojects-Howtodefinepolicies"></a>How to
define policies</h1>
<p>There are basically 3 main possibilities to define WS-Policy in CXF projects:</p>
<ol>
	<li>WSDL Policy attachment</li>
	<li>Spring configuration</li>
	<li>Dynamically via message context property</li>
</ol>


<p>Let look into them in details. </p>

<h3><a name="UsingWS-PolicyinCXFprojects-WSDLPolicyattachment"></a>WSDL
Policy attachment</h3>
<p>WS-Policies can be attached and referenced in WSDL elements. <a href="http://www.w3.org/TR/ws-policy-attach/"
class="external-link" rel="nofollow">Web Services Policy 1.5 - Attachment </a> standard
describes all possible alternatives. WS-Policies can be placed inside WSDL itself or referenced
as external documents. CXF will automatically recognize, read and use policies defined or
referenced in WSDL. Sample of attached policy is shown below:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-xml">
&lt;wsdl:definitions name=<span class="code-quote">"HelloWorld"</span> targetNamespace=<span
class="code-quote">"http://apache.org/hello_world_soap_http"</span> 
…
<span class="code-tag">&lt;wsdl:service name=<span class="code-quote">"SOAPService"</span>&gt;</span>
    <span class="code-tag">&lt;wsdl:port binding=<span class="code-quote">"tns:Greeter_SOAPBinding"</span>
name=<span class="code-quote">"SoapPort"</span>&gt;</span>
        <span class="code-tag">&lt;soap:address location=<span class="code-quote">"http://localhost:9000/SoapContext/SoapPort"</span>/&gt;</span>
        <span class="code-tag">&lt;wsp:Policy <span class="code-keyword">xmlns:wsp</span>=<span
class="code-quote">"http://www.w3.org/ns/ws-policy"</span>&gt;</span>
             <span class="code-tag">&lt;wsam:Addressing <span class="code-keyword">xmlns:wsam</span>=<span
class="code-quote">"http://www.w3.org/2007/02/addressing/metadata"</span>&gt;</span>
                 <span class="code-tag">&lt;wsp:Policy/&gt;</span>
              <span class="code-tag">&lt;/wsam:Addressing&gt;</span>
         <span class="code-tag">&lt;/wsp:Policy&gt;</span>
    <span class="code-tag">&lt;/wsdl:port&gt;</span>
<span class="code-tag">&lt;/wsdl:service&gt;</span>
<span class="code-tag">&lt;/wsdl:definitions&gt;</span>
</pre>
</div></div>

<h3><a name="UsingWS-PolicyinCXFprojects-Springconfiguration"></a>Spring
configuration</h3>
<p>It is possible to define policies directly in Spring configuration of client and
service as jaxws feature. CFX will recognize and use configured WS-Policies:<br/>
Client:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-xml">
&lt;jaxws:client id=<span class="code-quote">"CRMServiceClient"</span> name=<span
class="code-quote">"{http://services.talend.org/CRMService}CRMServiceProvider"</span>
        <span class="code-keyword">xmlns:serviceNamespace</span>=<span class="code-quote">"http://services.talend.org/CRMService"</span>
        serviceClass=<span class="code-quote">"org.talend.services.crmservice.CRMService"</span>
        serviceName=<span class="code-quote">"serviceNamespace:CRMServiceProvider"</span>
        endpointName=<span class="code-quote">"serviceNamespace:CRMServicePort"</span>
        address=<span class="code-quote">"${endpoint.prefix}/CRMServiceProvider"</span>&gt;
        <span class="code-tag">&lt;jaxws:features&gt;</span>
            <span class="code-tag">&lt;p:policies&gt;</span>
                <span class="code-tag">&lt;wsp:PolicyReference URI=<span class="code-quote">"classpath:/saml.policy"</span>/&gt;</span>
            <span class="code-tag">&lt;/p:policies&gt;</span>
        <span class="code-tag">&lt;/jaxws:features&gt;</span>
<span class="code-tag">&lt;/jaxws:client&gt;</span>
</pre>
</div></div>

<p>Service:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-xml">
&lt;jaxws:endpoint id=<span class="code-quote">"CRMService"</span>
        <span class="code-keyword">xmlns:serviceNamespace</span>=<span class="code-quote">"http://services.talend.org/CRMService"</span>
        serviceName=<span class="code-quote">"serviceNamespace:CRMServiceProvider"</span>
        endpointName=<span class="code-quote">"serviceNamespace:CRMServicePort"</span>
        implementor=<span class="code-quote">"#CRMServiceBean"</span>
        address=<span class="code-quote">"/CRMServiceProvider"</span>&gt;
        <span class="code-tag">&lt;jaxws:features&gt;</span>
            <span class="code-tag">&lt;p:policies&gt;</span>
                <span class="code-tag">&lt;wsp:PolicyReference URI=<span class="code-quote">"classpath:/saml.policy"</span>/&gt;</span>
            <span class="code-tag">&lt;/p:policies&gt;</span>
        <span class="code-tag">&lt;/jaxws:features&gt;</span>
<span class="code-tag">&lt;/jaxws:endpoint&gt;</span>
</pre>
</div></div>

<h3><a name="UsingWS-PolicyinCXFprojects-Dynamicallyviamessageproperty"></a>Dynamically
via message property</h3>
<p>Sometimes policies cannot be configured statically, because they are obtained or
calculated dynamically for concrete message (for example using Policy Server or Service Registry).
For such cases CXF provide a possibility to load policy dynamically and set it into the message
context property. It can be done for example in custom interceptor that fulfils the following:</p>
<ol>
	<li>Get policy from external location and build it for current message.</li>
	<li>Parse WS-Policy XML using Neethi library.</li>
	<li>Store result Policy object into <em>PolicyConstants.POLICY_OVERRIDE</em>
message content property.<br/>
Important is that this custom policy interceptor is called before CXF <em>PolicyInInterceptor</em>
or <em>PolicyOutInterceptor</em>. Than CXF will automatically recognize Policy
stored into this property and use it with highest priority.</li>
</ol>


<h1><a name="UsingWS-PolicyinCXFprojects-Createcustompolicyassertionsandassociateinterceptors"></a>Create
custom policy assertions and associate interceptors</h1>
<p>It is quite easy to define own policy assertions and associate interceptors with
it. Topic is already well described in CXF document <a href="http://cxf.apache.org/docs/developing-assertions.html"
class="external-link" rel="nofollow">http://cxf.apache.org/docs/developing-assertions.html</a>,
I just provide a list of steps necessary to do:</p>
<ol>
	<li>Provide Assertion Builder class for custom assertion implementing <em>AssertionBuilder&lt;T&gt;</em>
interface.<br/>
Interface type can be <em>Element</em>, <em>XMLStreamReader</em> or
<em>OMElement</em>. <br/>
Interface contains two methods: <em>build()</em> and <em>getKnownElements()</em>.
<br/>
Implementation of <em>build()</em> method should construct Assertion from the
incoming type. It can be <em>PrimitiveAssertion</em> (without attributes or child
elements), NestedPrimitiveAssertion  (without attributes but with nested policy element) and
<em>JaxbAssertion</em> (assertion described by any XML schema).<br/>
<em>getKnownElements()</em> method must return  QNames of assertion elements from
which assertion can be built.</li>
	<li>Implement policy interceptor provider class extending <em>AbstractPolicyInterceptorProvider</em>
class.  The main task of policy interceptor provider is to say which interceptors must be
activated for specified policy assertion. Policy interceptor provider constructor gives assertions
QNames as argument of super constructor and adds corresponded interceptors using getters:</li>
</ol>


<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
<span class="code-keyword">public</span> class AuthorizationInterceptorProvider
<span class="code-keyword">extends</span> AbstractPolicyInterceptorProvider {
    <span class="code-keyword">private</span> <span class="code-keyword">static</span>
<span class="code-keyword">final</span> <span class="code-object">long</span>
serialVersionUID = -5248428637449096540L;
    <span class="code-keyword">private</span> <span class="code-keyword">static</span>
<span class="code-keyword">final</span> AuthorizationInInterceptor IN_AUTHZ_INTERCEPTOR
= <span class="code-keyword">new</span> AuthorizationInInterceptor();
    <span class="code-keyword">private</span> <span class="code-keyword">static</span>
<span class="code-keyword">final</span> AuthorizationInInterceptor OUT_AUTHZ_INTERCEPTOR
= <span class="code-keyword">new</span> AuthorizationOutInterceptor();
    
    <span class="code-keyword">private</span> <span class="code-keyword">static</span>
<span class="code-keyword">final</span> Collection&lt;QName&gt; ASSERTION_TYPES;
    <span class="code-keyword">static</span> {
        ASSERTION_TYPES = <span class="code-keyword">new</span> ArrayList&lt;QName&gt;();
        ASSERTION_TYPES.add(AuthorizationConstants.AUTHORIZATION_ASSERTION);
    }

    <span class="code-keyword">public</span> AuthorizationInterceptorProvider()
{
        <span class="code-keyword">super</span>(ASSERTION_TYPES);
        getInInterceptors().add(IN_AUTHZ_INTERCEPTOR);        
        getOutInterceptors().add(OUT_AUTHZ_INTERCEPTOR);        
    }
}
</pre>
</div></div>
<p>Assertion builder and policy interceptor provider can be registered using CXF bus
extension mechanism: just create a file META-INF/cxf/bus-extensions.txt containing the following:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
org.company.AuthorizationInterceptorProvider::<span class="code-keyword">true</span>
org.company.AuthorizationAssertionBuilder::<span class="code-keyword">true</span>
</pre>
</div></div>
<p>Boolean value at the end specifies lazy loading strategy. <br/>
CXF automatically recognizes the assertion builder and policy interceptor provider and store
them into registries: <em>AssertionBuilderRegistry</em> and <em>PolicyInterceptorProviderRegistry</em>.
Since CXF 2.6.0 it is possible to register multiple interceptor providers for single assertion.</p>

<h1><a name="UsingWS-PolicyinCXFprojects-HowandwhereCXFprocessespolicies"></a>How
and where CXF processes policies</h1>
<p>As I already mentioned, CXF provides two interceptors:  org.apache.cxf.ws.policy.PolicyInInterceptor
and org.apache.cxf.ws.policy.PolicyOutInterceptor. These interceptors are responsible to load
policy from destination, parse, merge them and add all associated interceptors into message
interceptor chain. Functionality of policy interceptors are represented on the following figure:<br/>
<span class="image-wrap" style=""><img src="/confluence/download/attachments/27838786/cxf-ws-policies.jpg?version=1&amp;modificationDate=1329751694691"
style="border: 0px solid black" /></span></p>

<p>Briefly, policy interceptors make following steps:</p>
<ol>
	<li>Check message property <em>PolicyConstants.POLICY_OVERRIDE</em>.</li>
	<li>If <em>PolicyConstants.POLICY_OVERRIDE</em> contains policy, it will
be taken for further processing.</li>
	<li>If property is empty, policy will be asked from ServiceModel. Here CXF loads policies
attached to WSDL or provided via Spring configuration.</li>
	<li>If any policy on step 2 or step 3 is found, <em>EffectivePolicy</em>
will be created. Appropriate WS-policies will be merged for the current message and built
into Neethi <em>Policy</em> object.</li>
	<li>All interceptors registered for result policy assertions will be added to message
interceptor chain.</li>
</ol>


<p>Additionally, CXF verifies satisfied policy assertions in <em>PolicyVerfificationInInterceptor</em>,
<em>PolicyVerificationInFaultInterceptor</em>, <em>PolicyVerificationOutInterceptor</em>.
 If assertion is not processed and not satisfied in corresponded interceptor, than In- interceptors
throw Fault and Out- interceptors provide appropriate log messages.<br/>
The practical using of WS-Policy is illustrated in ws_policy and ws_security CXF samples.</p>
    </div>
        <div id="commentsSection" class="wiki-content pageSection">
        <div style="float: right;">
            <a href="https://cwiki.apache.org/confluence/users/viewnotifications.action"
class="grey">Change Notification Preferences</a>
        </div>
        <a href="https://cwiki.apache.org/confluence/display/CXF/Using+WS-Policy+in+CXF+projects">View
Online</a>
        |
        <a href="https://cwiki.apache.org/confluence/pages/diffpagesbyversion.action?pageId=27838786&revisedVersion=7&originalVersion=6">View
Changes</a>
                |
        <a href="https://cwiki.apache.org/confluence/display/CXF/Using+WS-Policy+in+CXF+projects?showComments=true&amp;showCommentArea=true#addcomment">Add
Comment</a>
            </div>
</div>
</div>
</div>
</div>
</body>
</html>

Mime
View raw message