[英]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.