WCF身份验证 - 使用ASPNET成员身份的TransportCredentialOnly

时间:2013-11-25 05:22:30

标签: asp.net vb.net wcf

我觉得我很接近,但我是WCF的新手,无法弄清楚为什么这不起作用。我试过搜索,但是我找不到使用aspnet成员资格而不使用消息级别安全性的示例。我正在尝试通过https从Android到WCF服务进行身份验证。它工作得很好,直到我将clientCredentialType从'None'更改为'Basic'。我必须通过用户名和密码进行身份验证。当我尝试通过对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

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

1 个答案:

答案 0 :(得分: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>