WCF身份验证不会提示输入凭据

WCF身份验证不会提示输入凭据

问题描述:

我已经创建了一个测试WCF应用程序,其中我试图使身份验证正常工作,但它只是运行我的方法,并未要求我登录/验证身份。下面的代码片段在我的web.config中我的WCF应用程序:WCF身份验证不会提示输入凭据

<bindings> 
     <wsHttpBinding> 
      <binding name="Binding1"> 
       <security mode="Message"> 
        <message clientCredentialType="UserName" /> 
       </security> 
      </binding> 
     </wsHttpBinding> 
</bindings> 

<serviceCredentials> 
     <userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="MyAPI.Authorization, App_Code" /> 
</serviceCredentials> 

我的授权类:

public class Authorization : UserNamePasswordValidator 
    { 
     public override void Validate(string userName, string password) 
     { 
      if (null == userName || null == password) 
      { 
       throw new ArgumentNullException(); 
      } 

      if (!(userName == "test1" && password == "1tset") && !(userName == "test2" && password == "2tset")) 
      { 
       // This throws an informative fault to the client. 
       throw new FaultException("Unknown Username or Incorrect Password"); 
       // When you do not want to throw an infomative fault to the client, 
       // throw the following exception. 
       // throw new SecurityTokenException("Unknown Username or Incorrect Password"); 
      } 
     } 
    } 

我Service.svc.cs类

public string Hello(string message) 
{ 
    return "You typed: " + message; 
} 

我应该在该方法之上放置一些属性以要求验证或在类之上?

我已经然后创建了一个测试控制台应用程序,这里是代码:

public static Test.Service1Client client = new Test.Service1Client(); 
     static void Main(string[] args) 
     { 
      Console.WriteLine(client.Hello("hello")); 
      Console.ReadLine(); 
     } 

这只是输出“您输入:你好”不要求身份验证。这里是我的app.config的片段:

<system.serviceModel> 
     <bindings> 
      <basicHttpBinding> 
       <binding name="BasicHttpBinding_IService1" closeTimeout="00:01:00" 
        openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" 
        allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard" 
        maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536" 
        messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered" 
        useDefaultWebProxy="true"> 
        <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384" 
         maxBytesPerRead="4096" maxNameTableCharCount="16384" /> 
        <security mode="None"> 
         <transport clientCredentialType="None" proxyCredentialType="None" 
          realm="" /> 
         <message clientCredentialType="UserName" algorithmSuite="Default" /> 
        </security> 
       </binding> 
      </basicHttpBinding> 
     </bindings> 
     <client> 
      <endpoint address="http://MyServer/Service1.svc" binding="basicHttpBinding" 
       bindingConfiguration="BasicHttpBinding_IService1" contract="Test.IService1" 
       name="BasicHttpBinding_IService1" /> 
     </client> 
    </system.serviceModel> 

我希望有设置登录凭据做致电client.Hello("hello")前:

client.ClientCredentials.UserName.UserName = "test1"; 
client.ClientCredentials.UserName.Password = "1tset"; 

但显然不是

编辑

<?xml version="1.0"?> 
<configuration> 

    <system.web> 
     <compilation debug="true" targetFramework="4.0" /> 
    </system.web> 
    <system.serviceModel> 
     <bindings> 
      <wsHttpBinding> 
       <binding name="Binding1"> 
        <security mode="Message"> 
         <message clientCredentialType="UserName" /> 
        </security> 
       </binding> 
      </wsHttpBinding> 
     </bindings> 
     <behaviors> 
      <serviceBehaviors> 
       <behavior> 
        <serviceCredentials> 
    <userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="MyAPI.Authorization, App_Code" /> 
</serviceCredentials> 
        <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment --> 
        <serviceMetadata httpGetEnabled="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"/> 
       </behavior> 
      </serviceBehaviors> 
     </behaviors> 
     <serviceHostingEnvironment multipleSiteBindingsEnabled="true" /> 
    </system.serviceModel> 
    <system.webServer> 
     <modules runAllManagedModulesForAllRequests="true"/> 
    </system.webServer> 

</configuration> 
+0

通常,客户端(如浏览器)会提示输入凭据。你的测试控制台应用程序不会提示,因为你没有这样编码。如果您没有提供凭据,那么服务调用应该失败。检查您是否绑定了服务,并在服务器配置中绑定Binding1。 – VinayC 2012-03-22 11:07:28

