Flowing Basic HTTP UserName Credentials

Topics: Technical Questions, Usage Scenarios
Nov 9, 2009 at 8:11 PM

I've reviewed the security guide and walkthrough but am unable to configure the MSE to accomplish the task of flowing basic http username credentials from endpoint to implementation.  My clients need to communicate with the service endpoint using basic http authentication (TransportCredentialsOnly).  However, the Endpoint Security Policy described in the security guide does not seem to be picking up the credentials and placing them on the thread.  I've verfied that the Endpoint Security Policy is being applied, but it is never invoked for requests over this binding.  Is this policy incompatible for my binding, and if so, is there another approach to accomplish this task?

<bindings xmlns="">
  <basicHttpBinding>
    <binding name="windowsCredentialBinding">
      <security mode="TransportCredentialOnly">
        <transport clientCredentialType="Basic">
        </transport>
      </security>
    </binding>
  </basicHttpBinding>
</bindings> 

Endpoint Security Policy:

<sec:EndpointSecurityElement xmlns:sec="clr-namespace:Microsoft.MSE.Behaviors.Security.Configuration;assembly=Microsoft.MSE.Behaviors.Security" xmlns:sec2="clr-namespace:Microsoft.MSE.Behaviors.Security;assembly=Microsoft.MSE.Behaviors.Security">
  <sec:EndpointSecurityElement.ServiceCredentials>
    <sec2:BasicUserNameServiceCredentials FlowUserNameToken="True">
    </sec2:BasicUserNameServiceCredentials>
  </sec:EndpointSecurityElement.ServiceCredentials>
</sec:EndpointSecurityElement>

Developer
Nov 10, 2009 at 12:02 AM

The samples in the security guide will work with message level credentials.  For example the security guide code would work if you used a binding with security mode="TransportWithMessageCredential" and then specified a clientCredentialType="UserName" for the message security element.

The trouble with trying to flow transport level credentials like the Base64 encoded string that encompases the "Basic" credential is that it isn't bubbled up to the WCF extensibility layers we currently plug into.  The Basic transport credentials are handled by the transport layer and would have to be intercepted at that level which we haven't explored.

The second thing to keep in mind based on the security guide is that flowing credentials is a two step process.

1) Capture the incomming credentials via a policy on the virtual service endpoint

2) replay the captured credentials via a policy on the resource or system instance that identifies the service implementation you want to invoke.

The need for the two step process is due to the fact that the MSE is an intermediary and the request to the service implementation is a new WCF client proxy.  The original incoming credentials need to be applied to the new WCF client proxy that is created.

hope that helps.

Nov 11, 2009 at 2:52 PM

Thanks for the information, botto.  I'm familiar with the IdentityAwareChannelChannel behavior and have used it to apply credentials at the resource level for other scenarios.  Can you give me any guidance on a workaround for this scenario?  For instance, would it be possible to write my own WCF extension to capture transport headers, and if so, what would be the recommended approach...custom biniding, service behavior, etc.  Or should I take some other approach?

To give you you some background, I'm a soa analyst/developer with a large company and we're trying to use MSE within my application group (.NET Apps/Windows Integrated Authentication) to route all incoming/outgoing messages with other application groups (Websphere Apps/Basic HTTP Authentication).  Any guidance is appreciated.  We are also a Microsoft Platinum customer.

thanks. 

 

Developer
Nov 11, 2009 at 5:29 PM

So this turned out to be quite a bit easier than I was expecting.  Here's what I did...

Add a message inspector to your Endpoint hosted in the MSE.  The message inspector will retrieve the transport security token and store it on the current thread.  The existing identity aware channel policy should function w/o change... taking the security token stored on the current thread and supplying it to the final service implementation.

Here's the snippet in the AfterReceiveRequest method of the message inspector I created:

if (null != OperationContext.Current.IncomingMessageProperties && 
    null != OperationContext.Current.IncomingMessageProperties.Security &&
    null != OperationContext.Current.IncomingMessageProperties.Security.TransportToken)
    {
        SecurityToken token = OperationContext.Current.IncomingMessageProperties.Security.TransportToken.SecurityToken;
        TokenPrincipal principal = new TokenPrincipal(Thread.CurrentPrincipal.Identity, token);
        Thread.CurrentPrincipal = principal;
    }
return null;
Nov 11, 2009 at 10:17 PM

Works great!