【问题标题】:WCF Authentication - TransportCredentialOnly with ASPNET MembershipWCF 身份验证 - 仅具有 ASPNET 成员身份的 TransportCredentialOnly
【发布时间】:2013-11-25 05:22:29
【问题描述】:

我觉得我很接近,但我是 WCF 的新手,无法弄清楚为什么这不起作用。我已经尝试过搜索,但我找不到在不使用消息级别安全性的情况下使用 aspnet 成员资格的示例。我正在尝试通过 https 从 Android 到 WCF 服务进行身份验证。在我将 clientCredentialType 从“无”更改为“基本”之前,它工作得很好。我必须通过用户名和密码进行身份验证。当我尝试通过针对https://myPublicWebsite/ABCService/ABC.svc 运行 slsvcutil.exe 来更新我的代理时,它会出现以下错误:

主机上配置的身份验证方案(“IntegratedWindowsAuthentication, Anonymous”)不允许在绑定“BasicHttpBinding”(“Basic”)上配置的身份验证方案。请确保将 SecurityMode 设置为 Transport 或 TransportCredentialOnly。此外,可以通过 IIS 管理工具、通过 ServiceHost.Authentication.AuthenticationSchemes 属性、在元素的应用程序配置文件中更改此应用程序的身份验证方案、通过更新绑定上的 ClientCredentialType 属性或通过调整来解决此问题HttpTransportBindingElement 上的 AuthenticationScheme 属性。

这是我的服务的 web.config。感谢您能给我的任何帮助。

    <system.web>
    <compilation debug="false" strict="false" explicit="true" targetFramework="4.0" />
    <customErrors mode="Off" />

    <membership defaultProvider="AspNetSqlMembershipProvider" userIsOnlineTimeWindow="15">
      <providers>
        <remove name="AspNetSqlMembershipProvider" />
        <clear />
        <add
          name="AspNetSqlMembershipProvider"
          type="System.Web.Security.SqlMembershipProvider"
          connectionStringName="LocalSqlServer"
          applicationName="ABC"
          enablePasswordRetrieval="false"
          enablePasswordReset="false"
          requiresQuestionAndAnswer="false"
          minRequiredPasswordLength="8"
          requiresUniqueEmail="true"
          passwordFormat="Hashed" />
      </providers>
    </membership>
  </system.web>

  <system.serviceModel>
    <services>
      <service name="ABCService.ABC" behaviorConfiguration="metadataBehavior">
        <endpoint
            address=""
            binding="basicHttpBinding"
            bindingConfiguration="ABCBinding"
            contract="ABCService.IService1"/>
      </service>
    </services>

    <behaviors>
      <serviceBehaviors>
        <behavior name="metadataBehavior">
          <serviceMetadata httpGetEnabled="false" httpsGetEnabled="true"/>
          <serviceDebug includeExceptionDetailInFaults="false"/>
          <serviceCredentials>
            <userNameAuthentication
            userNamePasswordValidationMode="MembershipProvider"
            membershipProviderName="AspNetSqlMembershipProvider" />
          </serviceCredentials>
        </behavior>
      </serviceBehaviors>
    </behaviors>

    <bindings>
      <basicHttpBinding>
        <binding name="ABCBinding">
          <security mode="TransportCredentialOnly">
            <transport clientCredentialType="Basic" />
          </security>
        </binding>
      </basicHttpBinding>
    </bindings>

    <protocolMapping>
      <add binding="basicHttpsBinding" scheme="https"/>
    </protocolMapping>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true"/>
  </system.serviceModel>
  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>    
    <directoryBrowse enabled="false"/>
  </system.webServer>

另外,我应该在服务代码中添加什么来运行验证检查?我有这个:

Public Class MyCustomUserNameValidator
    Inherits IdentityModel.Selectors.UserNamePasswordValidator

    ' This method validates users. It allows two users, test1 and test2  
    ' with passwords 1tset and 2tset respectively. 
    ' This code is for illustration purposes only and  
    ' MUST NOT be used in a production environment because it is NOT secure.     
    Public Overrides Sub Validate(ByVal userName As String, ByVal password As String)
        If Nothing = userName OrElse Nothing = password Then
            Throw New ArgumentNullException()
        End If

        If Not (userName = "test1" AndAlso password = "1tset") AndAlso Not (userName = "test2" AndAlso password = "2tset") Then
            Throw New IdentityModel.Tokens.SecurityTokenException("Unknown Username or Password")
        End If

    End Sub
End Class

但我真的不明白它是如何工作的,因为我从不调用它,我宁愿使用默认的而不是自定义的。我确信这很简单,但我可以通过搜索找到的所有示例都是“自定义”验证器。这会自动调用吗?或者如果我只想要默认值,我什至需要它?

【问题讨论】:

    标签: asp.net vb.net wcf


    【解决方案1】:

    您使用的是 IIS 吗?您需要在 IIS 中安装并启用基本身份验证。

    但是,即使您启用了基本身份验证,您也只能在基于消息的安全性中以及当 clientCredentialType 设置为 UserName 时使用成员资格提供程序和自定义验证程序。像 TransportCredentialOnly 和 Transport 这样的纯基于传输的安全模式将不起作用。

    Reference - go to the Authentication section

    这应该适用于 wsHttpBinding

    <security mode="Message">
       <message clientCredentialType="UserName" />
    </security>
    

    wsHttpBinding 和 basicHttpBinding 的另一种可能性

    <security mode="TransportWithMessageCredential">
       <message clientCredentialType="UserName" />
    </security>
    

    【讨论】:

    • 你是对的。但是,我使用的是 Xamarin,它们还不支持使用消息安全性。是否可以在不使用 Active Directory 的情况下使用传输和基本安全性?我可以通过其他方式使用会员提供商吗?
    • 我正在尝试关注leastprivilege.com/2007/10/31/…,但我得到了同样的错误。奇怪的是,我已将 IIS 设置更改为 authentication="None",当我浏览该站点时,仍然会提示输入 Windows 凭据。任何想法?非常感谢!
    • IIS -> 站点 -> 您的网站 -> 身份验证 -> 如果您想在没有身份验证的情况下访问,请启用匿名身份验证。启用基本身份验证以解决您的原始问题。如果这些选项不存在,您需要安装它们(请参阅我更新的答案)。但是,我无法在您指出的博客中提出解决方案。它根本不调用自定义的 UserNamePasswordValidator。
    • 我真的认为这篇博文是错误的。你可以试试这个custombasicauth.codeplex.com 或阅读wcfsecurityguide.codeplex.com 的第 13 章。两者都采用相同的方法,即创建一个自定义的基本身份验证 HTTP 模块。
    猜你喜欢
    • 1970-01-01
    • 2012-07-05
    • 1970-01-01
    • 2016-02-11
    • 2011-08-18
    • 1970-01-01
    • 2011-07-06
    相关资源
    最近更新 更多