【问题标题】:WCF with BasicAuthentification problems带有 BasicAuthentification 问题的 WCF
【发布时间】:2015-10-07 12:12:31
【问题描述】:

我几乎没有尝试为我的 WCF 设置 BasicAuthentification(在 IIS 8.5 上发布)。但我总是得到以下错误之一:

http 请求被客户端身份验证方案“基本”禁止。从服务器获得以下 authentificationheader "Digest qop="auth",algorithm=MD5-sess,nonce="someMD5stuff",charset=utf-8,realm="Digest",Negotiate,NTLM,Basic realm="localhost""。

或

客户端身份验证方案“基本”禁止 HTTP 请求。从服务器获得 authentificationheader "Basic realm="localhost""。

我的 web.config 服务器端(在 WCF 中):

<system.serviceModel>
<services>
  <service name="WCF_for_APP.Service1">
    <endpoint
      address=""
      binding="basicHttpBinding"
      contract="WCF_for_APP.Service"/>
  </service>
</services>
<bindings>
  <basicHttpBinding>
    <binding name="BasicHttpBinding_IPersonService" />
    <binding>
      <security mode="TransportCredentialOnly">
        <transport clientCredentialType="Basic" proxyCredentialType="None" realm=""/>
      </security>
    </binding>
  </basicHttpBinding>
</bindings>
<client>
  <endpoint address="http://somewhere/customerService"
    binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IPersonService"
    contract="PersonService.IPersonService" name="BasicHttpBinding_IPersonStateService" />
</client>
<behaviors>
  <serviceBehaviors>
    <behavior>        
      <serviceMetadata httpGetEnabled="true" httpsGetEnabled="false"/>  
      <serviceAuthenticationManager authenticationSchemes="Basic"></serviceAuthenticationManager>
      <serviceCredentials>
        <userNameAuthentication userNamePasswordValidationMode="Custom"
          customUserNamePasswordValidatorType="CustomerValidator.SecureBindingUsernamePasswordValidator, CustomerValidator" />
      </serviceCredentials>
    </behavior>
  </serviceBehaviors>
</behaviors>
</system.servicemodel>

我已经尝试为 bindingConfiguration 等设置名称,但它没有改变任何事情。

我尝试在 ASP 应用程序中通过 Channelfactory 客户端访问我的 WCF:

EndpointAddress endpointAddress = new EndpointAddress(endpointadress);

BasicHttpBinding basicHttpBinding = new BasicHttpBinding();
basicHttpBinding.ReaderQuotas.MaxBytesPerRead = Int16.MaxValue;
basicHttpBinding.MaxReceivedMessageSize = int.MaxValue;
basicHttpBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;
basicHttpBinding.Security.Mode = BasicHttpSecurityMode.TransportCredentialOnly;

ChannelFactory<Service> channelFactory = null;
Service client = null;            

channelFactory = new ChannelFactory<Service>(basicHttpBinding, endpointAddress);
channelFactory.Credentials.UserName.UserName = ConfigurationManager.AppSettings["wcfUser"].ToString();
channelFactory.Credentials.UserName.Password = ConfigurationManager.AppSettings["wcfPW"].ToString();
try
{
    client = channelFactory.CreateChannel();
    string a = client.SendMail();
}
catch(Exception e)
{
    Response.Write(e.Message);
}

IIS 上的基本身份验证已激活。我真的不想切换到 HTTPS 和证书,因为我只需要这个 basicauthent 来保证内部安全。我什至无法使用 Visual Studio wcf testclient 启动 WCF,但没有身份验证设置一切正常。 WCF 和 ASP 都在我的本地 IIS 上发布。

有什么建议吗?我是否必须使用相同的凭据将用户添加到本地系统?

** 编辑 **

我想我知道这个问题!在我的 WCF 中,我调用了另一个 WCF(来自客户),而这个与我的安全设置相结合正在制造麻烦。那么我该如何解决呢?我的带有服务器端配置的 WCF 和带有客户端配置的客户 WCF 在一个 web.config 中? (客户 WCF 也通过 ChannelFactory 调用)因为如果我命名 bindingconfigs 它不会改变任何东西(参见上面的代码)。

通过 ChannelFactory 调用客户 WCF 的代码类似于上面的代码。 这可能是问题吗? 2 WCF - 一个服务器端和一个调用?!

【问题讨论】:

  • 不要在没有 https 的情况下使用 BASIC。用嗅探器从电线上提取密码是微不足道的。不要认为 internal 只意味着“安全”。
  • @Crowcoder - 我真的不在乎外部是否能看到某些东西。没有亲密的转移。如果他们错误地访问 WCF 的站点,这只是为了确保每位员工的内部安全。
  • @DaveStockinger 您是否尝试将领域添加到客户端的凭据?
  • @mkysoft 我只是尝试在 WCF 的 web.config 中添加localhost,但它也不起作用。而且我没有找到以编程方式在客户端上添加领域的方法。
  • @DaveStockinger 您可以删除基本身份验证和自定义验证配置,然后仅在 IIS 上启用基本身份验证。在文件夹安全选项卡中将用户添加到网站文件夹。这是简单的方法。但是每个有权访问站点文件夹的用户都可以调用您的网络服务。

标签: c# asp.net wcf iis basic-authentication


【解决方案1】:

我的 BasicAuthentification 一切正常。

