<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:atom="https://www.w3.org/2005/Atom" xmlns:sy="https://purl.org/rss/1.0/modules/syndication/" xmlns:dc="https://purl.org/dc/elements/1.1/" xmlns:content="https://purl.org/rss/1.0/modules/content/" xmlns:wfw="https://wellformedweb.org/CommentAPI/" xmlns:slash="https://purl.org/rss/1.0/modules/slash/"
  version="2.0">
  <channel>
    <title>Phil Henning's WebLog</title>
    <atom:link
      href="https://docs.microsoft.com/archive/blogs/phenning/feed.xml"
      rel="self"
      type="application/rss+xml" />
    <link>https://docs.microsoft.com/archive/blogs/phenning/feed.xml</link>
    <description />
    <lastBuildDate>Tue, 16 Apr 2019 05:24:15 GMT</lastBuildDate>
    <language>en-US</language>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>Silverlight Web Services Team Blog</title>
      <link>https://docs.microsoft.com/archive/blogs/phenning/silverlight-web-services-team-blog</link>
      <pubDate>Fri, 07 Mar 2008 13:58:00 GMT</pubDate>
      <dc:creator><![CDATA[Phil Henning]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/phenning/2008/03/07/silverlight-web-services-team-blog/</guid>
      <description><![CDATA[For those interested in WCF development on Silverlight, the Silverlight Web Services team just set...]]></description>
      <content:encoded><![CDATA[For those interested in WCF development on Silverlight, the Silverlight Web Services team just set up a <A class="" href="https://blogs.msdn.com/silverlightws" mce_href="https://blogs.msdn.com/silverlightws">team blog</A>.]]></content:encoded>
    </item>
    <item>
      <title>Custom transport channels and BindingElements</title>
      <link>https://docs.microsoft.com/archive/blogs/phenning/custom-transport-channels-and-bindingelements</link>
      <pubDate>Mon, 14 Jan 2008 11:00:00 GMT</pubDate>
      <dc:creator><![CDATA[Phil Henning]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/phenning/2008/01/14/custom-transport-channels-and-bindingelements/</guid>
      <description><![CDATA[When&nbsp;creating a custom transport channel, you must be sure to remove the&nbsp;encoding binding...]]></description>
      <content:encoded><![CDATA[<P class=MsoNormal style="MARGIN: 0in 0in 0pt"><SPAN style="FONT-SIZE: 11pt; COLOR: #1f497d; FONT-FAMILY: 'Calibri','sans-serif'; mso-ascii-theme-font: minor-latin; mso-hansi-theme-font: minor-latin; mso-bidi-font-family: 'Times New Roman'; mso-bidi-theme-font: minor-bidi; mso-themecolor: dark2">When&nbsp;creating a custom transport channel, you must be sure to remove the&nbsp;encoding binding element from the binding context before&nbsp;returning from your BuildChannelFactory and BuildChannelListener calls. The best place to do this is within the constructor for your transport channel factory or listener.</SPAN></P><!-- code formatted by https://manoli.net/csharpformat/ --><PRE class=csharpcode>MessageEncodingBindingElement encodingBindingElement = context.BindingParameters.Remove&lt;MessageEncodingBindingElement&gt;();</PRE>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt"><SPAN style="FONT-SIZE: 11pt; COLOR: #1f497d; FONT-FAMILY: 'Calibri','sans-serif'; mso-ascii-theme-font: minor-latin; mso-hansi-theme-font: minor-latin; mso-bidi-font-family: 'Times New Roman'; mso-bidi-theme-font: minor-bidi; mso-themecolor: dark2">Its needs to be removed because there is a validation step that is performed after the channel stack has been fully created. If there are binding elements left in the stack, an InvalidOperaionException will be thrown from Binding.BuildChannelFactory or Binding.BuildChannelListener.<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt"><SPAN style="FONT-SIZE: 11pt; COLOR: #1f497d; FONT-FAMILY: 'Calibri','sans-serif'; mso-ascii-theme-font: minor-latin; mso-hansi-theme-font: minor-latin; mso-bidi-font-family: 'Times New Roman'; mso-bidi-theme-font: minor-bidi; mso-themecolor: dark2"><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt"><SPAN style="FONT-SIZE: 11pt; COLOR: #1f497d; FONT-FAMILY: 'Calibri','sans-serif'; mso-ascii-theme-font: minor-latin; mso-hansi-theme-font: minor-latin; mso-bidi-font-family: 'Times New Roman'; mso-bidi-theme-font: minor-bidi; mso-themecolor: dark2">Also, be aware if you are building a custom encoder; be sure to add your MessageEncodingBindingElement back to the BindingContext before returning from your BuildChannelListener/BuildChannelFactory methods of your MessageEncodingBindingElement back so that the transport is able to create your encoder.&nbsp;</SPAN></P><!-- code formatted by https://manoli.net/csharpformat/ --><PRE class=csharpcode>context.BindingParameters.Add(<SPAN class=kwrd>this</SPAN>); </PRE>]]></content:encoded>
    </item>
    <item>
      <title>Custom UserNamePassword Validators in .Net Framework 3.5</title>
      <link>https://docs.microsoft.com/archive/blogs/phenning/custom-usernamepassword-validators-in-net-framework-3-5</link>
      <pubDate>Fri, 11 Jan 2008 16:29:00 GMT</pubDate>
      <dc:creator><![CDATA[Phil Henning]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/phenning/2008/01/11/custom-usernamepassword-validators-in-net-framework-3-5/</guid>
      <description><![CDATA[In the version of WCF that shipped with .Net Framework 3.0 we didn't support custom validators with...]]></description>
      <content:encoded><![CDATA[<P>In the version of WCF that shipped with .Net Framework 3.0 we didn't support custom validators with transport level HTTP security. We received much feedback from the community that this was a highly desired feature, so I'm happy to say we added support for this scenario in the 3.5 release of the .Net Framework. </P>
<P>Note that this is only supported under self hosted services. </P>
<P>Here is what you'll need to do to get it to work: </P>
<P>1. Create your validator: </P><!-- code formatted by https://manoli.net/csharpformat/ --><PRE class=csharpcode><SPAN class=kwrd>namespace</SPAN> Sample
{
   <SPAN class=kwrd>using</SPAN> System.ServiceModel;
   <SPAN class=kwrd>using</SPAN> System.IdentityModel.Selectors;
   <SPAN class=kwrd>using</SPAN> System.ServiceModel.Security;

   <SPAN class=kwrd>public</SPAN> <SPAN class=kwrd>class</SPAN> CustomUserNameValidator : UserNamePasswordValidator
   {
       <SPAN class=rem>// This method validates users. It allows in two users, test1 and test2 </SPAN>
       <SPAN class=rem>// with passwords 1tset and 2tset respectively.</SPAN>
       <SPAN class=rem>// This code is for illustration purposes only and </SPAN>
       <SPAN class=rem>// must not be used in a production environment because it is not secure. </SPAN>
       <SPAN class=kwrd>public</SPAN> <SPAN class=kwrd>override</SPAN> <SPAN class=kwrd>void</SPAN> Validate(<SPAN class=kwrd>string</SPAN> userName, <SPAN class=kwrd>string</SPAN> password)
       {
           <SPAN class=kwrd>if</SPAN> (<SPAN class=kwrd>null</SPAN> == userName || <SPAN class=kwrd>null</SPAN> == password)
           {         
               <SPAN class=kwrd>throw</SPAN> <SPAN class=kwrd>new</SPAN> ArgumentNullException();
           }

           <SPAN class=kwrd>if</SPAN> (!(userName == <SPAN class=str>"test1"</SPAN> &amp;&amp; password == <SPAN class=str>"1tset"</SPAN>) &amp;&amp; !(userName == <SPAN class=str>"test2"</SPAN> &amp;&amp; password == <SPAN class=str>"2tset"</SPAN>))
           {
               <SPAN class=kwrd>throw</SPAN> <SPAN class=kwrd>new</SPAN> SecurityTokenException(<SPAN class=str>"Unknown Username or Incorrect Password"</SPAN>);
           }
      }
   }
}

</PRE>
<P>&nbsp;2. Configure your service; you'll want to use Transport security and Basic clientCredentialType, this way the authentication header will be protected by SSL. </P>
<P>Configuration for the binding and behavior: </P><!-- code formatted by https://manoli.net/csharpformat/ --><PRE class=csharpcode><SPAN class=kwrd>&lt;</SPAN><SPAN class=html>bindings</SPAN><SPAN class=kwrd>&gt;</SPAN>
 <SPAN class=kwrd>&lt;</SPAN><SPAN class=html>wsHttpBinding</SPAN><SPAN class=kwrd>&gt;</SPAN>
  <SPAN class=kwrd>&lt;</SPAN><SPAN class=html>binding</SPAN> <SPAN class=attr>name</SPAN><SPAN class=kwrd>="BasicAuthentication"</SPAN><SPAN class=kwrd>&gt;</SPAN>
   <SPAN class=kwrd>&lt;</SPAN><SPAN class=html>security</SPAN> <SPAN class=attr>mode</SPAN><SPAN class=kwrd>="Transport"</SPAN><SPAN class=kwrd>&gt;</SPAN>
    <SPAN class=kwrd>&lt;</SPAN><SPAN class=html>transport</SPAN> <SPAN class=attr>clientCredentialType</SPAN><SPAN class=kwrd>="Basic"</SPAN> <SPAN class=kwrd>/&gt;</SPAN>
   <SPAN class=kwrd>&lt;/</SPAN><SPAN class=html>security</SPAN><SPAN class=kwrd>&gt;</SPAN>
  <SPAN class=kwrd>&lt;/</SPAN><SPAN class=html>binding</SPAN><SPAN class=kwrd>&gt;</SPAN>
 <SPAN class=kwrd>&lt;/</SPAN><SPAN class=html>wsHttpBinding</SPAN><SPAN class=kwrd>&gt;</SPAN>
<SPAN class=kwrd>&lt;/</SPAN><SPAN class=html>bindings</SPAN><SPAN class=kwrd>&gt;</SPAN>


<SPAN class=kwrd>&lt;</SPAN><SPAN class=html>behaviors</SPAN><SPAN class=kwrd>&gt;</SPAN>
 <SPAN class=kwrd>&lt;</SPAN><SPAN class=html>serviceBehaviors</SPAN><SPAN class=kwrd>&gt;</SPAN>
  <SPAN class=kwrd>&lt;</SPAN><SPAN class=html>behavior</SPAN> <SPAN class=attr>name</SPAN><SPAN class=kwrd>="CustomUserNamePassword"</SPAN><SPAN class=kwrd>&gt;</SPAN>
   <SPAN class=kwrd>&lt;</SPAN><SPAN class=html>serviceCredentials</SPAN><SPAN class=kwrd>&gt;</SPAN>
    <SPAN class=kwrd>&lt;</SPAN><SPAN class=html>userNameAuthentication</SPAN> 
     <SPAN class=attr>userNamePasswordValidationMode</SPAN><SPAN class=kwrd>="Custom"</SPAN> 
     <SPAN class=attr>customUserNamePasswordValidatorType</SPAN><SPAN class=kwrd>="Sample.CustomUserNameValidator, assemblyName"</SPAN><SPAN class=kwrd>/&gt;</SPAN>
   <SPAN class=kwrd>&lt;/</SPAN><SPAN class=html>serviceCredentials</SPAN><SPAN class=kwrd>&gt;</SPAN>
  <SPAN class=kwrd>&lt;/</SPAN><SPAN class=html>behavior</SPAN><SPAN class=kwrd>&gt;</SPAN>
 <SPAN class=kwrd>&lt;/</SPAN><SPAN class=html>serviceBehaviors</SPAN><SPAN class=kwrd>&gt;</SPAN>
<SPAN class=kwrd>&lt;/</SPAN><SPAN class=html>behaviors</SPAN><SPAN class=kwrd>&gt;</SPAN>
</PRE>
<P>You can also add the custom validator through code: </P><!-- code formatted by https://manoli.net/csharpformat/ --><PRE class=csharpcode>host.Credentials.UserNameAuthentication.CustomUserNamePasswordValidator = <SPAN class=kwrd>new</SPAN> CustomUserNameValidator();
host.Credentials.UserNameAuthentication.UserNamePasswordValidationMode = UserNamePasswordValidationMode.Custom;

</PRE>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Courier New"></SPAN>&nbsp;</P>]]></content:encoded>
    </item>
    <item>
      <title>Client IP addresses in Orcas</title>
      <link>https://docs.microsoft.com/archive/blogs/phenning/client-ip-addresses-in-orcas</link>
      <pubDate>Wed, 08 Aug 2007 18:08:00 GMT</pubDate>
      <dc:creator><![CDATA[Phil Henning]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/phenning/2007/08/08/client-ip-addresses-in-orcas/</guid>
      <description><![CDATA[As Nicholas promised, here is&nbsp;some more information about client IP address in Orcas.
In the...]]></description>
      <content:encoded><![CDATA[<P>As Nicholas <A class="" href="https://blogs.msdn.com/drnick/archive/2007/09/10/more-about-client-ip-addresses.aspx" mce_href="https://blogs.msdn.com/drnick/archive/2007/09/10/more-about-client-ip-addresses.aspx">promised</A>, here is&nbsp;some more information about client IP address in Orcas.</P>
<P>In the Orcas release of WCF, we added the ability for services to get the IP address and port of the calling client from your service methods when the underlying transport is Http or Tcp. </P>
<P>You can access the address and port as follows: </P><!-- code formatted by https://manoli.net/csharpformat/ --><PRE class=csharpcode><SPAN class=kwrd>namespace</SPAN> Sample
{
    <SPAN class=kwrd>using</SPAN> System;
    <SPAN class=kwrd>using</SPAN> System.ServiceModel;
    <SPAN class=kwrd>using</SPAN> System.ServiceModel.Channels;
    <SPAN class=kwrd>using</SPAN> System.Net;

    [ServiceContract]
    <SPAN class=kwrd>interface</SPAN> IMyService
    {
        [OperationContract]
        <SPAN class=kwrd>public</SPAN> <SPAN class=kwrd>string</SPAN> ProcessUntyped(Message message);
        [OperationContract]
        <SPAN class=kwrd>public</SPAN> <SPAN class=kwrd>string</SPAN> ProcessTyped(<SPAN class=kwrd>string</SPAN> str);
    }

    <SPAN class=kwrd>class</SPAN> MyService : IMyService
    {
        <SPAN class=kwrd>public</SPAN> <SPAN class=kwrd>string</SPAN> ProcessUntyped(Message message)
        {
            RemoteEndpointMessageProperty endpoint = message.Properties[RemoteEndpointMessageProperty.Name] <SPAN class=kwrd>as</SPAN> RemoteEndpointMessageProperty;
            <SPAN class=kwrd>return</SPAN> <SPAN class=kwrd>string</SPAN>.Format(<SPAN class=str>"Connected from {0}:{1}"</SPAN>, str, endpoint.Address, endpoint.Port);
        }

        <SPAN class=kwrd>public</SPAN> <SPAN class=kwrd>string</SPAN> ProcessTyped(<SPAN class=kwrd>string</SPAN> str)
        {
            OperationContext context = OperationContext.Current;
            MessageProperties properties = context.IncomingMessageProperties;
            RemoteEndpointMessageProperty endpoint = properties[RemoteEndpointMessageProperty.Name] <SPAN class=kwrd>as</SPAN> RemoteEndpointMessageProperty;
            <SPAN class=kwrd>return</SPAN> <SPAN class=kwrd>string</SPAN>.Format(<SPAN class=str>"You said: '{0}'. Connected from {1}:{2}"</SPAN>, str, endpoint.Address, endpoint.Port);
        }
    }
}</PRE>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Courier New"><FONT face=Arial size=2>Note, if you are using the channel model directly, you can just look at Message.IncomingMessageProperties for the RemoteEndpointMessageProperty</FONT></P></SPAN>
<P>If you are developing your own transport channel, you can attach the property to messages received through your transport channel: </P><!-- code formatted by https://manoli.net/csharpformat/ --><PRE class=csharpcode><SPAN class=kwrd>public</SPAN> RemoteEndpointMessageProperty(<SPAN class=kwrd>string</SPAN> address, <SPAN class=kwrd>int</SPAN> port); </PRE>
<P>The address specified must be a non zero-length sting and the port should be from 0-65535. </P>
<P>Some additional things to consider: </P>
<OL>
<LI>The IP address and port are as reported from the underlying socket or http.sys and is from the connected machine, so it may be a proxy address. </LI>
<LI>We don't do any sort of spoof detection, so be careful about using the IP for any sort of security decisions. </LI>
<LI>For all transports other then http and net.tcp the property will not be on the message. </LI>
<LI>If you are using composite duplex, the property will be available on the client on replies from the service. </LI></OL>]]></content:encoded>
    </item>
    <item>
      <title>Accessing the Http Query String from a service method.</title>
      <link>https://docs.microsoft.com/archive/blogs/phenning/accessing-the-http-query-string-from-a-service-method</link>
      <pubDate>Fri, 22 Jun 2007 17:40:00 GMT</pubDate>
      <dc:creator><![CDATA[Phil Henning]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/phenning/2007/06/22/accessing-the-http-query-string-from-a-service-method/</guid>
      <description><![CDATA[I'm trying to access the query string used by the client when contacting my service. How can I do...]]></description>
      <content:encoded><![CDATA[<P><STRONG><EM>I'm trying to access the query string used by the client when contacting my service. How can I do this?</EM></STRONG>&nbsp;<SPAN style="FONT-SIZE: 12pt; FONT-FAMILY: Times New Roman"> </SPAN></P>
<P>You can access the query string through the HttpRequestMessageProperty.</P><!-- code formatted by https://manoli.net/csharpformat/ --><PRE class=csharpcode>OperationContext context = OperationContext.Current;
MessageProperties properties = context.IncomingMessageProperties;

HttpRequestMessageProperty requestProperty = properties[HttpRequestMessageProperty.Name] <SPAN class=kwrd>as</SPAN> HttpRequestMessageProperty;

<SPAN class=kwrd>string</SPAN> queryString = requestProperty.QueryString; 
</PRE>]]></content:encoded>
    </item>
    <item>
      <title>Securing WCF to only respond to local requests.</title>
      <link>https://docs.microsoft.com/archive/blogs/phenning/securing-wcf-to-only-respond-to-local-requests</link>
      <pubDate>Tue, 31 Oct 2006 19:45:00 GMT</pubDate>
      <dc:creator><![CDATA[Phil Henning]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/phenning/2006/10/31/securing-wcf-to-only-respond-to-local-requests/</guid>
      <description><![CDATA[Is it possible to secure a web service to only respond to local requests over HTTP?
Yes, you just...]]></description>
      <content:encoded><![CDATA[<P><EM><STRONG>Is it possible to secure a web service to only respond to local requests over HTTP?</STRONG><BR><BR></EM></P>
<P>Yes, you just need to make sure that you listen at https://127.0.0.1/MyService/ with HostNameComparisonMode = Exact.</P><!-- code formatted by https://manoli.net/csharpformat/ --><PRE class=csharpcode>ServiceHost service = <SPAN class=kwrd>new</SPAN> ServiceHost(<SPAN class=kwrd>typeof</SPAN>(MyService), <SPAN class=kwrd>new</SPAN> Uri(<SPAN class=str>"https://127.0.0.1/MyService/"</SPAN>));
BasicHttpBinding binding = <SPAN class=kwrd>new</SPAN> BasicHttpBinding();
binding.HostNameComparisonMode = HostNameComparisonMode.Exact;
service.AddServiceEndpoint(<SPAN class=kwrd>typeof</SPAN>(IMyService), binding , <SPAN class=str>"BasicEndpoint"</SPAN>);</PRE>
<P mce_keep="true"><FONT size=2>Also, be sure to run httpcfg or netsh http&nbsp;add urlacl with&nbsp;the&nbsp;127.0.0.1 address.&nbsp;&nbsp;<BR></FONT><FONT size=2></P></FONT>]]></content:encoded>
    </item>
    <item>
      <title>Changing BindingElement settings on a Binding.</title>
      <link>https://docs.microsoft.com/archive/blogs/phenning/changing-bindingelement-settings-on-a-binding</link>
      <pubDate>Mon, 15 May 2006 14:03:00 GMT</pubDate>
      <dc:creator><![CDATA[Phil Henning]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/phenning/2006/05/15/changing-bindingelement-settings-on-a-binding/</guid>
      <description><![CDATA[We don’t allow you to modify the properties of the binding directly, but you can create a copy of...]]></description>
      <content:encoded><![CDATA[<BR><SPAN style="mso-bidi-font-size: 11.0pt; mso-ascii-font-family: Calibri; mso-hansi-font-family: Calibri"><FONT size=3><FONT color=#000000><FONT face=Calibri>We don’t allow you to modify the properties of the binding directly, but you can create a copy of the binding elements used to create a particular binding, alter the desired properties, then use the binding element collection to create a new custom binding.<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /><o:p></o:p></FONT></FONT></FONT></SPAN>&nbsp; <!-- code formatted by https://manoli.net/csharpformat/ --><PRE class=csharpcode>BasicHttpBinding basicBinding = <SPAN class=kwrd>new</SPAN> BasicHttpBinding();
BindingElementCollection bindingElementCollection = basicBinding.CreateBindingElements();
bindingElementCollection.Find&lt;HttpTransportBindingElement&gt;().KeepAliveEnabled = <SPAN class=kwrd>false</SPAN>;
CustomBinding myBasicBinding = <SPAN class=kwrd>new</SPAN> CustomBinding(bindingElementCollection);
</PRE></SPAN></SPAN></FONT><PRE></PRE>]]></content:encoded>
    </item>
  </channel>
</rss>