免责声明:我从未使用过 SOAP Web 服务。完全没有。一点点也没有。所以通道和 WCF 脚手架的概念让我有点困惑,所以我在这里。
我被要求集成到使用基本身份验证的 SOAP XML Web 服务。 (例如授权标头、基本 xxxxxxxxxxxxxxxxxxxxxxxxxxxx <- which is a Base64 encoded username:password). My project is in .NET Core using C#.
我已经使用 Visual Studio WCF 连接的服务发现来生成脚手架代码,该代码非常适合实例化所需的对象等,但是我的问题是我被要求使用基本身份验证,并且我不知道在哪里注入它将代码放入已生成的脚手架中。我以前使用过基本身份验证,因此我了解“如何”执行此操作,例如 REST API 等。只需用户名:密码、base64 编码并添加到授权标头。但是,我不确定如何为这个搭建的 SOAP Web 服务执行此操作。
我相信可以注入到每个请求中以添加自定义标头的代码是:
using (OperationContextScope scope = new OperationContextScope(IContextChannel or OperationContext)
{
OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = new HttpRequestMessageProperty()
{
Headers =
{
{ "MyCustomHeader", Environment.UserName },
{ HttpRequestHeader.UserAgent, "My Custom Agent"}
}
};
// perform proxy operations...
}
OperationContextScope 需要 IContextChannel 或 OperationContext。我不知道要在这里添加什么。如果我查看我的脚手架代码,我可以在这里找到 Web 服务的“客户端”:
public partial class POSUserInformationManagerV1_2Client : System.ServiceModel.ClientBase<McaEndpointPosUserInformation.POSUserInformationManagerV1_2>, McaEndpointPosUserInformation.POSUserInformationManagerV1_2
我可以在这里找到“通道”,但这只是另一个接口,没有指定任何合约?
[System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "2.0.2")]
public interface POSUserInformationManagerV1_2Channel : McaEndpointPosUserInformation.POSUserInformationManagerV1_2, System.ServiceModel.IClientChannel
{
}
我查了一下 ChannelBase,它似乎应该接受实现一个或另一个通道接口的各种对象(包括 IClientChannel,支架 POSUserInformationManagerV1_2Channel 使用它)
protected class ChannelBase<T> : IDisposable, IChannel, ICommunicationObject, IOutputChannel, IRequestChannel, IClientChannel, IContextChannel, IExtensibleObject<IContextChannel> where T : class
{
protected ChannelBase(ClientBase<T> client);
[SecuritySafeCritical]
protected IAsyncResult BeginInvoke(string methodName, object[] args, AsyncCallback callback, object state);
[SecuritySafeCritical]
protected object EndInvoke(string methodName, object[] args, IAsyncResult result);
但是我仍然坚持将哪些内容放入OperationContextScope 中以将其适当地连接到“通道”。我尝试过 POSUserInformationManagerV1_2Client 和相关 Channel 接口,但都不会转换为 IContextChannel。有人有什么想法/想法吗?
编辑:这是我尝试注入代码以添加 Auth HTTP 标头的位置:
public System.Threading.Tasks.Task<McaEndpointPosUserInformation.requestUserInformationResponse> requestUserInformationAsync(McaEndpointPosUserInformation.requestUserInformation request)
{
using (OperationContextScope scope = new OperationContextScope(request)
{
OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = new HttpRequestMessageProperty()
{
Headers =
{
{ "MyCustomHeader", Environment.UserName },
{ HttpRequestHeader.UserAgent, "My Custom Agent"}
}
};
// perform proxy operations...
}
return base.Channel.requestUserInformationAsync(request);
}
问题原来是没有通过使用以下方式将传输安全设置为“基本”:
// Set the binding. Without this, the WCF call will be made as anonymous
var binding = new BasicHttpsBinding();
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;
在创建客户端的方法中添加以下代码
private void SetAuthCredentials<T>(ClientBase<T> client) where T : class
{
client.ClientCredentials.UserName.UserName = _config.Login;
client.ClientCredentials.UserName.Password = _config.Password;
var httpBinding = (BasicHttpBinding)client.Endpoint.Binding;
httpBinding.Security.Transport.ClientCredentialType =
HttpClientCredentialType.Basic;
httpBinding.Security.Mode = BasicHttpSecurityMode.TransportCredentialOnly;
}
这添加了基本身份验证方案的标头