我需要创建一个符合 Oasis 2004 标准的安全 WCF Web 服务(http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd)
我收到了示例请求,这些请求将由第 3 方发送给我。请求的正文并不重要,但我将在此处显示标头(某些数据已更改以保护身份):
<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>
从 Header 中可以看出,安全性使用了 Password-Digest 和 Nonce。我需要能够在 WCF 服务中使用这些详细信息对用户进行身份验证。(安全不能更改,因为第三方的系统被许多其他人使用)
到目前为止,我已经设置了一个简单的 WCF 服务,其中包含数据合同、操作合同和服务合同。我使用了带有自定义 MembershipProvider 的 wsHttpBinding。请参阅下面的 WCF 服务 Web.config 的相关部分:
<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>
这是我对会员提供程序的实现:
public class CustomMembershipProvider : MembershipProvider
{
public override bool ValidateUser(string username, string password)
{
throw new NotImplementedException();
}
}
如您所见,它没有为我提供检查密码摘要是否有效的要求参数。我需要标题密码摘要、随机数、创建日期和用户名。这样我就可以生成自己的密码摘要(使用以下算法)以检查发送的密码是否使用正确的密码生成。
密码摘要算法(伪代码):
var passwordDigestToCompare = Base64(Sha1(nonce + created + KnownPassword));
if(passwordDigestFromWebServiceCall == passwordDigestToCompare )
{
// digest is valid
}
创建自定义成员资格提供程序并没有为我提供使用密码摘要安全性所需的功能。
我应该做些什么不同的事情,在 WCF 服务中实现 WSSE 密码摘要安全性的最佳实践是什么?