错误是我通过我的 WCF 调用的另一个 WCF,并且由于我的 WCF 中的安全设置我无法调试(不是挂起进程或测试客户端)并且因为错误消息中没有详细信息我没有找到这个错误的根源。这个其他 WCF 抛出“Basic”错误是不允许的,所以我的客户在他的 IIS 上做了一些更改(也许)。

我必须添加一个与我在 WCF 中使用的凭据相同的本地用户。不知道,但是是的 - 一切都很好,我必须等待我的客户告诉我他们的设置。

【讨论】:

    【解决方案2】:

    我创建了测试项目并且它正在工作。代码如下:

    IService1 接口:

    namespace WcfTestService
    {
        // NOTE: You can use the "Rename" command on the "Refactor" menu to change the interface name "IService1" in both code and config file together.
        [ServiceContract]
        public interface IService1
        {
    
            [OperationContract]
            string GetData(int value);
    
            [OperationContract]
            CompositeType GetDataUsingDataContract(CompositeType composite);
    
            // TODO: Add your service operations here
        }
    
    
        // Use a data contract as illustrated in the sample below to add composite types to service operations.
        [DataContract]
        public class CompositeType
        {
            bool boolValue = true;
            string stringValue = "Hello ";
    
            [DataMember]
            public bool BoolValue
            {
                get { return boolValue; }
                set { boolValue = value; }
            }
    
            [DataMember]
            public string StringValue
            {
                get { return stringValue; }
                set { stringValue = value; }
            }
        }
    }
    

    Service1 类:

    namespace WcfTestService
    {
        // NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "Service1" in code, svc and config file together.
        // NOTE: In order to launch WCF Test Client for testing this service, please select Service1.svc or Service1.svc.cs at the Solution Explorer and start debugging.
        public class Service1 : IService1
        {
            public string GetData(int value)
            {
                return string.Format("You entered: {0}", value);
            }
    
            public CompositeType GetDataUsingDataContract(CompositeType composite)
            {
                if (composite == null)
                {
                    throw new ArgumentNullException("composite");
                }
                if (composite.BoolValue)
                {
                    composite.StringValue += "Suffix";
                }
                return composite;
            }
        }
    }
    

    web.config 文件:

    <?xml version="1.0"?>
    <configuration>
    
      <system.web>
        <compilation debug="true" targetFramework="4.0" />
      </system.web>
      <system.serviceModel>
        <services>
          <service name="WcfTestService.Service1" behaviorConfiguration="HttpBehavior">
            <endpoint address="" binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding" contract="WcfTestService.IService1" />
    
          </service>
    
        </services>
        <bindings>
          <basicHttpBinding>
            <binding name="BasicHttpBinding"  >
              <readerQuotas />
              <security mode="TransportCredentialOnly">
    
                <transport clientCredentialType="Basic" realm="" />
              </security>
            </binding>
          </basicHttpBinding>
        </bindings>
        <behaviors>
          <serviceBehaviors>
            <behavior name="HttpBehavior">
              <serviceMetadata httpGetEnabled="true" />
              <serviceDebug includeExceptionDetailInFaults="false" />
            </behavior>
          </serviceBehaviors>
        </behaviors>
        <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
    
      </system.serviceModel>
      <system.webServer>
        <modules runAllManagedModulesForAllRequests="true"/>
        <!--
            To browse web app root directory during debugging, set the value below to true.
            Set to false before deployment to avoid disclosing web app folder information.
          -->
        <directoryBrowse enabled="true"/>
      </system.webServer>
    
    </configuration>
    

    在 IIS 上启用基本身份验证,禁用匿名。

    WCF 客户端控制台应用程序:

    namespace WcfTestClient
    {
        class Program
        {
            static void Main(string[] args)
            {
                EndpointAddress endpointAddress = new EndpointAddress(@"http://localhost/Service1.svc");
    
                BasicHttpBinding basicHttpBinding = new BasicHttpBinding();
                basicHttpBinding.MaxReceivedMessageSize = int.MaxValue;
                basicHttpBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;
                basicHttpBinding.Security.Mode = BasicHttpSecurityMode.TransportCredentialOnly;
    
                var channelFactory = new ChannelFactory<WcfTestService.IService1>(basicHttpBinding, endpointAddress);
                channelFactory.Credentials.UserName.UserName = @"server\someuser";
                channelFactory.Credentials.UserName.Password = @"somepass";
                try
                {
                    var client = channelFactory.CreateChannel();
                    string a = client.GetData(55);
                    Console.Write(e.Message);
                }
                catch (Exception e)
                {
                    Console.Write(e.Message);
                }
            }
        }
    }
    

    下载:http://sharesend.com/6gutdu4s

    【讨论】:

    • 如果我尝试通过浏览器访问我的 wcf,一切正常。我被要求提供凭据,当我登录时,我看到了该服务,但是当我尝试以编程方式访问它时,当涉及到 client.GetData() 时,我仍然遇到同样的错误。
    • 我想我知道这个问题!在我的 WCF 中,我调用了另一个 WCF(来自客户),而这个与我的安全设置相结合正在制造麻烦。那么我该如何解决呢?我的带有服务器端配置的 WCF 和带有客户端配置的客户 WCF 在一个 web.config 中? (客户 WCF 也通过 ChannelFactory 调用)
    • 我测试过,它工作正常。我在不同的机器上安装服务。你试过同样的代码吗?
    • 我的 WCF 一切正常。我调用的第二个 WCF 处于脱机状态,我收到的错误消息来自此连接失败。还是谢谢你!
    猜你喜欢
    • 2012-09-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-02
    • 2018-05-06
    相关资源
    最近更新 更多