使用WSSE安全性创建WCF服务(PasswordDigest)

时间:2015-01-29 10:25:01

标签: c# wcf wcf-binding wcf-security wsse

我需要创建一个符合Oasis 2004标准的安全WCF Web服务(http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd

我收到了示例请求,这些请求将由第三方发送给我。请求的主体并不重要,但我会在这里显示标题(一些数据已被更改以保护身份):

<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();
     }
}

正如您所看到的,它没有为我提供require参数来检查密码摘要是否有效。我需要从标题密码 - 摘要,Nonce,创建日期和用户名。这样我就可以生成自己的密码摘要(使用以下算法)来检查发送的密码摘要是否使用正确的密码生成。

密码摘要算法(伪代码):

var passwordDigestToCompare = Base64(Sha1(nonce + created + KnownPassword));

if(passwordDigestFromWebServiceCall == passwordDigestToCompare )
{
    // digest is valid
}

创建自定义成员资格提供程序并不能提供我使用密码摘要安全性所需的功能。

我应该做些什么,以及在WCF服务中实施WSSE密码摘要安全性的最佳做法是什么?

0 个答案:

没有答案