In part 1 I talked about a simple approach to combine WCF Routing service and claims-based security and I got some questions about the sample code and routing service configuration. In this post, I’ll explain some additional scenarios and would provide link to the source code. In my original post I used following very simple routing configuration where the RST (Request Security Token) message goes to the STS and everything else goes to the UserService (a business service)

Simple Routing Configuration
  1. <routing>
  2.   <filterTables>
  3.     <filterTable name="SLRouting">
  4.       <add endpointName="stsEndpoint" filterName="matchRST" priority="5"/>
  5.       <add endpointName="serviceEndpoint" filterName="allMessages" priority="1"/>
  6.     </filterTable>
  7.   </filterTables>
  8.   <filters>
  9.     <filter filterType="Action" filterData="http://docs.oasis-open.org/ws-sx/ws-trust/200512/RST/Issue" name="matchRST"/>
  10.     <filter filterType="MatchAll" name="allMessages"/>
  11.   </filters>
  12. </routing>

 

The STS endpoint uses an action filter (line 4) which looks for a WS-Trust RST message and forwards it to the STS. If RST filter doesn’t match, then the routing engine goes and tries the second filter (line 5) which is a match all. So in my simple configuration all non-RST messages are simply sent to the second endpoint. Real world scenarios obviously would require more granular routing but it can easily be enabled using the same pattern. WCF routing configuration is quite powerful and supports composite (AND, OR etc) and custom filters using which you can model any routing logic as you per your needs.

Another interesting scenarios is to support multiple authentication schemes on the STS – windows authentication for the intranet while userName password for the internet. 

To enables this I have exposed the STS functionality using two different endpoints supporting both username/password based authentication as well as windows authentication. 

/ActiveSTS/issue.svc/IWSTrust13/ActiveSTS/windowsintegrated/issue.svc/IWSTrust13

Because windows authentication is point-point so I relied on impersonation to flow the end-user identity to the STS via the Router. The windows authentication flow looks like this:

image

For the windows-integrated endpoint,  router is configured to impersonate the client and the outgoing messages is sent under this impersonated context which enables the STS to authenticate the original user using windows authentication.

      <serviceBehaviors>        <behavior>          <serviceAuthorization impersonateCallerForAllOperations="true"/>                  </behavior>      </serviceBehaviors>

When deploying in IIS, both the router endpoint and the STS endpoint needs to be configured for windows-authentication and I have accomplished it by creating a sub-folder (windowsintegrated) under both virtual directories and configuring this for windows-authentication. The main/parent virtual directories still has anonymous access enabled for the userName authentication to work. Note with userName authentication,  the credentials goes inside the SOAP message. My VS setup look like this:

image

The web.config(s) under the ‘windowsintegrated’ folder overrides the settings to enable windows-authentication. For example, in the STS project the root web.config defines both service endpoints along with a default binding which is configured for UserName authentication over HTTP.

Root web.config: STS
  1. <system.serviceModel>
  2.   <serviceHostingEnvironment>
  3.     <serviceActivations>
  4.       <add relativeAddress="~/issue.svc" service="CustomSecurityTokenServiceConfiguration"
  5.            factory="Microsoft.IdentityModel.Protocols.WSTrust.WSTrustServiceHostFactory"/>
  6.       
  7.       <add relativeAddress="~/windowsintegrated/issue.svc" service="CustomSecurityTokenServiceConfiguration"
  8.            factory="Microsoft.IdentityModel.Protocols.WSTrust.WSTrustServiceHostFactory"/>
  9.     </serviceActivations>
  10.   </serviceHostingEnvironment>
  11.  
  12.   <services>
  13.     <service name="Microsoft.IdentityModel.Protocols.WSTrust.WSTrustServiceContract">
  14.       <endpoint address="IWSTrust13"
  15.                 binding="customBinding"
  16.                 contract="Microsoft.IdentityModel.Protocols.WSTrust.IWSTrust13SyncContract"/>
  17.     </service>
  18.   </services>
  19.  
  20.   <bindings>
  21.     <customBinding>
  22.       <binding>
  23.         <security authenticationMode="UserNameOverTransport" allowInsecureTransport="true"/>
  24.         <httpTransport/>
  25.       </binding>
  26.     </customBinding>
  27.   </bindings>
  28. </system.serviceModel>

 

The web.config in the ‘windowsintegrated’ changes the default binding to enable windows authentication. I’m using the ‘Simplified WCF Configuration’ here so the final config is very clean as a result.

Overriden default CustomBindin
  1. <system.serviceModel>
  2.   <services/>
  3.   <bindings>
  4.     <customBinding>
  5.       <binding>
  6.         <httpTransport authenticationScheme="Negotiate"/>
  7.       </binding>
  8.     </customBinding>
  9.   </bindings>
  10. </system.serviceModel>

Similar technique is used on the WebSite/Router where I pick different STS endpoint/binding depending on the chosen router endpoint. The root web.config goes to the anonymous STS endpoint (line 2 & 3) and authentication is done using the message credentials (userName).

Root web.config WebSite
  1. <client>
  2.   <endpoint name="stsEndpoint" address="http://localhost/ActiveSTS/issue.svc/IWSTrust13"
  3.             binding="customBinding" bindingConfiguration="outBinding" contract="*">
  4.   </endpoint>
  5.  
  6.   <endpoint name="serviceEndpoint" address="http://localhost/UserService/Service1.svc"
  7.       binding="customBinding" bindingConfiguration="outBinding" contract="*">
  8.  
  9.   </endpoint>
  10.  
  11. </client>

 

Web.config in the ‘windowsintegrated’ changes the default STS endpoint/binding to match the windows authentication requirements and also enables impersonation to flow windows identity to the STS.

Router config for windows auth
  1. <system.serviceModel>
  2.   <services/>
  3.   <client>
  4.     <remove name="stsEndpoint"/>
  5.     <endpoint name="stsEndpoint" address="http://localhost/ActiveSTS/windowsintegrated/issue.svc/IWSTrust13"
  6.               binding="customBinding" bindingConfiguration="outBinding" contract="*"/>
  7.   </client>
  8.   <bindings>
  9.     <customBinding>
  10.       <binding name="inBinding">
  11.         <httpsTransport authenticationScheme="Negotiate"/>
  12.       </binding>
  13.  
  14.       <binding name="outBinding">
  15.         <httpTransport authenticationScheme="Negotiate"/>
  16.       </binding>
  17.  
  18.     </customBinding>
  19.   </bindings>
  20.   <behaviors>
  21.     <serviceBehaviors>
  22.       <behavior>
  23.         <serviceAuthorization impersonateCallerForAllOperations="true"/>          
  24.       </behavior>
  25.     </serviceBehaviors>
  26.   </behaviors>
  27. </system.serviceModel>

 

Finally make sure to enable integrated windows authentication on the ‘windowsintegrated’ directory in IIS before you run the samples.

image

enjoy…

Download: Sample solution

 

Original post by Zulfiqar Ahmed on 23/03/11 here: http://zamd.net/2011/03/23/silverlight-claim-based-security-part-2/