.NET Framework Developer Center > .NET Development Forums > Windows Communication Foundation > WCF/Geneva client binding for webservice (RP) that requires an Security Context Token (SCT) issued by an STS according to WS-Trust/WS-SecureConversation
Ask a questionAsk a question
 

Proposed AnswerWCF/Geneva client binding for webservice (RP) that requires an Security Context Token (SCT) issued by an STS according to WS-Trust/WS-SecureConversation

  • Wednesday, November 04, 2009 4:43 PMmkeim Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Has Code
    Hi All,

    I'm trying to set up a WCF client for a webservice (RP) that requires a SecurityContextToken that is issued by an STS within the service domain. If it's usefull/necessary, I could also use the Geneva-SDK to implement the client.
    The STS is using a (customized) username token for authentication, which includes username, password and an additional one-time-password.
    From the webservice-documentation, I've an example for an RST against the STS:


    <?xml version="1.0" encoding="UTF-8"?>
    <soapenv:Envelope
      xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
      xmlns:xsd="http://www.w3.org/2001/XMLSchema"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
      <soapenv:Header>
        <wsa:Action
          soapenv:actor=""
          soapenv:mustUnderstand="0"
          xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing/">
          http://schemas.xmlsoap.org/ws/2005/02/trust/RST/SCT
        </wsa:Action>
        <wsse:Security
          soapenv:actor=""
          soapenv:mustUnderstand="1"
          xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
          <wsse:UsernameToken xmlns:acme="http://www.acme.com/namespace">
            <wsse:Username>myuser</wsse:Username>
            <wsse:Password
    Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">mypasswd</wsse:Password>
            <acme:OTP>12345678</acme:OTP>
          </wsse:UsernameToken>
        </wsse:Security>
      </soapenv:Header>
      <soapenv:Body>
        <RequestSecurityToken xmlns="http://schemas.xmlsoap.org/ws/2005/02/trust">
          <TokenType>http://schemas.xmlsoap.org/ws/2005/02/sc/sct</TokenType>
          <RequestType>http://schemas.xmlsoap.org/ws/2005/02/trust/Issue</RequestType>
        </RequestSecurityToken>
      </soapenv:Body>
    </soapenv:Envelope>
    
    
    

    And a call to the actual service, including the issued SCT:


    <?xml version="1.0" encoding="UTF-8"?>
    <soapenv:Envelope
      xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
      xmlns:xsd="http://www.w3.org/2001/XMLSchema"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
      <soapenv:Header>
        <wsse:Security
          soapenv:actor=""
          soapenv:mustUnderstand="1"
          xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
          <wsc:SecurityContextToken xmlns:wsc="http://schemas.xmlsoap.org/ws/2005/02/sc">
            <wsc:Identifier>acme:1234567abcde</wsc:Identifier>
          </wsc:SecurityContextToken>
        </wsse:Security>
      </soapenv:Header>
      <soapenv:Body>
        <getSomeStuff xmlns="http://www.acme.com/namespace"/>
      </soapenv:Body>
    </soapenv:Envelope>
    
    

    Security is done on transport level (via HTTPS).
    According to the webservice provider, all this adheres to the WS-Trust, WS-Security and WS-SecureConversation standards.
    I've some experience with the WCF-examples for the "wsFederationHttpBinding", so I'd thought that it should be possible to implement a WCF-client for the above scenario, using (mainly) an appropriate binding for the actual service. That is, w/o manually doing the STS/RST/SCT stuff.
    But I'm pretty lost on that. I've searched the web for the last day to find an example or something related to such an scenario, alas to no avail.
    Using the "WsdlImporter"-tool on the WSDL of the webservice simply generates a custom binding with HTTPS-transport that has no relation to the STS or the SCT (and doesn't work, of course).

    So, the question is quite general if someone has an idea how to implement a client for such a service, using WCF (or maybe Geneva SDK). Any information would be greatly appreciated.


    Thanks & Ciao,

    Markus

All Replies

  • Tuesday, November 10, 2009 5:15 PMmkeim Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Has Code
    Hello All,

    WRT my prior post (which didn't had too much resonance so far :) ) I'm trying now to give some additional resp. more precise information to ask for your advice.
    What I'm trying to do is to generate WCF client proxy code for a WS that uses a SecurityContextToken (SCT) according to the WS-Trust/WS-SecureConversation standards. The token is issued by an separate STS on the same domain.
    AFAIK WCF supports the relevant standards (WS-Security, WS-Trust, WS-SecureConversation) so I'd thought that it should be possible to generate client code that (implicitly) handles the bootstrapping of the secure conversation (request the SCT from the STS etc.).

    I've tried to fed the webservice-WSDL to the "svcutil"-tool, but it gives a warning for the part of the WSDL that IMHO is crucial to the SCT/STS/SecureConversation thing. Consequently, the generated client code/configuration has no relation to the SCT/STS.

    Warning: The following Policy Assertions were not imported:
      XPath://wsdl:definitions[@targetNamespace='http://www.acme.com/namespace']/wsdl:binding[@name='TicketServiceBinding']
    Assertions:
        <sp:SupportingTokens xmlns:sp='http://schemas.xmlsoap.org/ws/2005/07/securitypolicy'>..</sp:SupportingTokens>

    This is the WSDL for the WS ("TicketService"):

    <?xml version="1.0" encoding="UTF-8"?>
    <wsdl:definitions
    	targetNamespace="http://www.acme.com/namespace"
    	xmlns:acme="http://www.acme.com/namespace"
    	xmlns:soapbind="http://schemas.xmlsoap.org/wsdl/soap/"
    	xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy"
    	xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing"
    	xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
    	xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"
    	xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
    	xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
    
    	<!-- ================================================================================
    	WS-Policy
    	================================================================================ -->
    
    	<wsp:Policy wsu:Id="TicketServiceSecurityPolicy">
    		<wsp:ExactlyOne>
    			<wsp:All>
    				<sp:TransportBinding>
    					<wsp:Policy>
    						<sp:TransportToken>
    							<wsp:Policy>
    								<sp:HttpsToken RequireClientCertificate="false"/>
    							</wsp:Policy>
    						</sp:TransportToken>
    						<sp:Layout>
    							<wsp:Policy>
    								<sp:Strict/>
    							</wsp:Policy>
    						</sp:Layout>
    						<sp:AlgorithmSuite>
    							<wsp:Policy>
    								<sp:Basic128/>
    							</wsp:Policy>
    						</sp:AlgorithmSuite>
    					</wsp:Policy>
    				</sp:TransportBinding>
    				<sp:SupportingTokens>
    					<wsp:Policy>
    						<sp:SecureConversationToken sp:IncludeToken="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/AlwaysToRecipient">
    							<sp:Issuer>
    								<wsa:Address>
    									https://www.acme.com/services/STS
    								</wsa:Address>
    							</sp:Issuer>
    						</sp:SecureConversationToken>
    					</wsp:Policy>
    				</sp:SupportingTokens>
    			</wsp:All>
    		</wsp:ExactlyOne>
    	</wsp:Policy>
    
    	<!-- ================================================================================
    	WSDL-Types
    	================================================================================ -->
           
    	<!-- ommited types for  the sake of brevity -->
    
    
    	<!-- ================================================================================
    	WSDL-Messages
    	================================================================================ -->
    
    	<wsdl:message name="getClientListRequest">
    		<wsdl:part element="acme:getClientList" name="parameters"/>
    	</wsdl:message>
    	<wsdl:message name="getClientListResponse">
    		<wsdl:part element="acme:getClientListResponse" name="parameters"/>
    	</wsdl:message>
    	<wsdl:message name="getTicketRequest">
    		<wsdl:part element="acme:getTicket" name="parameters"/>
    	</wsdl:message>
    	<wsdl:message name="getTicketResponse">
    		<wsdl:part element="acme:getTicketResponse" name="parameters"/>
    	</wsdl:message>
    
    	<!-- ================================================================================
    	WSDL-PortType
    	================================================================================ -->
    
    	<wsdl:portType name="TicketServicePortType">
    		<wsdl:operation name="getClientList" parameterOrder="parameters">
    			<wsdl:input message="acme:getClientListRequest" name="getClientListRequest"/>
    			<wsdl:output message="acme:getClientListResponse" name="getClientListResponse"/>
    		</wsdl:operation>
    		<wsdl:operation name="getTicket" parameterOrder="parameters">
    			<wsdl:input message="acme:getTicketRequest" name="getTicketRequest"/>
    			<wsdl:output message="acme:getTicketResponse" name="getTicketResponse"/>
    		</wsdl:operation>
    	</wsdl:portType>
    
    	<!-- ================================================================================
    	WSDL-Binding
    	================================================================================ -->
    
    	<wsdl:binding name="TicketServiceBinding" type="acme:TicketServicePortType">
    		<soapbind:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
    		<wsp:PolicyReference URI="#TicketServiceSecurityPolicy"/>
    		<wsdl:operation name="getClientList">
    			<soapbind:operation soapAction="urn:getClientList" style="document"/>
    			<wsdl:input name="getClientListRequest">
    				<soapbind:body use="literal"/>
    			</wsdl:input>
    			<wsdl:output name="getClientListResponse">
    				<soapbind:body use="literal"/>
    			</wsdl:output>
    		</wsdl:operation>
    		<wsdl:operation name="getTicket">
    			<soapbind:operation soapAction="urn:getTicket" style="document"/>
    			<wsdl:input name="getTicketRequest">
    				<soapbind:body use="literal"/>
    			</wsdl:input>
    			<wsdl:output name="getTicketResponse">
    				<soapbind:body use="literal"/>
    			</wsdl:output>
    		</wsdl:operation>
    	</wsdl:binding>
    
    	<!-- ================================================================================
    	WSDL-Service
    	================================================================================ -->
    
    	<wsdl:service name="AcmeTicketService">
    		<wsdl:port binding="acme:TicketServiceBinding" name="TicketService">
    			<soapbind:address location="https://www.acme.com/services/TicketService"/>
    		</wsdl:port>
    	</wsdl:service>
    
    </wsdl:definitions>
    

    Security is done on transport-level (via HTTPS).
    There is a separate WSDL for the STS, but AFAICS it only describes the RST/RSTR mechanism for the SCT.
    I'm not sure how the service is implemented, but I'm quite sure that it's based on some Java-Framework.
    Could this be a (possibly known) interoperability problem WRT WS-SecureConversation, a version-conflict or something alike?
    Or doesn't WCF support this kind of sevice (SecureConversation with an SCT that is issued by an separate STS)?


    Thanks & Ciao,

    Markus
  • Wednesday, November 11, 2009 4:47 AMSteven Cheng - MSFTMSFT, ModeratorUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     

    Hi Markus,

    Regarding on your scenario, I'm afraid there is no simple means to directly generate such client proxy which can automatically handle the custom STS and username tokens. Per the sample soap message you provided, your request will require a secuirtyContextToken Header, if your service has fixed requirement on this and you do not want to build custom STS, you may consider manually inject a soapheader into your WCF request, however, this will require you to build the soapheader(security token header ) manually.

     #Handling custom SOAP headers via WCF Behaviors

    http://weblogs.asp.net/paolopia/archive/2008/02/25/handling-custom-soap-headers-via-wcf-behaviors.aspx



    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
  • Wednesday, November 11, 2009 5:13 PMmkeim Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Has Code
    Hello Steve,

    and many thanks for your interest.
    The SecurityContextToken in the header of the webservice request is a fixed requirement, I've no influence  on how the service works resp. authenticates.
    So, if I've to manually put the SCT in the header, that's one thing (thank you for the link!). But before that, I've to get the SCT from the STS. But if I run "svcutil" on the WSDL of the STS, I get an similar error as when I run the tool on the webservice WSDL (see my second post to this topic).
    The problem seems to be that the STS WSDL also includes an element "SupportingTokens":

    <?xml version="1.0" encoding="UTF-8"?>
    <wsdl:definitions
      targetNamespace="http://www.acme.com/namespace"
      xmlns:acme="http://www.acme.com/namespace"
      xmlns:soapbind="http://schemas.xmlsoap.org/wsdl/soap/"
      xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy"
      xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
      xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"
      xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
      xmlns:wst="http://schemas.xmlsoap.org/ws/2005/02/trust"
      xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
    
    
         <wsp:Policy wsu:Id="UserAuthSecurityPolicy">
            <wsp:ExactlyOne>
               <wsp:All>
                  <sp:TransportBinding>
                     <wsp:Policy>
                        <sp:TransportToken>
                           <wsp:Policy>
                              <sp:HttpsToken RequireClientCertificate="false"/>
        	               </wsp:Policy>
        	            </sp:TransportToken>
                        <sp:Layout>
                           <wsp:Policy>
                              <sp:Strict/>
        	               </wsp:Policy>
        	            </sp:Layout>
                        <sp:AlgorithmSuite>
                           <wsp:Policy>
                              <sp:Basic128/>
        	               </wsp:Policy>
        	            </sp:AlgorithmSuite>
        	         </wsp:Policy>
                  </sp:TransportBinding>
                  <sp:SupportingTokens>
                     <wsp:Policy>
    	                <wsp:ExactlyOne>
    	          	       <sp:UsernameToken wsu:Id="AcmeBasicToken"/>
    	                </wsp:ExactlyOne>
                     </wsp:Policy>
                  </sp:SupportingTokens>
               </wsp:All>
            </wsp:ExactlyOne>
         </wsp:Policy>
    

    (BTW, this STS (there are two) authenticates with a standard UsernameToken, but it makes no difference, the OTP-extension of the UsernamToken doesn't seem to be the problem here)

    It seems that the "svcutil" tool doesn't work on WSDLs that includes a "SupportingTokens" element.
    So, do I really have to manually do the RST against the STS to get the SCT, and than manually put it in the webservice request? This would also mean that I've to (manually) check the SCT before any service request to check if it's still valid.
    That seems a bit cumbersome, at least by comparison to a WS-Federation scenario, where an WCF-client is able to do handle the RST/RSTR for a SAML token against an STS completely implicit during the webservice request. Simlpy by configuration.
    Is WS-SecureConversation with an SCT such an exotic thing? Or could it be that the webservice isn't as standard compliant as I've been told (see my second post for the WSDL)?


    Thanks & Ciao,

    Markus
  • Wednesday, November 11, 2009 9:31 PMHarald13 Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Proposed AnswerHas Code
    Hello Markus,

    take a policy like this:

           <wsp:Policy wsu:Id="UserAuthSecurityPolicy">
                <wsp:ExactlyOne>
                  <wsp:All>
                    <sp:TransportBinding xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702">
                      <wsp:Policy>
                        <sp:TransportToken>
                          <wsp:Policy>
                            <sp:HttpsToken/>
                          </wsp:Policy>
                        </sp:TransportToken>
                        <sp:AlgorithmSuite>
                          <wsp:Policy>
                            <sp:Basic256/>
                          </wsp:Policy>
                        </sp:AlgorithmSuite>
                        <sp:Layout>
                          <wsp:Policy>
                            <sp:Lax/>
                          </wsp:Policy>
                        </sp:Layout>
                        <sp:IncludeTimestamp/>
                      </wsp:Policy>
                    </sp:TransportBinding>
                    <sp:EndorsingSupportingTokens xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702">
                      <wsp:Policy>
                        <sp:IssuedToken sp:IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/IncludeToken/AlwaysToRecipient">
                          <Issuer xmlns="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702">
                            <Address xmlns="http://www.w3.org/2005/08/addressing">http://www.w3.org/2005/08/addressing/anonymous</Address>
                            <Metadata xmlns="http://www.w3.org/2005/08/addressing">
                              <Metadata xmlns="http://schemas.xmlsoap.org/ws/2004/09/mex" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
                                <wsx:MetadataSection xmlns="">
                                  <wsx:MetadataReference>
                                    <Address xmlns="http://www.w3.org/2005/08/addressing">http://localhost:6000/SimpleActiveSTS/mex</Address>
                                  </wsx:MetadataReference>
                                </wsx:MetadataSection>
                              </Metadata>
                            </Metadata>
                          </Issuer>
                          <sp:RequestSecurityTokenTemplate>
                            <trust:TokenType xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512">http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV2.0</trust:TokenType>
                            <trust:KeyType xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512">http://docs.oasis-open.org/ws-sx/ws-trust/200512/SymmetricKey</trust:KeyType>
                            <trust:KeySize xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512">256</trust:KeySize>
                            <trust:Claims Dialect="http://schemas.xmlsoap.org/ws/2005/05/identity" xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512">
                              <wsid:ClaimType Uri="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name" xmlns:wsid="http://schemas.xmlsoap.org/ws/2005/05/identity"/>
                              <wsid:ClaimType Uri=<a href="http://schemas.xxx.de/yyy/2008/09/Identities/Age">http://schemas.xxx.de/yyy/2008/09/Identities/Age</a> xmlns:wsid="http://schemas.xmlsoap.org/ws/2005/05/identity"/>
                            </trust:Claims>
                            <t:EncryptWith xmlns:t="http://docs.oasis-open.org/ws-sx/ws-trust/200512">http://www.w3.org/2001/04/xmlenc#aes256-cbc</t:EncryptWith>
                            <t:SignWith xmlns:t="http://docs.oasis-open.org/ws-sx/ws-trust/200512">http://www.w3.org/2000/09/xmldsig#hmac-sha1</t:SignWith>
                            <t:CanonicalizationAlgorithm xmlns:t="http://docs.oasis-open.org/ws-sx/ws-trust/200512">http://www.w3.org/2001/10/xml-exc-c14n#</t:CanonicalizationAlgorithm>
                            <t:EncryptionAlgorithm xmlns:t="http://docs.oasis-open.org/ws-sx/ws-trust/200512">http://www.w3.org/2001/04/xmlenc#aes256-cbc</t:EncryptionAlgorithm>
                          </sp:RequestSecurityTokenTemplate>
                          <wsp:Policy>
                            <sp:RequireInternalReference/>
                          </wsp:Policy>
                        </sp:IssuedToken>
                        <sp:SignedParts>
                          <sp:Header Name="To" Namespace="http://www.w3.org/2005/08/addressing"/>
                        </sp:SignedParts>
                      </wsp:Policy>
                    </sp:EndorsingSupportingTokens>
                    <sp:Wss11 xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702">
                      <wsp:Policy>
                        <sp:MustSupportRefKeyIdentifier/>
                        <sp:MustSupportRefIssuerSerial/>
                        <sp:MustSupportRefThumbprint/>
                        <sp:MustSupportRefEncryptedKey/>
                      </wsp:Policy>
                    </sp:Wss11>
                    <sp:Trust13 xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702">
                      <wsp:Policy>
                        <sp:MustSupportIssuedTokens/>
                        <sp:RequireClientEntropy/>
                        <sp:RequireServerEntropy/>
                      </wsp:Policy>
                    </sp:Trust13>
                    <wsaw:UsingAddressing/>
                  </wsp:All>
                </wsp:ExactlyOne>
              </wsp:Policy>
    
    if you take svcutil against such a policy you will get such a config:

            <binding name="EchoUserSSL">
              <security defaultAlgorithmSuite="Default" authenticationMode="IssuedTokenOverTransport" 
                requireDerivedKeys="false" securityHeaderLayout="Lax" includeTimestamp="true"
                keyEntropyMode="CombinedEntropy" messageSecurityVersion="WSSecurity11WSTrust13WSSecureConversation13WSSecurityPolicy12BasicSecurityProfile10">
                <issuedTokenParameters keySize="256" keyType="SymmetricKey" tokenType="http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV2.0">
                  <additionalRequestParameters>
                    <t:EncryptWith xmlns:t="http://docs.oasis-open.org/ws-sx/ws-trust/200512">http://www.w3.org/2001/04/xmlenc#aes256-cbc</t:EncryptWith>
                    <t:SignWith xmlns:t="http://docs.oasis-open.org/ws-sx/ws-trust/200512">http://www.w3.org/2000/09/xmldsig#hmac-sha1</t:SignWith>
                    <t:CanonicalizationAlgorithm xmlns:t="http://docs.oasis-open.org/ws-sx/ws-trust/200512">http://www.w3.org/2001/10/xml-exc-c14n#</t:CanonicalizationAlgorithm>
                    <t:EncryptionAlgorithm xmlns:t="http://docs.oasis-open.org/ws-sx/ws-trust/200512">http://www.w3.org/2001/04/xmlenc#aes256-cbc</t:EncryptionAlgorithm>
                  </additionalRequestParameters>
                  <claimTypeRequirements>
                    <add claimType="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name"
                      isOptional="false" />
                    <add claimType="http://schemas.xxx.de/yyy/2008/09/Identities/Age"
                      isOptional="false" />
                  </claimTypeRequirements>
                  <issuerMetadata address="http://localhost:6000/SimpleActiveSTS/mex" >
                  </issuerMetadata>
                </issuedTokenParameters>
                <localClientSettings cacheCookies="true" detectReplays="false"
                  replayCacheSize="900000" maxClockSkew="00:05:00" maxCookieCachingTime="Infinite"
                  replayWindow="00:05:00" sessionKeyRenewalInterval="10:00:00"
                  sessionKeyRolloverInterval="00:05:00" reconnectTransportOnFailure="true"
                  timestampValidityDuration="00:05:00" cookieRenewalThresholdPercentage="60" />
                <localServiceSettings detectReplays="false" issuedCookieLifetime="10:00:00"
                  maxStatefulNegotiations="128" replayCacheSize="900000" maxClockSkew="00:05:00"
                  negotiationTimeout="00:01:00" replayWindow="00:05:00" inactivityTimeout="00:02:00"
                  sessionKeyRenewalInterval="15:00:00" sessionKeyRolloverInterval="00:05:00"
                  reconnectTransportOnFailure="true" maxPendingSessions="128"
                  maxCachedCookies="1000" timestampValidityDuration="00:05:00" />
                <secureConversationBootstrap />
              </security>
              <textMessageEncoding maxReadPoolSize="64" maxWritePoolSize="16"
                messageVersion="Default" writeEncoding="utf-8">
                <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
                  maxBytesPerRead="4096" maxNameTableCharCount="16384" />
              </textMessageEncoding>
              <httpsTransport manualAddressing="false" maxBufferPoolSize="524288"
                maxReceivedMessageSize="65536" allowCookies="false" authenticationScheme="Anonymous"
                bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
                keepAliveEnabled="true" maxBufferSize="65536" proxyAuthenticationScheme="Anonymous"
                realm="" transferMode="Buffered" unsafeConnectionNtlmAuthentication="false"
                useDefaultWebProxy="true" requireClientCertificate="false" />
            </binding>
    
    greetings from germany
    harald k.
  • Thursday, November 19, 2009 6:04 PMmkeim Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Has Code
    Hi Harald,

    and thanks for your example.
    Tho, I'm not sure how this applies to my scenario. I'm anything but an expert WRT to .NET/WCF, but your example looks to me like similar to a federated scenario where the client uses an SAML (1.1) token, issued by an STS to authenticate against the service. If so, one could also use the "wsFederationHttpBinding".
    In my case, I gues I've to support an authenticationMode "SecureConversation" according to WS-SecureConversation. My primary problem seems to be to get the SCT/STS information into the webservice binding of the WCF-client. That is, in such a way that the client automatically calls the STS for the SCT to put it in the actual service call.

    However, according to your example I've changed the WS-SecurityPolicy namespace to "http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702" and also the (obviously problematic) "SupportingTokens" element of the policy to "EndorsingSupportingTokens". Using this modified WSDL, at least I'm getting another warning from the "svcutil"-tool. Alas, I'm only get the German version of the warning (using an English VS2008!), but maybe that isn't a problem for you. ;)

    Warnung: Für den Endpunkt wurde eine Sicherheitsrichtlinie importiert.
    Die Sicherheitsrichtlinie enthält Anforderungen, die nicht in einer WCF-Konfiguration
    (Windows Communication Foundation) dargestellt werden können.
    Suchen Sie nach einem Kommentar zu den SecurityBindingElement-Parametern,
    die in der generierten Konfigurationsdatei erforderlich sind.
    Erstellen Sie mithilfe von Code das richtige Bindungselement.
    Die Bindungskonfiguration in der Konfigurationsdatei ist nicht sicher.
    The comments in the generated config-file are

    <!--Das Konfigurationsschema ist nicht ausreichend, um die nicht standardmäßige Konfiguration des folgenden Sicherheitsbindungselements zu beschreiben: -->
    <!--System.ServiceModel.Channels.TransportSecurityBindingElement:
    DefaultAlgorithmSuite: Basic128
    IncludeTimestamp: False
    KeyEntropyMode: CombinedEntropy
    MessageSecurityVersion: WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11
    SecurityHeaderLayout: Strict
    EndpointSupportingTokenParameters:
      Endorsing[0]
        System.ServiceModel.Security.Tokens.SecureConversationSecurityTokenParameters:
        InclusionMode: AlwaysToRecipient
        ReferenceStyle: Internal
        RequireDerivedKeys: False
        RequireCancellation: True
        BootstrapSecurityBindingElement: null
      No signed tokens.
      No signed encrypted tokens.
      No signed endorsing tokens.
    OptionalEndpointSupportingTokenParameters:
      No endorsing tokens.
      No signed tokens.
      No signed encrypted tokens.
      No signed endorsing tokens.
    OperationSupportingTokenParameters: none
    OptionalOperationSupportingTokenParameters: none-->

    Thanks & Ciao,

    Markus

  • Friday, November 20, 2009 4:45 PMmkeim Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Has Code
    Hello All,

    it seems I've made some (humble) progress, at least I hope so.
    I've manually edited the WCF-Config of the webservice client to somehow put in the relation to the SCT/STS.

    <?xml version="1.0" encoding="utf-8"?>
    <configuration>
    
      <system.serviceModel>
    
        <bindings>
          <customBinding>
            <binding name="TicketServiceBinding">
    
              <security
                includeTimestamp="false"
                keyEntropyMode="ServerEntropy"
                authenticationMode="SecureConversation"
                messageSecurityVersion="WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11">
                <secureConversationBootstrap
                  authenticationMode="UserNameOverTransport"
                  includeTimestamp="false">
                   <issuedTokenParameters
                     tokenType="http://schemas.xmlsoap.org/ws/2005/02/sc/sct">
                    <issuer
                      address="https://www.acme.com/services/STSWeak">
                     </issuer>
                  </issuedTokenParameters>
                </secureConversationBootstrap>
              </security>
    
              <textMessageEncoding
                maxReadPoolSize="64"
                maxWritePoolSize="16"
                messageVersion="Soap11WSAddressingAugust2004"
                writeEncoding="utf-8">
                <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
                    maxBytesPerRead="4096" maxNameTableCharCount="16384" />
              </textMessageEncoding>
    
              <httpsTransport
                  manualAddressing="false" maxBufferPoolSize="524288"
                  maxReceivedMessageSize="65536" allowCookies="false" authenticationScheme="Anonymous"
                  bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
                  keepAliveEnabled="true" maxBufferSize="65536" proxyAuthenticationScheme="Anonymous"
                  realm="" transferMode="Buffered" unsafeConnectionNtlmAuthentication="false"
                  useDefaultWebProxy="true" requireClientCertificate="false"/>
    
            </binding>
          </customBinding>
        </bindings>
    
        <client>
          <endpoint address="https://www.acme.com/services/TicketService"
            binding="customBinding" bindingConfiguration="TicketServiceBinding"
            contract="TicketServicePortType" name="TicketService">
          </endpoint>
        </client>
    
      </system.serviceModel>
    </configuration>
    
    


    With this configuration, the client actually sends an RST when I call a webservice method. The RST looks not exactly as in the webservice-documentation, but it's pretty close.


    <s:Envelope
      xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"
      xmlns:a="http://schemas.xmlsoap.org/ws/2004/08/addressing"
      xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
      <s:Header>
        <a:MessageID>urn:uuid:0a64049f-39f6-44c0-84d8-cd405fd20f7b</a:MessageID>
        <a:ReplyTo>
          <a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address>
        </a:ReplyTo>
        <a:To s:mustUnderstand="1">https://www.acme.com/services/TicketService</a:To>
        <o:Security s:mustUnderstand="1" xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
          <o:UsernameToken u:Id="uuid-ade5dd9a-3056-4ae0-bccc-7107d6ce414e-1">
            <o:Username>
              <!-- Removed-->
            </o:Username>
            <o:Password>
              <!-- Removed-->
            </o:Password>
          </o:UsernameToken>
        </o:Security>
      </s:Header>
      <s:Body>
        <t:RequestSecurityToken xmlns:t="http://schemas.xmlsoap.org/ws/2005/02/trust"><br/>
          <t:TokenType>http://schemas.xmlsoap.org/ws/2005/02/sc/sct</t:TokenType>
          <t:RequestType>http://schemas.xmlsoap.org/ws/2005/02/trust/Issue</t:RequestType>
          <t:KeySize>256</t:KeySize>
        </t:RequestSecurityToken>
      </s:Body>
    </s:Envelope>
    


    So far, so nice.
    The main problem is, that the RST is send to the endpoint of the TicketService , not the STS. The configured issuer-address seems to be comlpetely ignored. The webservice endpoint (consequently) gives an error that the request doesn't include the SCT.

    For testing purposes, I changed the address of the webservice endpoint to the one of the STS to see how it responds to the RST.
    Alas, with an error message:

    Did not understand "MustUnderstand" header(s):

    This seems to be the second major problem. WCF adds the SOAP-header element

    <a:To s:mustUnderstand="1">https://www.acme.com/services/TicketService</a:To>
    

    to the request. I searched for hours to find a way to remove that header, or at least to set the "mustUnderstand" attribute to false, but I found nothing.
    Maybe the "mustUnderstand" attribute of the <Action> element is the culprit (but I don't think so).

    <a:Action s:mustUnderstand="1">http://schemas.xmlsoap.org/ws/2005/02/trust/RST/SCT</a:Action>
    

    The webservice sample uses "mustUnderstand=0".

    So, any idea how to
    - get the STS endpoint address recognized
    - how to remove SOAP (address-) header elements or to control the "mustUnderstnd"-attribute?


    Thanks & Ciao,

    Markus