簡體   English   中英

以編程方式更改WCF服務端點后,維護安全配置

[英]Maintain security configuration after changing WCF service endpoint programmatically

我有一個ASP.NET MVC應用程序,我們使用幾個外部服務。

我們以這種方式為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>

現在,當切換到生產環境時,我們必須通過特定服務發現實際的端點URL,因為它們可以在沒有警告的情況下進行更改。 一旦找到新的端點,我們將在執行任何方法調用之前更改端點URL:

myserviceClientObject.Endpoint.Address = new EndpointAddress(newEndpointUrl);

完成此操作后,方法調用在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()); 

有了這個,對服務器的請求包括我們正在尋找的安全定義,服務器接受了它們。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM