【问题标题】:WCF Service with username security not working具有用户名安全性的 WCF 服务不起作用
【发布时间】:2014-04-25 18:12:44
【问题描述】:

我之前创建了一些 wcf 服务,但从未实现过安全性。现在我正在尝试为我的 wcf 服务实现用户名安全。经过一些研究,使用 wsHttpBinding 实现了服务的安全性。但是当我尝试使用 SOAPUI 工具测试服务时,我收到了一些奇怪的消息并且找不到什么问题。请帮我找出问题所在。

这是我的验证类。

namespace WDARProductsService
{
    public class MyAuthentication : UserNamePasswordValidator
    {
        public override void Validate(string userName, string password)
        {
            if (string.IsNullOrWhiteSpace(userName))
                throw new SecurityTokenException("userName required");

            if (string.IsNullOrWhiteSpace(password))
                throw new SecurityTokenException("password required");

            if (userName.ToLower() != "someusername" && password != "somepassword")
                throw new FaultException("userName and/or password is invalid.");
        }
    }
}

这是我的 wcf 配置。

 <system.serviceModel>
    <behaviors>
      <serviceBehaviors>
        <behavior name="svcbhvr1">
          <!-- To avoid disclosing metadata information, set the values below to false before deployment -->
          <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
          <!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information -->
          <serviceDebug includeExceptionDetailInFaults="false"/>
          <serviceCredentials>
            <userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="WDARProductsService.MyAuthentication, WDARProductsService"/>
            <serviceCertificate findValue="WDARProdService"
                          storeLocation="LocalMachine"
                          storeName="Root"
                          x509FindType="FindBySubjectName" />
          </serviceCredentials>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <bindings>
      <wsHttpBinding>
        <binding name="wshbinding">
          <security mode="Message">
            <message clientCredentialType="UserName"/>
          </security>
        </binding>
      </wsHttpBinding>
    </bindings>
    <services>
      <service name="WDARProductsService.ProductService" behaviorConfiguration="svcbhvr1">
        <endpoint address="" binding="wsHttpBinding" bindingConfiguration="wshbinding" contract="WDARProductsService.IProductService" ></endpoint>
      </service>
    </services>

    <serviceHostingEnvironment aspNetCompatibilityEnabled="false" multipleSiteBindingsEnabled="true" />
  </system.serviceModel>

这是我从 SOAPUI 发送的 SOAP 消息。

<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:tem="http://tempuri.org/">
  <soap:Header>
    <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-38DE8B83BF5FAA37EE13984444482027">
        <wsse:Username>someusername</wsse:Username>
        <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">somepassword</wsse:Password>
        <wsse:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">vkis9SvbH3lnvdNWR/L5nA==</wsse:Nonce>
        <wsu:Created>2014-04-25T16:47:28.202Z</wsu:Created>
      </wsse:UsernameToken>
    </wsse:Security>
  </soap:Header>
  <soap:Body>
    <tem:GetProducts>
    </tem:GetProducts>
  </soap:Body>
</soap:Envelope>

这是来自服务器的响应。

<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing">
   <s:Header>
      <a:Action s:mustUnderstand="1">http://www.w3.org/2005/08/addressing/soap/fault</a:Action>
   </s:Header>
   <s:Body>
      <s:Fault>
         <s:Code>
            <s:Value>s:Sender</s:Value>
            <s:Subcode>
               <s:Value xmlns:a="http://schemas.xmlsoap.org/ws/2005/02/sc">a:BadContextToken</s:Value>
            </s:Subcode>
         </s:Code>
         <s:Reason>
            <s:Text xml:lang="en-US">The message could not be processed. This is most likely because the action 'http://tempuri.org/IProductService/GetProducts' is incorrect or because the message contains an invalid or expired security context token or because there is a mismatch between bindings. The security context token would be invalid if the service aborted the channel due to inactivity. To prevent the service from aborting idle sessions prematurely increase the Receive timeout on the service endpoint's binding.</s:Text>
         </s:Reason>
      </s:Fault>
   </s:Body>
</s:Envelope>

谁能帮我找出问题所在。谢谢大家。

【问题讨论】:

    标签: c# web-services wcf soap ws-security


    【解决方案1】:

    默认情况下,将 Security 设置为 Message 的 WsHttpBinding 将启用安全上下文: 见:http://msdn.microsoft.com/en-us/library/system.servicemodel.wshttpsecurity.message.aspx

    因此,在您发送包含用户名令牌的消息之前。您需要建立安全的对话。我不知道 SoapUI 是否支持它,但你可以找到一些提示: WCF wsHttpBinding in SoapUI

    如果您不想使用安全对话,请将建立安全上下文设置为 false。如果您计划在生产中使用它,请考虑使用 TransportWithMessageCredential 来使用 SSL 加密消息。

    【讨论】:

      猜你喜欢
      • 2011-06-08
      • 1970-01-01
      • 2016-07-28
      • 2019-09-14
      • 2013-09-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多