Return-Path: Delivered-To: apmail-cxf-dev-archive@www.apache.org Received: (qmail 31460 invoked from network); 8 Oct 2008 21:18:08 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.2) by minotaur.apache.org with SMTP; 8 Oct 2008 21:18:08 -0000 Received: (qmail 61222 invoked by uid 500); 8 Oct 2008 21:18:07 -0000 Delivered-To: apmail-cxf-dev-archive@cxf.apache.org Received: (qmail 61170 invoked by uid 500); 8 Oct 2008 21:18:06 -0000 Mailing-List: contact dev-help@cxf.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@cxf.apache.org Delivered-To: mailing list dev@cxf.apache.org Received: (qmail 61159 invoked by uid 500); 8 Oct 2008 21:18:06 -0000 Delivered-To: apmail-incubator-cxf-dev@incubator.apache.org Received: (qmail 61156 invoked by uid 99); 8 Oct 2008 21:18:06 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 08 Oct 2008 14:18:06 -0700 X-ASF-Spam-Status: No, hits=0.1 required=10.0 tests=DNS_FROM_SECURITYSAGE,SPF_HELO_PASS,SPF_PASS X-Spam-Check-By: apache.org Received-SPF: pass (athena.apache.org: domain of sergey.beryozkin@iona.com designates 12.170.54.180 as permitted sender) Received: from [12.170.54.180] (HELO amer-mx1.iona.com) (12.170.54.180) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 08 Oct 2008 21:17:04 +0000 X-IronPort-AV: E=Sophos;i="4.33,380,1220241600"; d="scan'208";a="15534872" Received: from amer-ems1.ionaglobal.com ([10.65.6.25]) by amer-mx1.iona.com with ESMTP; 08 Oct 2008 17:16:38 -0400 Received: from sergeyD820 ([10.59.0.20]) by amer-ems1.IONAGLOBAL.COM with Microsoft SMTPSVC(6.0.3790.1830); Wed, 8 Oct 2008 17:16:36 -0400 From: "Sergey Beryozkin" To: , Subject: RE: More on server response policies Date: Wed, 8 Oct 2008 22:16:33 +0100 MIME-Version: 1.0 X-Mailer: Microsoft Office Outlook, Build 11.0.5510 In-Reply-To: <0EF8EE34-0EFF-488F-8611-476C8BE21817@dushin.net> X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.2962 Thread-Index: AckpZ9nYiV+yLVSTRSePYSctWX3U0wAEuegg Message-ID: X-OriginalArrivalTime: 08 Oct 2008 21:16:38.0420 (UTC) FILETIME=[26C1D540:01C9298B] Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="us-ascii" X-Virus-Checked: Checked by ClamAV on apache.org Hi I agree with what Dan suggested - logging a message in a PolicyVerificationOutInterceptor should suffice in most cases. Few more comments. I think that asserting a policy on the outbound path makes sense only if a specification for a given policy expression explicitly states that it applies to both inbound and outbound paths or to outbound path only. If a given policy expression specifies a behavior which is only engaged on the inbound path then there's no need to verify that it indeed was engaged on the outbound path. And vice versa. Ex1. A policy expression is attached to a wsdl:service/wsdl:port. Only this policy's interceptors know when to get involved and assert a policy - either on the inbound only, outbound only or both. This policy applies to all operations. Ex2. A policy expression is attached to a wsdl:binding/wsdl:operation/wsdl:output. When a given operation is executed this policy assertion is only executed on the outbound path - hence no sence to verify it on the inbound path. Ex 3 : policy is attached to wsdl:binding/wsdl:operation/wsdl:input I'll comment a bit more on these examples later. Now, as Dan said, on the server inbound path, a union of all policy expressions is selected as at any moment of time we may need to satisfy requests from clients meeting either all or one of the available alternatives. All required interceptors are installed - but the api allows for on-demand interceptors installation (for ex, based in the in message's content & headers). AFAIK, PolicyVerificationInInterceptor would say OK as long as at least one of the alternatives is fully satisfied. In your example we have a compact policy expression, so there'no problems if either or has been asserted. On the outbound path only the alternative which has been selected during the inbound path should be optionally verified. I don't think any alternative selection algorithm should apply on the outbound path as we already have an alternative active in the scope of a given operation. If we have the Ex2 (above) then this alternative will simply have no any inbound behaviors to engage (see more below). In Ex1 - it's up to that specific policy's out interceptors to do any additional outbound work. Thus, in many cases, like in Ex1, if no explicit out policy interceptors have been provided then PolicyVerificationOutInterceptor should simply log a (FINE?) level message as suggested. In fact it's not clear what else it can do other than do this logging on the server side. While (on the server side) PolicyVerificationInInterceptor is useful in that it ensures that at least one alternative has been met, its out counterpart is of little use. Unless we provide some hints. We can introduce additional optional hints (in the form of policy attributes) to both in/out verifiers that this policy only applies to the in or out path or to both paths. Thus, in case of Ex2, In verifier won't fail but Out verifier can log a WARNING (or throw a fault if its phase can be changed). Likewise, in Ex3, In verifier may throw exception while OUT verifier will keep quiet. In case of Ex1, both in/out verifiers may report failures (through exceptions or logging). Without such helper attributes the default (server) behavior should likely be : - PolicyVerificationInInterceptor throws fault if none of the alternatives has been met (as it is now) - PolicyVerificationOutInterceptor logs a FINE message if not all of the expressions in the alternative selected during the inbound invocation has been met. If we have a policy-aware client runtime on the other end then it will also do its own verification. There're some differences in how things are handled in the policy aware client runtime but we can discuss it in the other thread... Cheers, Sergey -----Original Message----- From: Fred Dushin [mailto:fred@dushin.net] Sent: 08 October 2008 18:02 To: cxf-dev@incubator.apache.org Subject: More on server response policies This is a continuation of the discussion at http://mail-archives.apache.org/mod_mbox/cxf-dev/200808.mbox/%3c3AAFD5B7-693 A-4FDB-AA50-15696098F98C@dushin.net%3e I've confirmed that this is still an issue in 2.2-SNAPSHOT, and I'd like to start a discussion of solutions. I'll start by describing the policy framework architecture, as I understand it, but I'll focus on the server-side of a CXF request and response, when policy is involved. This should give enough context to form a discussion of how to proceed. Generally, the way the CXF policy framework works is as follows (please chime in if I've gotten any details wrong). When the policy framework is loaded, at least 2 interceptors are installed on the interceptor chain (and again, let's just focus, for the time being, on the inbound server request and outbound server response): * ServerPolicy(In|Out)Interceptor * PolicyVerification(In|Out)Interceptor The role of the ServerPolicy*Interceptors are to: 1. Establish the "effective" policy for the request/response, based off a collection of policy sources (WSDL, Spring, etc) 2. Select a set of policy assertion alternatives, using an alternative selector (defined essentially at Bus granularity) 3. Construct an AssertionInfoMap, which is basically just a map from the policy assertion QNames out of the list of selected assertions to the selected assertions, themselves. Think of it as a multimap. Once constructed, the AssertionInfoMap placed on the message, for subsequent interceptors to inspect and/or mutate. The role of the PolicyVerification*Interceptor is to compare the asserted policies against the effective policies, and to compute whether the effective policy has been satisfied by the collection of asserted policies. If the effective policy is so satisfiable, then the request is allowed to proceed; otherwise, a fault is raised (and I see that in 2.2, Dan has added some nice helpful information about why). (A bug has been identified [1] in the case of faults thrown in the PolicyVerificationOutInterceptor.) (Between these interceptors, applications (like a WS-* provider) are expected to inspect and/or mutate the AssertionInfo objects in the AssertionInfoMap, to indicate that a particular policy assertion has been satisfied in the runtime.) Now, the server-side request and response processing is slightly asymmetric, in the following respects: A. When processing an inbound request, the intervening interceptors are sandwiched by a ServerPolicyInInterceptor and a PolicyVerificationInInterceptor, whereas the outbound response interceptor chain is sandwiched by a ServerPolicyOutInterceptor and a PolicyVerificationOutInterceptor B. The AssertionInfoMap, and the association policy assertion instances contained in them, are different instances on the inbound request and outbound response chains. In particular, any policy assertion instances that are "checked off" on the inbound request side must also be checked off on the outbound response side. C. The policy alternative selection algorithm (the AlternativeSelector) is different on the inbound request and outbound response sides. In particular, on the inbound request side, all possible alternatives are selected, whereas on the outbound response side, the default AlternativeSelector (the MinimalAlternativeSelector) on the PolicyEngine is used, which generally picks one alternative from a collection possibilities. As a consequence, not only are the AssertionInfo instances on the response AssertionInfoMap different from those on the request (B above), but the structure of the AssertionInfoMap itself is different. The combination of B and C actually conspires to yield another, more serious bug. Consider the following effective policy: On the inbound request, the key set of the AssertionInfoMap will contain the QNames: [{foo}Bar, {gnu:Gnat}] whereas the key set of the AssertionInfoMap on the outbound response will contain just the QName (say): [{foo}Bar] Now let's say a client sends a request that satisfies . The effective policy will have been satisfied on the inbound request; however, on the outbound response, it will not. The result is a fault raised in the PolicyVerificationOutInterceptor, though by [1], this can easily go undetected. So, what are the solutions? [bad] One workaround is to set the AlternativeSelector on the PolicyEngine to be something like the UnionAlternativeSelector that's used on the inbound request side. That way, the AssertionInfoMap on the outbound response will contain all the "right" QNames, and the effective policy will be reported as being satisfied. One reason this is bad is that the PolicyEngine is global wrt the Bus, so this sort of change to the engine would have all sorts of nasty unintended side- effects. Perhaps a better level of granularity would work, where you could specify a specific policy alternative selector on a per- interceptor-chain basis, which would mitigate the badness, a bit. [marginally better] Copy the asserted AssertionInfo objects that have been satisfied on the inbound request to the outbound response. The assertions have already been checked off. Why should we need to do this again on the outbound response? That still won't actually solve the bug I've identified here, but it might still be a good thing to do, nonetheless. [better] Discriminate between inbound and outbound policies, and the level of configuration. That way, the user can say, "here are the inbound policies I expect/require to be satisfied on the inbound side, and here are the policies for the outbound side". The problem with this is that it would probably only really work when specifying policies through Spring, since I don't think there's a way to specify this sort of distinction in WSDL, or whatever other policy retrieval mechanisms we support. [not sure, but I think it's my choice] Do away with the policy interceptors on the outbound server response, all together. Seriously, why do we need these? What's the use-case? The only think I can think of is something like "encrypting the response", or something like that. However, I'm not sure there is a standard policy that expresses this. There might be application-specific policies that have this need, but I can't really picture them. Thoughts on a solution? -Fred [1] https://issues.apache.org/jira/browse/CXF-1849 ---------------------------- IONA Technologies PLC (registered in Ireland) Registered Number: 171387 Registered Address: The IONA Building, Shelbourne Road, Dublin 4, Ireland