I've got a requirement to connect to a web service using a digital signature. I'm using .NET 4.0 and WCF (Service Reference), and X509 SSL certificate, but can't find any suitable instructions on how to properly accomplish the goal.
I've found hundreds and hundreds of posts and blogs, etc, on encrypting soap messages, signing data, and the lot, with numerous examples using everything from X509Certificate1, X509Certificate2, X509Certificate3, DSACryptoServiceProvider, RSACryptoServiceProvider, setting up config in the web.config, setting up the config in code, using basicHttpBinding, or wsHttpBinding, or using WSE, WSE2, WSE3, ad nauseum.
Basically, I've found all kinds of information that is completely useless to me, as I've not been able to find a single complete example of how to simply add a digital signature to a soap message.
It certainly sounds like it should be a simple process, by the reading of examples of what digital signatures are, but I can't find a single useful implementation.
Can someone please point me in the right direction?
I think it depends on the security setup in the WCF binding. If you're just looking for the structure of your SOAP message, create a client using .NET and turn message logging on for the service. That will record every message being sent back and forth. I had to do this once, and found that the data encoding WCF uses (TLSNego) is proprietary, so a non-WCF client won't work.
A bit of a late answer, but hopefully this might help someone who lands here...
Using WCF client to connect to a SOAP service that used WS-Security with digital signature on the messages means you have to use a custom client binding. Some of the details might vary depending on your service, for example, the service WSDL (or the service provider might tell you if you cannot get the WSDL) might define a different message security version, but I have made this work using a client configuration like this:
<bindings>
<customBinding>
<binding name="WSHttpBinding_IService">
<security defaultAlgorithmSuite="Default" authenticationMode="SecureConversation"
requireDerivedKeys="true" includeTimestamp="true" messageProtectionOrder="SignBeforeEncrypt"
messageSecurityVersion="WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10"
requireSignatureConfirmation="false" canRenewSecurityContextToken="true">
<secureConversationBootstrap defaultAlgorithmSuite="Default"
authenticationMode="MutualSslNegotiated" requireDerivedKeys="true"
includeTimestamp="true" messageSecurityVersion="WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10"
requireSignatureConfirmation="false">
<localClientSettings detectReplays="true" />
<localServiceSettings detectReplays="true" />
</secureConversationBootstrap>
<localClientSettings detectReplays="true" />
<localServiceSettings detectReplays="true" />
</security>
<textMessageEncoding />
<httpTransport />
</binding>
</customBinding>
</bindings>
Related
I need to create a .NET client for a wso2 Secure Token Service.
Normally I would create a simple console or WinForm project adding a Service Reference to it. The exposed WSDL would be turned in a set of classes that I can use to query the service and to properly manage its response.
Unfortunately, the generated request and response classes are empty: just the class declaration without any property or method. This is similar to the behaviour described in this other (unanswered) Stack Overflow question https://stackoverflow.com/q/22049080/2131913
I have found a sample request for the service in this forum post: http://cxf.547215.n5.nabble.com/Sample-STS-Client-tp4643980p4664175.html and I made it to work with SOAP UI.
Is there a proper, and possibly automated, way to recreate the complex data structure needed to query the Secure Token Service?
EDIT
OK, after many tries I have reduced the SOAP request from the above forum post to the minimal structure needed to still get a RequestSecurityTokenResponse from the STS service.
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
<soap:Header xmlns:wsa="http://www.w3.org/2005/08/addressing">
<wsse:Security 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">
<wsse:UsernameToken wsu:Id="UsernameToken-6D35592DCDDA26FFF3141578725699577">
<wsse:Username>USERNAME HERE</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">PASSWORD HERE</wsse:Password>
</wsse:UsernameToken>
<wsu:Timestamp wsu:Id="TS-6D35592DCDDA26FFF3141578725699576">
<wsu:Created>2014-11-12T10:14:16.995Z</wsu:Created>
<wsu:Expires>2014-11-12T10:16:16.995Z</wsu:Expires>
</wsu:Timestamp>
</wsse:Security>
<wsa:Action soap:mustUnderstand="1">http://schemas.xmlsoap.org/ws/2005/02/trust/RST/SCT</wsa:Action>
<wsa:MessageID soap:mustUnderstand="1">uuid:6d4eab69-77f9-42b7-8d6b-1f710020fb0b</wsa:MessageID>
<wsa:To soap:mustUnderstand="1">STS ENDPOINT ADDRESS HERE</wsa:To>
</soap:Header>
<soap:Body>
<wst:RequestSecurityToken xmlns:wst="http://schemas.xmlsoap.org/ws/2005/02/trust">
<wst:RequestType>http://schemas.xmlsoap.org/ws/2005/02/trust/Issue</wst:RequestType>
<wst:TokenType>http://schemas.xmlsoap.org/ws/2005/02/sc/sct</wst:TokenType>
<wst:Claims>
<wsid:ClaimType Uri="http://wso2.org/claims/userid" xmlns:wsid="http://schemas.xmlsoap.org/ws/2005/05/identity"/>
</wst:Claims>
</wst:RequestSecurityToken>
</soap:Body>
</soap:Envelope>
I have obtained a partial success defining in the app.config of my project either a single wsHttpBinding like the following:
<wsHttpBinding>
<binding name="SendUsername" messageEncoding="Text">
<security mode ="TransportWithMessageCredential">
<message clientCredentialType ="UserName"/>
<transport clientCredentialType ="Basic" />
</security>
</binding>
</wsHttpBinding>
with or without adding a CustomBinding like the following:
<customBinding>
<binding name="wso2carbon-stsSoap12Binding">
<security defaultAlgorithmSuite="Default" authenticationMode="IssuedToken"
requireDerivedKeys="true" securityHeaderLayout="Lax" includeTimestamp="true">
<localClientSettings detectReplays="false" />
<localServiceSettings detectReplays="false" />
<issuedTokenParameters keyType ="SymmetricKey" tokenType ="http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV2.0">
<issuer address =STS ENDPOINT ADDRESS HERE binding ="wsHttpBinding" bindingConfiguration ="SendUsername"/>
<claimTypeRequirements>
<add claimType ="http://wso2.org/claims/userid"/>
</claimTypeRequirements>
</issuedTokenParameters>
</security>
<textMessageEncoding messageVersion="Soap12" />
<httpsTransport />
</binding>
</customBinding>
In both cases however the request throws a timeout exception, and inspecting with WCF tracing the issued request I can see that it is missing the Claims element. Any hints?
Please refer this article
Security Token Service with WSO2 Identity Server 2.0
For more insight on this please refer:
http://wso2.com/library/3190/
Configuring WSO2 Identity Server Passive STS with an ASP.NET
Client
After many days struggling with WCF configuration option I have obtained a partial success.
The key that allows me to obtain a response from the Security Token Service is that I realized that, in the long term, I will need to operate in a federated security scenario. I don't need the token per se, but I need it to obtain a mean to authenticate to other services.
With this option in mind I started to explore what WCF has to offer for this kind of scenario and I built the following configuration options:
<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 address here --> binding ="customBinding" bindingConfiguration ="StsBinding"/>
<claimTypeRequirements>
<add claimType="http://wso2.org/claims/userid" />
</claimTypeRequirements>
</message>
</security>
</binding>
</wsFederationHttpBinding>
The above binding is used to contact the service that needs token authentication while the following adds further instructions about how to contact the security token issuer:
<customBinding>
<binding name="StsBinding">
<textMessageEncoding messageVersion="Soap12WSAddressingAugust2004"/>
<useManagedPresentation/>
<security authenticationMode="UserNameOverTransport" includeTimestamp ="true" keyEntropyMode ="ServerEntropy" securityHeaderLayout ="Lax"
messageSecurityVersion="WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10" >
</security>
<httpsTransport authenticationScheme ="Basic"/>
</binding>
</customBinding>
With this configuration, and with the help of Fiddler and WCF trace I can see I get a Security Token Response from the STS issuer.
Howevere as I said, in the beginnig, this was only a partial success because WCF infrastructure, when processing the token, says that it has a wrong action... but this can be the subjet of another question ;-)
I hope this can be considered a valid answer although my quest for token authentication is not yet concluded
I have a non-WCF service that i need to communicate with. I have the WSDL of the service, and it uses WS-Security 1.0 with UsernameToken policy.
Example of the header:
<S11:Envelope xmlns:S11="..." xmlns:wsse="...">
<S11:Header>
...
<wsse:Security>
<wsse:UsernameToken>
<wsse:Username>username</wsse:Username>
<wsse:Password>password</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
...
</S11:Header>
...
</S11:Envelope>
What is the best way to communicate with this service?
If i use WCF, making the header look like what i need for the UsernameToken is going to be a problem from what i know, right? How can i do that?
On the other hand, i can make a non WCF proxy even though it's kind of obsolete.
What's the best way?
if the service uses ssl then you can have your wcf config like this:
<customBinding>
<binding name="NewBinding0">
<textMessageEncoding messageVersion="Soap11" />
<security authenticationMode="UserNameOverTransport">
<secureConversationBootstrap />
</security>
<httpTransport />
</binding>
</customBinding>
if the service does not use ssl then you should use ClearUsernameBinding
I am trying to create a WCF service that needs to be consumed by a Java client. Requirements from the Java client is to disable WS-Addressing. I must have to use WSHttpBinding. First of all I am bit new to this. I did some quick search online but was not able to figure out if that is the correct solution. Can somebody please point me to right direction ?
Thanks
Use http://webservices20.cloudapp.net/ for such issues. You did not specify which security you need. One option is
<!-- generated via Yaron Naveh's http://webservices20.blogspot.com/ -->
<customBinding>
<binding name="NewBinding0">
<transactionFlow />
<security authenticationMode="UserNameOverTransport" messageSecurityVersion="WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10" />
<textMessageEncoding messageVersion="Soap12" />
<httpsTransport />
</binding>
</customBinding>
<!-- generated via Yaron Naveh's http://webservices20.blogspot.com/ -->
I have a WCF service hosted in a Windows Service. Clients from various platforms will access the service. Now I would like to add a basic security mechanism. Ideally, the clients should use username/password for authentication.
Which binding settings do I have to use in this scenario and how can I authenticate the client? Interoperability is more important than a very secure solutions. If possible the client should not be forced to use a certificate or something the like. Additionally, authentication should not be strongly coupled with a SQL Server database. I would like to manually inspect the client credentials.
Thanks for your help
The best for your case can be BasicHttpBinding with security set to TransportWithMessageCredentials and credential type set to UserName. In this case your service will be secured with HTTPS (requires server certificate for SSL which has to be trusted on clients) and authentication will be provided on message level with UserName Token Profile (SOAP header). You can implement your own password validator.
BasicHttpBinding configuration skeleton:
<bindings>
<basicHttpBinding>
<binding name="Secured">
<security mode="TransportWithMessageCredential">
<message clientCredentialType="UserName" />
</security>
</binding>
</basicHttpBinding>
</bindings>
If you don't want to use HTTPS you can create custom binding with HttpTransport, TextMessageEncoding and with security mode set to UserNameOverTransport. But you have to set allowInsecureTransport to true (be aware that there is some bug with WSDL generation in this setting).
Custom binding configuration skeleton:
<bindings>
<customBinding>
<binding name="Secured">
<security authenticationMode="UserNameOverTransport" allowInsecureTransport="true" />
<textMessageEncoding messageVersion="Soap11" />
<httpTransport />
</binding>
</cutomBinding>
</bindings>
See the Internet section of the Application Scenarios for guides on how to achieve this:CodePlex Application Scenarios
I'm writing a C# WCF service that publishes an endpoint using a WSHttpFederationBinding. We have our own security token server providing tokens, for which callers need to use a custom binding.
This is all working fine for a C# client I've written: this has a custom binding in its app.config like so:
<bindings>
<customBinding>
<binding name="CustBind">
<security authenticationMode="UserNameForCertificate" requireDerivedKeys="true"
messageProtectionOrder="SignBeforeEncryptAndEncryptSignature"
requireSecurityContextCancellation="false"
requireSignatureConfirmation="false">
<secureConversationBootstrap/>
</security>
<httpTransport/>
</binding>
</customBinding>
<wsFederationHttpBinding>
<binding name="FedBind">
<security>
<message issuedTokenType="http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV1.1"
negotiateServiceCredential="false">
<issuer address="http://STSHost/MySTS" binding="customBinding"
bindingConfiguration="CustBind">
<identity>
<certificateReference x509FindType="FindBySubjectName" findValue="localhost"/>
</identity>
</issuer>
</message>
</security>
</binding>
</wsFederationHttpBinding>
</bindings>
However, what I want is for users to be able to generate their own clients in whatever language they want, just given the WSDL that the WCF service publishes. The problem with this is that when I try such a thing with Developer Studio's "Add Service Reference" functionality, the resulting client doesn't work.
The reason it doesn't work is because the generated client's app.config is clearly wrong: while the STS is there in the "issuer" element, there's no sign of the custom binding. Looking at the WSDL this isn't too surprising, as there's no mention of anything there other than the issuer address.
Is there any way to get WCF to add something to the WSDL to describe this situation? My server's app.config bindings look okay to me: the "issuer" element is exactly the same as for the working client, including the address and details of the custom binding. Does anyone know why WCF seems to be ignoring this when generating the WSDL?