为简单的WCF服务启用基本身份验证? [英] Turn on Basic Authentication for a simple WCF service?

查看:334
本文介绍了为简单的WCF服务启用基本身份验证?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个非常简单的WCF网络服务,客户在他们自己的IIS上托管。

I have a very simple WCF webservice that a customer is hosting on their own IIS.

客户有他们自己的客户端,他们一直在测试它,在他们的测试环境中,一切正常,直到他们禁用匿名身份验证并启用基本身份验证。一旦他们这样做,他们就开始收到错误:

The customer has their own client that they've been testing against it, in their testing environment, and everything was working fine, until they disabled anonymous authentication and enabled basic. Once they did, they started getting errors:

The authentication schemes configured on the host ('Basic') do not allow those configured on the binding 'BasicHttpBinding' ('Anonymous'). Please ensure that the SecurityMode is set to Transport or TransportCredentialOnly. 

那么,我需要做什么才能让基本身份验证工作?

So, what do I need to do, to get basic authentication working?

我的网络服务的当前web.config:

My webservice's current web.config:

<configuration>
    <system.web>
        <compilation debug="true" targetFramework="4.5" />
        <httpRuntime targetFramework="4.5" />
    </system.web>
    <system.serviceModel>
        <behaviors>
            <serviceBehaviors>
                <behavior name="">
                    <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
                    <serviceDebug includeExceptionDetailInFaults="false" />
                </behavior>
            </serviceBehaviors>
        </behaviors>
        <serviceHostingEnvironment aspNetCompatibilityEnabled="true"
            multipleSiteBindingsEnabled="true" />
    </system.serviceModel>
</configuration>

我有自己的测试客户端,我可以针对我的webservice运行。它是当前的app.config:

I have my own test client, that I can run against my webservice. It's current app.config:

<configuration>
    <startup>
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
    </startup>
    <system.serviceModel>
        <bindings>
            <basicHttpBinding>
                <binding name="BasicHttpBinding_IMyServiceSvc" />
            </basicHttpBinding>
        </bindings>
        <client>
            <endpoint address="http://localhost/MyServiceSvc.svc"
                binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IMyServiceSvc"
                contract="MyServiceSvc.IMyServiceSvc"
                name="BasicHttpBinding_IMyServiceSvc" />
        </client>
    </system.serviceModel>
</configuration>

当我在本地IIS上安装服务,并针对它运行客户端时,一切正常,启用匿名身份验证。

When I install the service on my local IIS, and run the client against it, everything works, with anonymous authentication enabled.

在IIS中启用基本身份验证以及配置客户端和服务器以使用基本身份验证需要执行哪些操作?

What do I need to do to turn on basic authentication, in IIS, and to configure both client and server to use basic authentication?

我当前的测试客户代码:

My current test client code:

public class BlackHillsCompletionSvcTest
{
    static void Main(string[] args)
    {
        using (var client = new MyServiceSvcClient())
        {
            var data = new Data
            {
                id = "1",
                description = "test data"
            };

            try
            {
                var result = client.receiveData(data);
            }
            catch (Exception ex)
            {
                var msg = ex.Message;
            }
        }
    }
}

= =尝试:==

根据Pankaj Kapare的建议,我将此添加到webservice的web.config中:

As per Pankaj Kapare's suggestion, I added this to the webservice's web.config:

<system.serviceModel>
    <bindings>
        <basicHttpBinding>
            <binding name="httpBinding">
                <security mode="TransportCredentialOnly">
                    <transport clientCredentialType="Basic" />
                </security>
            </binding>
        </basicHttpBinding>
    </bindings>
    ...
</system.serviceModel>

有了这个,我在创建客户端时遇到错误:

With that, I got an error when creating the client:

The binding at system.serviceModel/bindings/basicHttpBinding does not have a configured binding named 'BasicHttpBinding_IMyServiceSvc'. This is an invalid value for bindingConfiguration. 

所以我添加到客户端的app.config:

So I added, to the client's app.config:

<system.serviceModel>
    <bindings>
        <basicHttpBinding>
            <binding name="BasicHttpBinding_IMyServiceSvc">
                <security mode="TransportCredentialOnly">
                    <transport clientCredentialType="Basic" />
                </security>
            </binding>
        </basicHttpBinding>
    </bindings>
    ...
</system.serviceModel>

有了这个,我又收到了一个错误:

With that, I got another error:

The username is not provided. Specify username in ClientCredentials.

所以我在我的客户端添加了用户名和密码:

So I added username and password in my client:

using (var client = new MyServiceSvcClient())
{
    client.ClientCredentials.UserName.UserName = "myusername";
    client.ClientCredentials.UserName.Password = "mypassword";
    ...
}

然后又出现了另一个错误:

And with that, I get yet another error:

The requested service, 'http://localhost/MyServiceSvc.svc' could not be activated.  Which got me wondering. So I loaded the .svc page in my browser, was asked to log in, and after I did, I saw this:

The authentication schemes configured on the host ('Basic') do not allow those configured on the binding 'BasicHttpBinding' ('Anonymous').  Please ensure that the SecurityMode is set to Transport or TransportCredentialOnly.  Additionally, this may be resolved by changing the authentication schemes for this application through the IIS management tool, through the ServiceHost.Authentication.AuthenticationSchemes property, in the application configuration file at the <serviceAuthenticationManager> element, by updating the ClientCredentialType property on the binding, or by adjusting the AuthenticationScheme property on the HttpTransportBindingElement.

客户看到的是什么。

想法?

==也许解决方案? ==

== Maybe a solution? ==

