C# 以编程方式更改WCF服务端点后维护安全配置
我有一个ASP.NETMVC应用程序,我们使用几个外部服务 我们以以下方式在web.config中定义每个服务的端点:C# 以编程方式更改WCF服务端点后维护安全配置,c#,asp.net,web-services,wcf,authentication,C#,Asp.net,Web Services,Wcf,Authentication,我有一个ASP.NETMVC应用程序,我们使用几个外部服务 我们以以下方式在web.config中定义每个服务的端点: <endpoint address="http://tempuri.org/myExternalServiceEndPointAddress" binding="basicHttpBinding" bindingConfiguration="myExternalServiceBinding" contract="myExternalServiceContract"
<endpoint address="http://tempuri.org/myExternalServiceEndPointAddress"
binding="basicHttpBinding" bindingConfiguration="myExternalServiceBinding" contract="myExternalServiceContract" name="MyExternalServiceName">
<headers>
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<wsse:UsernameToken>
<wsse:Username>myUsername</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">myPassword</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
</headers>
</endpoint>
一旦我们这样做了,方法调用将在newEndpointUrl上正确寻址,但是调用已经丢失了包含验证的头节点
我们尝试通过编程方式添加身份验证
myServiceClientObject.ClientCredentials.Username.Username = myUsername;
myServiceClientObject.ClientCredentials.Username.Password = myPassword;
但是,该服务似乎无法识别此身份验证(而在我们更改端点之前,前一个身份验证工作得很好)
任何见解或建议都将不胜感激。我终于解决了这个问题 我们最后做的是将一个具有所需头的对象连接到WCF管道中 为此,我们创建了一个类,该类在服务中添加了一个客户端行为,另一个类定义了行为本身,并在其中进行了注入 代码如下: 类来添加行为
public class EndpointAddCredentials : IEndpointBehavior {
public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters) { }
public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime) {
clientRuntime.MessageInspectors.Add(new SimpleMessageInspector());
}
public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher) { }
public void Validate(ServiceEndpoint endpoint) { }
}
类,该类在发送请求之前定义并应用它
public class SimpleMessageInspector : IClientMessageInspector, IDispatchMessageInspector {
public void AfterReceiveReply(ref Message reply, object correlationState) {
}
public object BeforeSendRequest(ref Message request, IClientChannel channel) {
UsernameToken authentication = new UsernameToken(remoteServiceUsername, remoteServicePassword, PasswordOption.SendPlainText); //Plain text is server requirement, we cannot do anything
var webUserHeader = MessageHeader.CreateHeader("Security",
"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd", authentication.GetXml(new XmlDocument()));
request.Headers.Add(webUserHeader);
return null;
}
public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext) {
return null;
}
public void BeforeSendReply(ref Message reply, object correlationState) {
}
}
然后,在服务重定向之后,我们只需将行为添加到客户端对象
serviceObject.Endpoint.Behaviors.Add(new EndpointAddCredentials());
这样,对服务器的请求包含了我们正在寻找的安全定义,服务器接受了它们。我终于解决了这个问题 我们最后做的是将一个具有所需头的对象连接到WCF管道中 为此,我们创建了一个类,该类在服务中添加了一个客户端行为,另一个类定义了行为本身,并在其中进行了注入 代码如下: 类来添加行为
public class EndpointAddCredentials : IEndpointBehavior {
public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters) { }
public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime) {
clientRuntime.MessageInspectors.Add(new SimpleMessageInspector());
}
public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher) { }
public void Validate(ServiceEndpoint endpoint) { }
}
类,该类在发送请求之前定义并应用它
public class SimpleMessageInspector : IClientMessageInspector, IDispatchMessageInspector {
public void AfterReceiveReply(ref Message reply, object correlationState) {
}
public object BeforeSendRequest(ref Message request, IClientChannel channel) {
UsernameToken authentication = new UsernameToken(remoteServiceUsername, remoteServicePassword, PasswordOption.SendPlainText); //Plain text is server requirement, we cannot do anything
var webUserHeader = MessageHeader.CreateHeader("Security",
"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd", authentication.GetXml(new XmlDocument()));
request.Headers.Add(webUserHeader);
return null;
}
public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext) {
return null;
}
public void BeforeSendReply(ref Message reply, object correlationState) {
}
}
然后,在服务重定向之后,我们只需将行为添加到客户端对象
serviceObject.Endpoint.Behaviors.Add(new EndpointAddCredentials());
这样,对服务器的请求就包含了我们正在寻找的安全定义,服务器也接受了它们。为什么端点会发生变化?当然,如果它是来自另一个服务的动态响应,您能保证它的有效性吗?关于您遇到的实际问题,在端点配置中,wsse命名空间引用与什么相关?我怀疑仅仅使用“ClientCredentials”部分可能还不够(您在安全性的密码部分有一个特殊类型),为什么端点会发生变化?当然,如果它是来自另一个服务的动态响应,您能保证它的有效性吗?关于您遇到的实际问题,在端点配置中,wsse命名空间引用与什么相关?我怀疑仅仅使用“ClientCredentials”部分可能还不够(您在安全性的密码部分有一个特殊类型)