本地托管的 WCF 服务 - 我不希望客户端必须进行身份验证

发布于 2024-10-18 16:01:46 字数 2215 浏览 6 评论 0原文

我有一个由桌面应用程序托管的自托管 WCF 服务。
我可以在我的 PC 本地成功连接到该服务,但无法远程使用该服务,至少在不提供 Windows/域级别凭据的情况下。

我使用以下代码在应用程序中启动服务:

ServiceHost host = new ServiceHost(
            typeof (SMService),
            new Uri("net.tcp://localhost:" + SMGlobals._DEFAULTSERVICEPORT.ToString() + "/SMService"));

        host.AddServiceEndpoint(
            typeof(ISMService),
            new NetTcpBinding(),
            "");
        System.ServiceModel.Channels.Binding mexBinding = MetadataExchangeBindings.CreateMexTcpBinding();

        var metadataBehavior =
            new ServiceMetadataBehavior();
        host.Description.Behaviors.Add(metadataBehavior);

        host.AddServiceEndpoint(
            typeof(IMetadataExchange),
            mexBinding,
            "net.tcp://localhost:" + SMGlobals._DEFAULTSERVICEPORT.ToString() + "/SMService/mex");

        host.Open();

        SMGlobals.SMServiceHost = host;

如果我创建一个简单的客户端来使用以下代码调用服务:

var client = new SMServiceClient();
        var uri = "net.tcp://192.168.11.10:8760/SMService";
        client.Endpoint.Address = new EndpointAddress(uri);


        var initiateResponse = client.InitiateAuthentication(new InitiateAuthenticationRequest());

        MessageBox.Show("Success!");

我收到以下异常:

System.ServiceModel.Security.SecurityNegotiationException:服务器已拒绝客户端凭据。 ---> System.Security.Authentication.InvalidCredentialException:服务器已拒绝客户端凭据。 ---> System.ComponentModel.Win32Exception:登录尝试失败

现在,从其他研究中,我发现我可以使用以下代码通过客户端调用提供我的凭据:

var client = new SMServiceClient();
        var uri = "net.tcp://192.168.11.10:8760/SMService";
        client.Endpoint.Address = new EndpointAddress(uri);

        client.ClientCredentials.Windows.ClientCredential.Domain = "domain";
        client.ClientCredentials.Windows.ClientCredential.UserName = "my_user_name";
        client.ClientCredentials.Windows.ClientCredential.Password = "my_password";

        var initiateResponse = client.InitiateAuthentication(new InitiateAuthenticationRequest());

        MessageBox.Show("Success!");

现在,代码成功完成。

我很难弄清楚如何删除这个要求。我尝试过修改客户端上的绑定设置,但没有成功。

有人能指出我正确的方向吗?

I have a self-hosted WCF service that is hosted by a desktop application.
I can successfully connect to the service locally on my PC, but I can't use the service remotely, at least without providing my windows/domain level credentials.

I use the following code to start the service in the app:

ServiceHost host = new ServiceHost(
            typeof (SMService),
            new Uri("net.tcp://localhost:" + SMGlobals._DEFAULTSERVICEPORT.ToString() + "/SMService"));

        host.AddServiceEndpoint(
            typeof(ISMService),
            new NetTcpBinding(),
            "");
        System.ServiceModel.Channels.Binding mexBinding = MetadataExchangeBindings.CreateMexTcpBinding();

        var metadataBehavior =
            new ServiceMetadataBehavior();
        host.Description.Behaviors.Add(metadataBehavior);

        host.AddServiceEndpoint(
            typeof(IMetadataExchange),
            mexBinding,
            "net.tcp://localhost:" + SMGlobals._DEFAULTSERVICEPORT.ToString() + "/SMService/mex");

        host.Open();

        SMGlobals.SMServiceHost = host;

If I create a simple client to call the service using the following code:

var client = new SMServiceClient();
        var uri = "net.tcp://192.168.11.10:8760/SMService";
        client.Endpoint.Address = new EndpointAddress(uri);


        var initiateResponse = client.InitiateAuthentication(new InitiateAuthenticationRequest());

        MessageBox.Show("Success!");

I receive the following exception:

System.ServiceModel.Security.SecurityNegotiationException: The server has rejected the client credentials. ---> System.Security.Authentication.InvalidCredentialException: The server has rejected the client credentials. ---> System.ComponentModel.Win32Exception: The logon attempt failed

Now, from other research, I have discovered that I could provide my credentials with the client call using the following code:

var client = new SMServiceClient();
        var uri = "net.tcp://192.168.11.10:8760/SMService";
        client.Endpoint.Address = new EndpointAddress(uri);

        client.ClientCredentials.Windows.ClientCredential.Domain = "domain";
        client.ClientCredentials.Windows.ClientCredential.UserName = "my_user_name";
        client.ClientCredentials.Windows.ClientCredential.Password = "my_password";

        var initiateResponse = client.InitiateAuthentication(new InitiateAuthenticationRequest());

        MessageBox.Show("Success!");

And now, the code successfully completes.

I'm having a hard time figuring out how to remove this requirement. I've tried messing around with the binding setup on the client without success.

Can anyone point me in the right direction?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

酒绊 2024-10-25 16:01:46

Tcp 绑定默认启用安全性,因此要获得您想要的功能,您需要显式将其关闭。像这样添加您的端点。您还可以浏览 NetTcpBinding 的 MSDN 帮助,因为您可能希望使用备用构造函数来关闭可靠消息传递。

 host.AddServiceEndpoint(
            typeof(ISMService),
            new NetTcpBinding(SecurityMode.None),
            "");

A Tcp Binding has security enabled by default, so to get what you want, you need to explicitly turn it off. Add your endpoint like this. You might also explore the MSDN help for NetTcpBinding as you might want to user an alternate constructor to also switch off reliable messaging.

 host.AddServiceEndpoint(
            typeof(ISMService),
            new NetTcpBinding(SecurityMode.None),
            "");
枫林﹌晚霞¤ 2024-10-25 16:01:46

我有类似的问题。在两个进程之间本地工作,但当两个进程放在不同的计算机上时(或在本地使用解析到本地计算机的公共 URL,例如 mylocalmachine.corp.com),相同的代码会失败。我发现我需要将匿名绑定的安全性显式设置为“无”:

<binding name="TcpAnonymousBinding" portSharingEnabled="true" receiveTimeout="24:00:00">
    <security mode="None"/>
</binding>

I had a similar issue. Worked locally between two processes but the same code failed when the two processes were put on different machines (or locally using a public URL that resolved to the local machine, e.g. mylocalmachine.corp.com). I found that I needed to explicitly set the Anonymous binding's security to 'None':

<binding name="TcpAnonymousBinding" portSharingEnabled="true" receiveTimeout="24:00:00">
    <security mode="None"/>
</binding>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文