+0

@VinayC - 我在哪里看到?看到我的编辑,它包含我的服务中的整个web.config文件 – CallumVass 2012-03-22 11:27:05

看起来您正在使用错误的绑定,客户端正在使用BasicHttp在服务器上定义WsHttpBinding时绑定。

WCF/IIS将神奇地连接你没有配置需要的服务(现在不记得这个功能的名字...)。然而,你正在定义一些自定义绑定配置 - 这很好,但你需要告诉你的服务使用它。

你需要一个<service>元素添加到您的服务器的配置,这样的:

<system.serviceModel> 
    ... 
    <services> 
     <service name="FullClassNameOfYourService"> 
     <endpoint binding="wsHttpBinding" 
        bindingConfiguration="Binding1" 
        contract="FullClassNameOfYourServiceContract" /> 
     </service> 
    </services> 

而且,事实上,你的客户端配置不包含wsHttpBinding元素表明HTTPS没有为网站启用托管您的服务。

+0

我现在得到:在服务'Service1'实现的合同列表中找不到合同名称'MyAPI.IService1'。 – CallumVass 2012-03-22 11:44:18

+0

“name”属性的值是否为“Serivce1”?根据您的合同类型,我认为服务名称应该是“MyAPI.Service1” - 类名也需要命名空间。 – 2012-03-22 11:48:02

+0

我有这一套:' ' – CallumVass 2012-03-22 11:48:54

您的userNameAuthentication不正确。 customUserNamePasswordValidatorType的格式必须是“[完全合格的程序集+类名],[名称空间]”。我不能告诉你的命名空间是从您的文章是什么,但这样的:

<userNameAuthentication userNamePasswordValidationMode="Custom" 
customUserNamePasswordValidatorType="MyNamespace.Authorization , MyNamespace" /> 

正如其他人所说,您的客户端必须使用相同的绑定类型连接到服务。

此外,在您的服务器端,您已将安全模式设置为无,但您有传输和消息标记。在安全标签内。如果您没有将“无”作为安全性,则任何传输和邮件安全规范都将被忽略。换句话说,在安全模式为None的情况下,您的客户端凭证类型将被忽略,因此客户端无需进行身份验证。

+0

我试过,但它一直抛出一个错误,所以这就是为什么我把我的授权类内App_Code和使用它,它的工作!我现在把安全类型设置为Transport,并在客户端和服务器上设置相同的绑定类型(都使用basicHttpbinding),但出现以下错误:'提供的URI方案'http'无效;预计'https'。 参数名称:via' – CallumVass 2012-03-22 13:02:33

+0

“一个错误”对我没有多大帮助。你如何知道,如果你得到一个不同的错误,把它放在App_Code的作品?如果它正在查找https,那似乎表明您已指定传输级别安全性。 – 2012-03-22 13:32:49

+0

由“一个错误”,我的意思是它抛出一个错误,直到我改变它使用App_Code,然后它“工作”,即没有抛出一个错误,但多数民众赞成在这里不是问题 – CallumVass 2012-03-22 14:18:52

您可以使用具有简化配置文件的WCF 4。它有其优点,但更难调试它。我怀疑你的自定义wshttpbinding不适用。尝试更详细的配置(如wcf 3.5):

<system.serviceModel> 
    <bindings> 
     <wsHttpBinding> 
     <binding name="NewBinding0"> 
      <security mode="TransportWithMessageCredential"> 
      <message clientCredentialType="UserName" /> 
      </security> 
     </binding> 
     </wsHttpBinding> 
    </bindings> 
    <services> 
     <service behaviorConfiguration="WcfService6.Service1Behavior" 
     name="WcfService6.Service1"> 
     <endpoint address="" binding="wsHttpBinding" bindingConfiguration="NewBinding0" 
      contract="WcfService6.IService1"> 
      <identity> 
      <dns value="localhost" /> 
      </identity> 
     </endpoint> 
     <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" /> 
     </service> 
    </services> 
    <behaviors> 
     <serviceBehaviors> 
     <behavior name="WcfService6.Service1Behavior"> 
      <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment --> 
      <serviceMetadata httpGetEnabled="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"/> 
     </behavior> 
     </serviceBehaviors> 
    </behaviors> 
    </system.serviceModel>