Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/303.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 以编程方式更改WCF服务端点后维护安全配置_C#_Asp.net_Web Services_Wcf_Authentication - Fatal编程技术网

C# 以编程方式更改WCF服务端点后维护安全配置

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"

我有一个ASP.NETMVC应用程序,我们使用几个外部服务

我们以以下方式在web.config中定义每个服务的端点:

<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”部分可能还不够(您在安全性的密码部分有一个特殊类型)