Zulfiqar's weblog

Architecture, security & random .Net

Silverlight Claim-Based-Security Part-2

Posted by zamd on March 23, 2011


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

Advertisements

6 Responses to “Silverlight Claim-Based-Security Part-2”

  1. Phill said

    Hi,

    I just wanted to find out if you are still monitoring these posts. I would like some advise regarding WCF Routing Service and WIF please

  2. Akash said

    As far I know WCF Routing Service doesn’t allow to pass security token except windows authentication, then how your solution work for user name token or claims tokens? Does your solution really works?

    • zamd said

      Akash,
      With message security, token goes as part of the SOAP message and that’s what is used for UserName & SAML tokens. For windows authentication, impersonation is used for flowing the token to the actual service.

      HTH,
      Zulfiqar

  3. jonyy said

    Hi,

    there will be some login check in STS for current logged-in user ? what is that ?

  4. MSK said

    Hi,
    I am getting the following exception when requesting my adfs
    An error occurred while trying to make a request to URI ‘https://corpsts.com/adfs/services/trust/13/usernamemixed’. This could be due to attempting to access a service in a cross-domain way without a proper cross-domain policy in place, or a policy that is unsuitable for SOAP services. You may need to contact the owner of the service to publish a cross-domain policy file and to ensure it allows SOAP-related HTTP headers to be sent. This error may also be caused by using internal types in the web service proxy without using the InternalsVisibleToAttribute attribute. Please see the inner exception for more details.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

 
%d bloggers like this: