向 WCF 脚手架 SOAP Web 服务添加授权 header
Adding an Authorization header to a WCF scaffolded SOAP web service
免责声明:我从未使用过 SOAP Web 服务。完全没有。一点儿都没有。所以通道和 WCF 脚手架的概念让我有点困惑,所以我来了。
我被要求集成到使用基本身份验证的 SOAP XML Web 服务。 (例如授权 header、基本 xxxxxxxxxxxxxxxxxxxxxxxxxxxx <- 这是 Base64 编码 username:password)。我的项目在 .NET Core 中使用 C#。
我已经使用 Visual Studio WCF 连接服务发现来生成脚手架代码,这对我实例化所需的 objects 等非常有用,但是我的问题是我被要求使用 Basic身份验证,我不知道在哪里将这段代码注入到已经生成的脚手架中。我之前使用过基本身份验证,所以我理解 'how' 可以做到这一点,例如 REST API 等。只需 username:password,base64 编码并添加到授权 header。但是,我不确定如何为这个脚手架 SOAP Web 服务执行此操作。
我相信可以注入每个请求的代码,以添加您的自定义 headers,是:
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 服务的 'client':
public partial class POSUserInformationManagerV1_2Client : System.ServiceModel.ClientBase<McaEndpointPosUserInformation.POSUserInformationManagerV1_2>, McaEndpointPosUserInformation.POSUserInformationManagerV1_2
我可以在这里找到 'channel',但这只是另一个界面,没有指定任何合同?
[System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "2.0.2")]
public interface POSUserInformationManagerV1_2Channel : McaEndpointPosUserInformation.POSUserInformationManagerV1_2, System.ServiceModel.IClientChannel
{
}
我查找了 ChannelBase,它似乎应该接受实现一个或另一个通道接口的各种 objects(包括脚手架 POSUserInformationManagerV1_2Channel 使用的 IClientChannel)
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 以将其适当地连接到 'channel'。我试过 POSUserInformationManagerV1_2Client 和相关的 Channel 接口,但都不会转换为 IContextChannel。有人有ideas/thoughts吗?
编辑:这是我尝试注入代码以添加 Auth HTTP header:
的地方
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);
}
问题原来是没有通过使用 'Basic' 将传输安全设置为:
// Set the binding. Without this, the WCF call will be made as anonymous
var binding = new BasicHttpsBinding();
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;
免责声明:我从未使用过 SOAP Web 服务。完全没有。一点儿都没有。所以通道和 WCF 脚手架的概念让我有点困惑,所以我来了。
我被要求集成到使用基本身份验证的 SOAP XML Web 服务。 (例如授权 header、基本 xxxxxxxxxxxxxxxxxxxxxxxxxxxx <- 这是 Base64 编码 username:password)。我的项目在 .NET Core 中使用 C#。
我已经使用 Visual Studio WCF 连接服务发现来生成脚手架代码,这对我实例化所需的 objects 等非常有用,但是我的问题是我被要求使用 Basic身份验证,我不知道在哪里将这段代码注入到已经生成的脚手架中。我之前使用过基本身份验证,所以我理解 'how' 可以做到这一点,例如 REST API 等。只需 username:password,base64 编码并添加到授权 header。但是,我不确定如何为这个脚手架 SOAP Web 服务执行此操作。
我相信可以注入每个请求的代码,以添加您的自定义 headers,是:
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 服务的 'client':
public partial class POSUserInformationManagerV1_2Client : System.ServiceModel.ClientBase<McaEndpointPosUserInformation.POSUserInformationManagerV1_2>, McaEndpointPosUserInformation.POSUserInformationManagerV1_2
我可以在这里找到 'channel',但这只是另一个界面,没有指定任何合同?
[System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "2.0.2")]
public interface POSUserInformationManagerV1_2Channel : McaEndpointPosUserInformation.POSUserInformationManagerV1_2, System.ServiceModel.IClientChannel
{
}
我查找了 ChannelBase,它似乎应该接受实现一个或另一个通道接口的各种 objects(包括脚手架 POSUserInformationManagerV1_2Channel 使用的 IClientChannel)
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 以将其适当地连接到 'channel'。我试过 POSUserInformationManagerV1_2Client 和相关的 Channel 接口,但都不会转换为 IContextChannel。有人有ideas/thoughts吗?
编辑:这是我尝试注入代码以添加 Auth HTTP header:
的地方 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);
}
问题原来是没有通过使用 'Basic' 将传输安全设置为:
// Set the binding. Without this, the WCF call will be made as anonymous
var binding = new BasicHttpsBinding();
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;