无法使用基本领域配置凭据 WCF?

Posted

技术标签:

【中文标题】无法使用基本领域配置凭据 WCF?【英文标题】:Can't configure credentials WCF with basic realm? 【发布时间】:2021-09-01 09:52:59 【问题描述】:

我在 Visual Studio 2019 中添加了一个连接引用。它使用了一个 https 端点,并将所需的所有绑定信息创建到一个 reference.cs 文件中。

它没有生成任何App.config 文件,所以我怀疑我需要的东西被捆绑到reference.cs 文件中。确实,仔细研究一下,它大多是。

所以我尝试创建一个客户端,以两种方式指定客户端凭据,如您所见,但不管我如何指定它,在下面调用此代码时都会出现异常。

        public async Task SendFile(Stream fileStream, string fileName, Guid machineKey)
        
            _logger.LogInformation("Starting file sending to Manager 1.");
            _logger.LogInformation($"Sending file fileName from Machine machineKey");
            try
            
                var client = new FileTransferClient(FileTransferClient.EndpointConfiguration.BasicHttpBinding_IFileTransfer, _options.FileTransferEndPoint)
                
                    ClientCredentials =
                    
                        UserName =
                        
                            UserName = _options.FileTransferUsername,
                            Password = _options.FileTransferPassword
                        
                    
                ;

                client.ClientCredentials.UserName.UserName = _options.FileTransferUsername;
                client.ClientCredentials.UserName.Password = _options.FileTransferPassword;

                using (new OperationContextScope(client.InnerChannel))
                

                

                await client.UploadAsync(new FileUploadMessage
                
                    // Assume that this is enough. Can't really supply file length...
                    FileInfo = new FileTransferInfo
                    
                        TransferId = new Guid(),
                        MachineUUID = machineKey.ToString(),
                        Name = fileName
                    ,

                    TransferStream = fileStream
                );
            
            catch (Exception e)
            
                _logger.LogError("An unexpected exception occurred while sending file to Manager 1G.", e);
            

            _logger.LogInformation("File sending finished.");
        

例外是"The HTTP request is unauthorized with client authentication scheme 'Basic'. The authentication header received from the server was 'Basic Realm'."

我比较了使用前面提到的App.config 的类似 API,并编辑了 reference.cs 以匹配我认为它应该具有的安全性。

具体来说,我在这里添加了与安全相关的行:

       private static System.ServiceModel.Channels.Binding GetBindingForEndpoint(EndpointConfiguration endpointConfiguration)
       
           if ((endpointConfiguration == EndpointConfiguration.BasicHttpBinding_IFileTransfer))
           
               System.ServiceModel.BasicHttpBinding result = new System.ServiceModel.BasicHttpBinding();
               result.MaxBufferSize = int.MaxValue;
               result.ReaderQuotas = System.Xml.XmlDictionaryReaderQuotas.Max;
               result.MaxReceivedMessageSize = int.MaxValue;
               result.AllowCookies = true;
               result.Security.Mode = System.ServiceModel.BasicHttpSecurityMode.Transport;
               result.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;
               result.Security.Transport.ProxyCredentialType = HttpProxyCredentialType.None;
               return result;
           
           if ((endpointConfiguration == EndpointConfiguration.MetadataExchangeHttpsBinding_IFileTransfer))
           
               System.ServiceModel.Channels.CustomBinding result = new System.ServiceModel.Channels.CustomBinding();
               System.ServiceModel.Channels.TextMessageEncodingBindingElement textBindingElement = new System.ServiceModel.Channels.TextMessageEncodingBindingElement();
               result.Elements.Add(textBindingElement);
               System.ServiceModel.Channels.HttpsTransportBindingElement httpsBindingElement = new System.ServiceModel.Channels.HttpsTransportBindingElement();
               httpsBindingElement.AllowCookies = true;
               httpsBindingElement.MaxBufferSize = int.MaxValue;
               httpsBindingElement.MaxReceivedMessageSize = int.MaxValue;
               result.Elements.Add(httpsBindingElement);
               return result;
           
           throw new System.InvalidOperationException(string.Format("Could not find endpoint with name \'0\'.", endpointConfiguration));
       

我发现令人震惊的是,在调用设置 ClientCredentials 的构造函数中嵌入时,当我检查带有调试会话的 client 时,它们并没有以任何方式填充。因此我尝试在之后专门设置它。

但无论哪种方式,最终结果都是一样的,得到同样的错误。

如何解决代码中的错误?

理论上我可以尝试添加App.config 并在那里执行,但我不知道合同。而且我不确定在生成的reference.cs 中寻找什么来识别它。所以我更喜欢通过代码来学习这样做,因为合同已经在那里,我可以通过_options 提供端点,所以它应该能够配置不同的环境。

【问题讨论】:

请编辑您的问题,并以 text 的形式提供代码、错误消息和其他 基于文本的信息,而不是作为截屏。谢谢。 根据要求从图片更改为基于文本的信息。 【参考方案1】:

原来我确实交换了密码和用户名,所以修复它帮助我解决了这个问题。

【讨论】:

以上是关于无法使用基本领域配置凭据 WCF?的主要内容,如果未能解决你的问题,请参考以下文章

WCF 使用凭据和 IIS 以编程方式启用 TLS

具有 basicHttpBinding、传输安全性和基本客户端凭据类型的自定义 WCF 凭据验证器

服务器已拒绝客户端凭据,WCF 作为 Windows 服务

使用TransportWithMessageLevel凭据和窗体身份验证的WCF配置

无法使用 WCF 调用具有基本身份验证的 Web 服务

Shiro - 无法使用散列密码进行身份验证