0

This question is a sort of follow up to this one: How to create a .NET client for a wso2 Secure Token Service

Briefly, I am trying to implement a client for a web service in a federated security scenario. My client should invoke a method of a given web service authenticating itself with a security token provided by another web service (both services are implemented with wso2 platform).

As I stated in the answer to the above question, with the proper binding configuration, the client is able to receive the requested token. The following is my binding configuration:

  <wsFederationHttpBinding>
    <binding name="fs">
      <security mode="TransportWithMessageCredential">
        <message issuedKeyType="SymmetricKey" issuedTokenType ="http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV2.0">
          <issuer address =<!-- STS URL HERE--> binding ="customBinding" bindingConfiguration ="StsBinding"/>
          <claimTypeRequirements>
            <add claimType="http://wso2.org/claims/userid" />
          </claimTypeRequirements>
        </message>
      </security>
    </binding>
  </wsFederationHttpBinding>
  ...
  <customBinding>
    <binding name="StsBinding">
      <textMessageEncoding messageVersion="Soap12WSAddressing10"/>
      <useManagedPresentation/>
      <security authenticationMode="UserNameOverTransport" includeTimestamp ="true" keyEntropyMode ="ServerEntropy" securityHeaderLayout ="Lax"   
                messageSecurityVersion="WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10" >
      </security>
      <httpsTransport authenticationScheme ="Basic"/>
    </binding>
  </customBinding>

However, when my client process the recieved token it fails with a SecurityNegotiationException stating that the "urn:IssueTokenResponse" action is wrong. What does this exception means? What should be the correct action?

I don't have access to any details of both services so I need to know if I can do something on client side only.

I have tried to follow the advice contained in this forum post https://social.msdn.microsoft.com/Forums/vstudio/en-US/6c838f7e-f72f-4fdd-827d-b29c61522aa0/wrong-action-httpdocsoasisopenorgwssxwstrust200512rstrissue?forum=wcf but I don't think it applies to my case because there isn't a single messageSecurityVersion value which seems to work

Community
  • 1
  • 1
sblandin
  • 904
  • 4
  • 11
  • 25

1 Answers1

0

I finally find a working solution, at least for the "wrong action" error.

Digging through the WCF documentation I found a reference document describing how to set-up a Security Token Service (MSDN address here)

The most intresting part of the document is this small phrase that seems to indicate the expected action for a response sent by a STS:

In addition, it defines the associated Action Uniform Resource Identifiers (URIs). The action URI associated with the RequestSecurityToken message is http://schemas.xmlsoap.org/ws/2005/02/trust/RST/Issue. The action URI associated with the RequestSecurityTokenResponse message is http://schemas.xmlsoap.org/ws/2005/02/trust/RSTR/Issue.

After some more research on the extensbility mechanism provided by the WCF framework I found a promising reference about IClientMessageInspector that allows to customize client behavior when sending requests or when receiving replies.

The following is the simple code of the behavior:

Public Class ChangeReplyActionMessageInspector
    Implements IClientMessageInspector

    Public Sub AfterReceiveReply(ByRef reply As Message, correlationState As Object) Implements IClientMessageInspector.AfterReceiveReply
        If reply.Headers.Action = "urn:IssueTokenResponse" Then
            reply.Headers.Action = "http://schemas.xmlsoap.org/ws/2005/02/trust/RSTR/Issue"
        End If
    End Sub

    Public Function BeforeSendRequest(ByRef request As Message, channel As ServiceModel.IClientChannel) As Object Implements IClientMessageInspector.BeforeSendRequest
        Return Nothing
    End Function
End Class

To attach this custom behavior to the client object responsible to talk to the Security Token Service I need a IEndpointBehavior like this one:

Public Class ChangeReplyActionEndpointBehavior
    Implements IEndpointBehavior

    Public Sub AddBindingParameters(endpoint As ServiceEndpoint, bindingParameters As BindingParameterCollection) Implements IEndpointBehavior.AddBindingParameters

    End Sub

    Public Sub ApplyClientBehavior(endpoint As ServiceEndpoint, clientRuntime As ClientRuntime) Implements IEndpointBehavior.ApplyClientBehavior
        clientRuntime.ClientMessageInspectors.Add(New ChangeReplyActionMessageInspector)
    End Sub

    Public Sub ApplyDispatchBehavior(endpoint As ServiceEndpoint, endpointDispatcher As EndpointDispatcher) Implements IEndpointBehavior.ApplyDispatchBehavior

    End Sub

    Public Sub Validate(endpoint As ServiceEndpoint) Implements IEndpointBehavior.Validate

    End Sub
End Class

That it is programmatically attached to the client with the following code:

    Dim endpointBehaviorCollection As New System.Collections.Generic.KeyedByTypeCollection(Of IEndpointBehavior)
    endpointBehaviorCollection.Add(New ChangeReplyActionEndpointBehavior)
    client.ClientCredentials.IssuedToken.IssuerChannelBehaviors.Add(New Uri("STS URL HERE"), endpointBehaviorCollection)

In this way the issued security token is sent back to the target service with the final request. I am still getting errors for the final request that however needs further investigation.

sblandin
  • 904
  • 4
  • 11
  • 25