{"id":702,"date":"2005-01-28T01:09:00","date_gmt":"2005-01-28T10:09:00","guid":{"rendered":"http:\/\/www.cloudidentity.com\/blog\/2005\/01\/29\/policyexecutionstage-or-the-seasons-of-a-ws-policy-assertion\/"},"modified":"2013-03-16T11:41:56","modified_gmt":"2013-03-16T20:41:56","slug":"policyexecutionstage-or-the-seasons-of-a-ws-policy-assertion","status":"publish","type":"post","link":"https:\/\/www.cloudidentity.com\/blog\/2005\/01\/28\/policyexecutionstage-or-the-seasons-of-a-ws-policy-assertion\/","title":{"rendered":"PolicyExecutionStage, or the seasons of a ws-policy assertion"},"content":{"rendered":"<p><P>Today I discovered that apparently the <A href=\"http:\/\/msdn.microsoft.com\/library\/default.asp?url=\/library\/en-us\/wseref\/html\/T_Microsoft_Web_Services2_Policy_PolicyExecutionStage.asp\">Microsoft.Web.Services2.Policy.PolicyExecutionStage<\/A> type lives behind some sort of event horizon: no mention of it on the net (nor the use-net), if you exclude the <A href=\"http:\/\/msdn.microsoft.com\/library\/default.asp?url=\/library\/en-us\/wseref\/html\/T_Microsoft_Web_Services2_Policy_PolicyExecutionStage.asp\">usual msnd entry<\/A>. Yet it&#8217;s a very useful compass while you implement custom policy assertions, so I&#8217;m going to tell you what it is about. The following comes from observation of the WSE behaviour while handling a custom assertion.<BR>I&#8217;m not going in big details here, WSE documentation,&nbsp;quickstarts&nbsp;and good articles around supply excellent coverage of the syntactic sugar; however I need to contextualize the following, so I have to set up the stage: but promise me you&#8217;ll go check serious sources later.<BR>A custom assertion is simply a class deriving from <FONT face=\"Courier New\">PolicyAssertion<\/FONT>. Among other things, there are two methods you want to override:<\/P><br \/>\n<UL><br \/>\n<LI><FONT face=\"Courier New\">bool IsSatisfiedBy(SoapEnvelope message)<\/FONT><BR>That goes without saying. You check the message, you decide if it&#8217;s a go or a no-go.<\/LI><br \/>\n<LI><FONT face=\"Courier New\">bool CanEnforce(ref IPolicyEnforcer enforcer)<\/FONT><BR>This one is trickier. Your code here must decide if it can do something to make a message comply to the policy: if it is the case, it should then assign the enforcer with a suitable enforcer instance (more about it below). A policy can be enforced only on the sending side, and that&#8217;s only reasonable: what is less advertised is that if you are not on the sending side the policy framework seems to <EM>avoid calling the method at all<\/EM>.<\/LI><br \/>\n<LI>the constructor<BR>I know, I said TWO. I forgot the costructor:&nbsp;there&#8217;s where&nbsp;you parse the XML fragment representing your assertion.<\/LI><\/UL><br \/>\n<P>An enforcer is simply a class implementing <FONT face=\"Courier New\">IPolicyEnforcer<\/FONT>: an hymn to the saying &#8220;simple but effective&#8221;, the interface exhibit a single member: <\/P><br \/>\n<UL><br \/>\n<LI><FONT face=\"Courier New\">void Enforce(SoapEnvelope message)<\/FONT><BR>This method is responsible for mangling in the message the directives imposed by the specific policy. Can very well implemented by the assertion class itself, as demonstrated by the WSE quickstart sample.<\/LI><\/UL><br \/>\n<P>Now,&nbsp;a reasonable&nbsp;sequence with which the above are invoked looks pretty much like that:<\/P><br \/>\n<OL><br \/>\n<LI>Constructor &#8211; At the first web service call, parse the policyCache.config hence call the constructor of every assertion (including yours)<\/LI><br \/>\n<LI><FONT face=\"Courier New\">CanEnforce<\/FONT> &#8211; but only if you are on&nbsp;a sending side (you are a client sending a request, or a service sending a response). The info will come handy at the next step<\/LI><br \/>\n<LI><FONT face=\"Courier New\">IsSatisfiedBy<\/FONT> &#8211; the moment of the truth. If you are on the receiving end, returning a false will always storm the place (i.e.: throw an exception); if you are a sender and you answered true to the question CanEnforce, you will proceed to the next step.<\/LI><br \/>\n<LI><FONT face=\"Courier New\">Enforce<\/FONT> &#8211; here you do your best to weave your stuff in the envelope. If you succeed the message will go on to the next assertion (and you don&#8217;t know what the next one is, though the probability that is the next one in the declaration order is very very high)<\/LI><\/OL><br \/>\n<P>Fairly simple model, very usable: great object model, good work. So far, however, it&#8217;s not clear how a custom implementation may tell if a method is executing on the sending or the receiving sides: there are situations in which such a knowledge may come useful. Let&#8217;s forget about the constructor, and let&#8217;s consider all other methods:<\/P><br \/>\n<UL><br \/>\n<LI><FONT face=\"Courier New\">CanEnforce<\/FONT> &#8211; easy. If it gets called, we are on sending side. On the receiving side, no check.<\/LI><br \/>\n<LI><FONT face=\"Courier New\">Enforce<\/FONT> &#8211; Same here.<\/LI><br \/>\n<LI><FONT face=\"Courier New\">IsSatisfiedBy<\/FONT>&#8211; hmmmmmmmmmmm&#8230;&#8230;&#8230;&#8230;&nbsp;<\/LI><\/UL><br \/>\n<P>OK, I&#8217;ll get to the point. The stages through which policy processing goes through are formalized in a static variable of type <FONT face=\"Courier New\">PolicyExecutionStage<\/FONT>, which you can find under the current policy context: <FONT face=\"Courier New\">PolicyContext.Current.Stage<\/FONT>.<BR><FONT face=\"Courier New\">PolicyExecutionStage<\/FONT> is an enum of four values:<\/P><br \/>\n<UL><br \/>\n<LI><STRONG>Parsing<\/STRONG> &#8211; policy is being parsed from the file<\/LI><br \/>\n<LI><STRONG>Compilation<\/STRONG> &#8211; policy is being compiled in its memory format<\/LI><br \/>\n<LI><STRONG>Enforcement<\/STRONG> &#8211; the message is being modified in order to make it compliant<\/LI><br \/>\n<LI><STRONG>Verification<\/STRONG> &#8211; the message is being checked for compliance<\/LI><\/UL><br \/>\n<P>For eliminating the ambiguity of the <FONT face=\"Courier New\">IsSatisfiedBy<\/FONT> execution environment I&#8217;ve added a trace inside every custom assertion method, displaying the state in which they were executing; and I applied my custom assertion to request and response on both the client and the web service.<BR>The result is that <FONT face=\"Courier New\">IsSatisfiedBy<\/FONT> runs in the <STRONG>Compilation<\/STRONG> stage when on a sending side, while it is in <STRONG>Verification<\/STRONG> stage when it is running on a receiving end. Below my traditional OneNote snapshot.<\/P><br \/>\n<P><IMG alt=\"CustomAssertionStages\" src=\"http:\/\/www.maseghepensu.it\/oldblogrecovery\/CustomAssertionStages.jpg\"> <\/P><\/p>\n<div style=\"clear:both\"><\/div>\n","protected":false},"excerpt":{"rendered":"<p>Today I discovered that apparently the Microsoft.Web.Services2.Policy.PolicyExecutionStage type lives behind some sort of event horizon: no mention of it on the net (nor the use-net), if you exclude the usual msnd entry. Yet it&#8217;s a very useful compass while you implement custom policy assertions, so I&#8217;m going to tell you what it is&#8230;<\/p>\n","protected":false},"author":1,"featured_media":1500,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_kad_post_transparent":"","_kad_post_title":"","_kad_post_layout":"","_kad_post_sidebar_id":"","_kad_post_content_style":"","_kad_post_vertical_padding":"","_kad_post_feature":"","_kad_post_feature_position":"","_kad_post_header":false,"_kad_post_footer":false,"footnotes":""},"categories":[61],"tags":[],"class_list":["post-702","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-architecture-ws"],"_links":{"self":[{"href":"https:\/\/www.cloudidentity.com\/blog\/wp-json\/wp\/v2\/posts\/702","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.cloudidentity.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.cloudidentity.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.cloudidentity.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.cloudidentity.com\/blog\/wp-json\/wp\/v2\/comments?post=702"}],"version-history":[{"count":1,"href":"https:\/\/www.cloudidentity.com\/blog\/wp-json\/wp\/v2\/posts\/702\/revisions"}],"predecessor-version":[{"id":1884,"href":"https:\/\/www.cloudidentity.com\/blog\/wp-json\/wp\/v2\/posts\/702\/revisions\/1884"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.cloudidentity.com\/blog\/wp-json\/wp\/v2\/media\/1500"}],"wp:attachment":[{"href":"https:\/\/www.cloudidentity.com\/blog\/wp-json\/wp\/v2\/media?parent=702"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.cloudidentity.com\/blog\/wp-json\/wp\/v2\/categories?post=702"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.cloudidentity.com\/blog\/wp-json\/wp\/v2\/tags?post=702"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}