我认为可能缺少的是服务器上的服务定义,将绑定绑定到端点:

I think what may have been missing was a service definition, on the server, tying the binding to the endpoint:

<system.serviceModel>
    <bindings>
        <basicHttpBinding>
            <binding name="httpBinding">
                <security mode="TransportCredentialOnly">
                    <transport clientCredentialType="Basic" />
                </security>
            </binding>
        </basicHttpBinding>
    </bindings>
    <services>
        <service
                name="MyServiceSvcNs.MyServiceSvc"
                behaviorConfiguration="ServiceWithMetaData"
                >
            <endpoint name="Default"
                address=""
                binding="basicHttpBinding"
                bindingConfiguration="httpBinding"
                contract="MyServiceSvcNs.IMyServiceSvc"
                />
        </service>
    </services>
    <behaviors>
        <serviceBehaviors>
            <behavior name="ServiceWithMetaData">
                <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
                <serviceDebug includeExceptionDetailInFaults="false" />
            </behavior>
        </serviceBehaviors>
    </behaviors>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true"
        multipleSiteBindingsEnabled="true" />
</system.serviceModel>

有了这个,事情似乎有效。至少乍一看。

With this, things seem to be working. At least at first glance.

推荐答案

好的,我明白了。

首先,在IIS管理器中,您需要关闭匿名身份验证,然后启用基本身份验证。这可能需要先启用基本身份验证,然后重新启动IIS管理器。这是基本的IIS内容,而不是我的问题的一部分。

First, in IIS Manager., you need to turn off anonymous authentication, and turn on basic authentication. Which may require enabling basic authentication first, then restarting IIS Manager. That's basic IIS stuff, and not really part of my question.

然后,我们需要更改Web服务的web.config。如果你还记得,它看起来像这样:

Then, we need to make changes to the web service's web.config. If you remember, it had looked like this:

<configuration>
    <system.web>
        <compilation debug="true" targetFramework="4.5" />
        <httpRuntime targetFramework="4.5" />
    </system.web>
    <system.serviceModel>
        <behaviors>
            <serviceBehaviors>
                <behavior name="">
                    <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
                    <serviceDebug includeExceptionDetailInFaults="false" />
                </behavior>
            </serviceBehaviors>
        </behaviors>
        <serviceHostingEnvironment aspNetCompatibilityEnabled="true"
            multipleSiteBindingsEnabled="true" />
    </system.serviceModel>
</configuration>

我们需要将其更改为:

<configuration>
    <system.web>
        <compilation debug="true" targetFramework="4.5" />
        <httpRuntime targetFramework="4.5" />
    </system.web>
    <system.serviceModel>
        <bindings>
            <basicHttpBinding>
                <binding name="httpTransportCredentialOnlyBinding">
                    <security mode="TransportCredentialOnly">
                        <transport clientCredentialType="Basic" />
                    </security>
                </binding>
            </basicHttpBinding>
        </bindings>
        <services>
            <service
                    name="MyServiceSvcNs.MyServiceSvc"
                    behaviorConfiguration="ServiceWithMetaData"
                    >
                <endpoint name="Default"
                    address=""
                    binding="basicHttpBinding"
                    bindingConfiguration="httpTransportCredentialOnlyBinding"
                    contract="MyServiceSvcNs.IMyServiceSvc"
                    />
            </service>
        </services>
        <behaviors>
            <serviceBehaviors>
                <behavior name="ServiceWithMetaData">
                    <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
                    <serviceDebug includeExceptionDetailInFaults="false" />
                </behavior>
            </serviceBehaviors>
        </behaviors>
        <serviceHostingEnvironment aspNetCompatibilityEnabled="true"
            multipleSiteBindingsEnabled="true" />
    </system.serviceModel>
</configuration>

我们正在做的是使用TransportCredentialOnly安全性定义basicHttpBinding。然后我们定义一个服务,其端点使用该绑定。

What we're doing is defining a basicHttpBinding with TransportCredentialOnly security. Then we define a service, with an endpoint that uses that binding.

然后在客户端上,我们有:

Then on the client, we had had:

<configuration>
    <startup>
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
    </startup>
    <system.serviceModel>
        <bindings>
            <basicHttpBinding>
                <binding name="BasicHttpBinding_IMyServiceSvc" />
            </basicHttpBinding>
        </bindings>
        <client>
            <endpoint address="http://localhost/MyServiceSvc.svc"
                binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IMyServiceSvc"
                contract="MyServiceSvc.IMyServiceSvc"
                name="BasicHttpBinding_IMyServiceSvc" />
        </client>
    </system.serviceModel>
</configuration>

这需要更改为:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <startup>
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
    </startup>
    <system.serviceModel>
        <bindings>
            <basicHttpBinding>
                <binding name="httpTransportCredentialOnlyBinding">
                    <security mode="TransportCredentialOnly">
                        <transport clientCredentialType="Basic" />
                    </security>
                </binding>
            </basicHttpBinding>
        </bindings>
        <client>
            <endpoint
                address="http://localhost/MyServiceSvc.svc"
                binding="basicHttpBinding"
                bindingConfiguration="httpTransportCredentialOnlyBinding"
                contract="MyServiceSvc.IMyServiceSvc"
                name="BasicHttpBinding_IMyServiceSvc"
                />
        </client>
    </system.serviceModel>
</configuration>

在这里,我们再次使用TransportCredentialOnly安全性创建basicHttpBinding,我们将端点修改为使用它。

Here, we're again creating an basicHttpBinding with TransportCredentialOnly security, the we're modifying the endpoint to use it.

这篇关于为简单的WCF服务启用基本身份验证?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