Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/wcf/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# WCF Rest自托管证书安全服务返回401未经授权_C#_Wcf_Authentication_Ssl Certificate_Webhttpbinding - Fatal编程技术网

C# WCF Rest自托管证书安全服务返回401未经授权

C# WCF Rest自托管证书安全服务返回401未经授权,c#,wcf,authentication,ssl-certificate,webhttpbinding,C#,Wcf,Authentication,Ssl Certificate,Webhttpbinding,我想使用证书rest服务创建一个WCF控制台自托管服务器端身份验证 我在实际调用服务时遇到了一个问题,因为我总是得到未经授权的响应 既然这是一种“单向”身份验证,其中服务向客户机标识自己,为什么我总是作为客户机应用程序获得401未经验证的响应(好像客户机需要向服务标识自己才能访问其资源?) 有谁能帮我找出哪里出了问题,以及如何让我的客户服务沟通最终发挥作用 简单服务合同: [ServiceContract] public interface IService1 { [Operation

我想使用证书rest服务创建一个WCF控制台自托管服务器端身份验证

我在实际调用服务时遇到了一个问题,因为我总是得到未经授权的响应

既然这是一种“单向”身份验证,其中服务向客户机标识自己,为什么我总是作为客户机应用程序获得401未经验证的响应(好像客户机需要向服务标识自己才能访问其资源?)

有谁能帮我找出哪里出了问题,以及如何让我的客户服务沟通最终发挥作用

简单服务合同:

[ServiceContract]
public interface IService1
{

    [OperationContract]
    [WebGet(UriTemplate = "Students", ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json)]
    List<Student> GetStudentDetails();

    // TODO: Add GetMethod with parameter 
    [OperationContract]
    [WebGet(UriTemplate = "Student/{id}", ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json)]
    Student GetStudentWithId(string id);

    //TODO: add one post method here
    [OperationContract]
    [WebInvoke(Method="POST", UriTemplate = "Student/New", ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json)]
    void NewStudent(Stream stream);

    //TODO: add one post method here
    [OperationContract]
    [WebInvoke(Method = "POST", UriTemplate = "Student/NewS", ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json)]
    void NewStudentS(Student stream);
}

// Use a data contract as illustrated in the sample below to add composite types to service operations.
[DataContract]
public class Student
{
    [DataMember]
    public int ID
    {
        get;
        set;
    }

    [DataMember]
    public string Name
    {
        get;
        set;
    }
}

向您致以最良好的问候并提前向您表示感谢,您正在将证书映射到端口8080,以使
https
协议正常工作。 在这一刻之前都很好

然而,401错误意味着服务需要来自客户端的一些凭据(如果有,则引发401错误)

请尝试删除(或注释)
SetCertificate
方法调用,如下所示

           //Add host certificate to service wcf for identification
            //host.Credentials.ServiceCertificate.SetCertificate(
            //    StoreLocation.LocalMachine,
            //    StoreName.My,
            //    X509FindType.FindBySubjectName,
            //    "localhost");
试试看它是否管用。只是检查一下

具有证书的Wcf传输安全性要求客户端也指定证书

我不确定您是否可以使用soap协议和
HttpWebRequest
使用带有证书身份验证的wcf服务。它要求使用具有
SetCertificate
方法的wcf客户端:

// The client must specify a certificate trusted by the server.  
cc.ClientCredentials.ClientCertificate.SetCertificate(  
    StoreLocation.CurrentUser,  
    StoreName.My,  
    X509FindType.FindBySubjectName,  
    "contoso.com");  
(这是文档中的示例)

WSHttpBinding=新的WSHttpBinding()
binding.Name=“binding1”
binding.Security.Mode=SecurityMode.Transport

上面的代码采用windows身份验证作为对客户端进行身份验证的方法

        //this is the default value unless we specify it manually.
        binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Windows;
因此,我们应该通过提供windows凭据在客户端调用它。 此外,这种WCF服务不是RESTAPI,而是SOAP web服务。我们通常使用客户端代理来调用它。

然后设置windows凭据并调用该方法

            ServiceReference1.ServiceClient client = new ServiceReference1.ServiceClient();
            //these are windows accounts on the server-side.
            client.ClientCredentials.Windows.ClientCredential.UserName = "administrator";
            client.ClientCredentials.Windows.ClientCredential.Password = "123456";
            var result = client.Test();
            Console.WriteLine(result);
如果我们想创建rest服务,请使用Webhttpbinding创建该服务

            WebHttpBinding binding = new WebHttpBinding();
            binding.Security.Mode = WebHttpSecurityMode.Transport;
            //this is default value. 
            binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None;
同样,我们需要将证书绑定到特定端口,以使传输层安全性可用

netsh http add sslcert ipport=0.0.0.0:8000 certhash=0000000000003ed9cd0c315bbb6dc1c08da5e6 appid={00112233-4455-6677-8899-AABBCCDDEEFF}

Netsh Http命令。

因此,验证客户端的安全模式是
HttpClientCredentialType.None
。我们不需要在客户端提供windows凭据。

如果有什么我能帮忙的,请随时告诉我。

你好,亚伯拉罕。谢谢你的详细答复。问题似乎在于我使用了错误的绑定类型,并且没有将ClientCredentialType设置为“none”。非常感谢你的帮助!
        //this is the default value unless we specify it manually.
        binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Windows;
            ServiceReference1.ServiceClient client = new ServiceReference1.ServiceClient();
            //these are windows accounts on the server-side.
            client.ClientCredentials.Windows.ClientCredential.UserName = "administrator";
            client.ClientCredentials.Windows.ClientCredential.Password = "123456";
            var result = client.Test();
            Console.WriteLine(result);
            WebHttpBinding binding = new WebHttpBinding();
            binding.Security.Mode = WebHttpSecurityMode.Transport;
            //this is default value. 
            binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None;