Reputation: 1860
I need to create a secure WCF Web-service which conforms to the Oasis 2004 standard(http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd)
I have been given example requests, which will be sent to me by a 3rd party. The body of the request is not important, but i will show the header here (some of the data has been changed to protect identities):
<soapenv:Header>
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
xmlns:wssu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<wsse:UsernameToken>
<wsse:Username>username</wsse:Username>
<wsse:Password
Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest">
weYI3nXd8LjMNVksCKFV8t3rgHh3Rw==
</wsse:Password>
<wsse:Nonce>WScqanjCEAC4mQoBE07sAQ==</wsse:Nonce>
<wssu:Created>2013-04-16T01:24:32Z</wssu:Created>
</wsse:UsernameToken>
</wsse:Security>
<urn:ESBMetaData>
<urn:OriginalServiceCallerID>SuchAndSuch</urn:OriginalServiceCallerID>
</urn:ESBMetaData>
<urn1:ESBContext soapenv:mustUnderstand="1">
<urn1:BusinessContextType>SuchandSuchSomething</urn1:BusinessContextType>
<urn1:BusinessContextInstanceId>uuid:7dc56353-9069-442d-8b69-163f676dd3e3</urn1:BusinessContextInstanceId>
<urn1:ServiceRequestId>uuid:7dc56353-9069-442d-8b69-163f676dd3e3</urn1:ServiceRequestId>
</urn1:ESBContext>
</soapenv:Header>
As can be seen from the Header, the security is utilizing a Password-Digest and a Nonce. I need to be able to authenticate the users with these details in a WCF Service. (the security cannot be changed, as the 3rd party's system is used by many others)
So far i have setup a simple WCF Service with Data-contracts, Operation-contracts and a Service-contract. I have used a wsHttpBinding with a custom MembershipProvider. See relevant parts of WCF service Web.config below:
<system.web>
<compilation debug="true" targetFramework="4.0"/>
<httpRuntime/>
<membership>
<providers>
<add name="CustomMembershipProvider" type="SupplierEngagementWCFService.Providers.CustomMembershipProvider" />
</providers>
</membership>
</system.web>
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name = "UserNameWS">
<security mode = "Message">
<message clientCredentialType = "UserName"/>
</security>
</binding>
</wsHttpBinding>
</bindings>
<serviceHostingEnvironment aspNetCompatibilityEnabled="false" multipleSiteBindingsEnabled="false"/>
<services>
<service name="SupplierEngagementWCFService.SupplierEngagementService" behaviorConfiguration="Internet">
<endpoint address="" binding="wsHttpBinding" bindingName="UserNameWS" contract="SupplierEngagementWCFService.ISupplierEngagementService"/>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="Internet">
<serviceCredentials>
<userNameAuthentication userNamePasswordValidationMode="MembershipProvider" membershipProviderName="CustomMembershipProvider"/>
</serviceCredentials>
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
Here is my implementation of a membership provider:
public class CustomMembershipProvider : MembershipProvider
{
public override bool ValidateUser(string username, string password)
{
throw new NotImplementedException();
}
}
As you can see it does not provide me with require arguments to check that the password digest is valid. I would need from the header Password-Digest, Nonce, Created date and UserName. So that i may generate a password digest of my own(using the following algorithm) to check that the one sent was generated with the correct password.
Password digest algorithm(pseudo code):
var passwordDigestToCompare = Base64(Sha1(nonce + created + KnownPassword));
if(passwordDigestFromWebServiceCall == passwordDigestToCompare )
{
// digest is valid
}
Creating a custom membership provider does not give me the functionality i require to work with password-digest security.
What should i be doing differently, and what is best practice for implementing WSSE password digest security in a WCF Service?
Upvotes: 3
Views: 1559