2013-08-16 52 views
0

我試圖消耗的authetication Web服務使用自定義傳遞的SOAP標頭的UsernameToken結合C#Webservice的錯誤:信息安全驗證失敗

ICollection<BindingElement> bindingElements = new List<BindingElement>(); 
HttpsTransportBindingElement httpBindingElement = new HttpsTransportBindingElement(); 
CustomTextMessageBindingElement textBindingElement = new CustomTextMessageBindingElement(); 
SecurityBindingElement securityElement = SecurityBindingElement.CreateUserNameOverTransportBindingElement(); 
securityElement.IncludeTimestamp = false; 
bindingElements.Add(securityElement); 
bindingElements.Add(textBindingElement); 
bindingElements.Add(httpBindingElement); 
CustomBinding binding = new CustomBinding(bindingElements); 

EndpointAddress address = new EndpointAddress("https://...."); 

var client = new WebServiceClient(binding, address); 
client.ClientCredentials.UserName.UserName = "USERNAME HERE"; 
client.ClientCredentials.UserName.Password = "PASSWORD HERE"; 

using (new OperationContextScope(client.InnerChannel)) 
{ 
    var req = new WebServiceRequest(); 
    var resp = client.initiate(req); 
} 

得到一個例外:

Message security verification failed.

Cannot read the token from the 'BinarySecurityToken' element with the ' http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd ' namespace for BinarySecretSecurityToken, with a 'oblix:ObSSOCookie' ValueType. If this element is expected to be valid, ensure that security is configured to consume tokens with the name, namespace and value type specified."}

服務器堆棧跟蹤:

at System.ServiceModel.Security.TransportSecurityProtocol.VerifyIncomingMessage(Message& message, TimeSpan timeout) at System.ServiceModel.Security.SecurityProtocol.VerifyIncomingMessage(Message& message, TimeSpan timeout, SecurityProtocolCorrelationState[] correlationStates) at System.ServiceModel.Channels.SecurityChannelFactory 1.SecurityRequestChannel.ProcessReply(Message reply, SecurityProtocolCorrelationState correlationState, TimeSpan timeout) at System.ServiceModel.Channels.SecurityChannelFactory 1.SecurityRequestChannel.Request(Message message, TimeSpan timeout) at System.ServiceModel.Dispatcher.RequestChannelBinder.Request(Message message, TimeSpan timeout) at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout) at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation) at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)

以下是由fiddler抓到的回覆:

<?xml version="1.0" encoding="UTF-8"?> 
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"> 
    <env:Header> 
     <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"> 
      <wsse:BinarySecurityToken EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary" ValueType="oblix:ObSSOCookie" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:oblix="http://schemas.oblix.com/ws/2004/04/authentication"><!--REMOVED--></wsse:BinarySecurityToken> 
     </wsse:Security> 
    </env:Header> 
    <env:Body> 
     <MobileAppsLoginSSOProcessResponse xmlns="http://xmlns.oracle.com/MobileAppsLoginSSO"> 
      <ReturnStatus>SUCCESS</ReturnStatus> 
     </MobileAppsLoginSSOProcessResponse> 
    </env:Body> 
</env:Envelope> 

我使用CustomTextMessageEncoder以下http://msdn.microsoft.com/en-us/library/ms751486%28v=vs.100%29.aspx

編輯:

如所建議的通過亞龍,除非我去掉從響應中的BinarySecurityToken標籤,所述代碼失敗,上述消息安全性驗證失敗例外。

響應中的'oblix:ObSSOCookie'是服務通過成功身份驗證發送回客戶端的身份驗證Cookie,我相信客戶端需要保存此Cookie。

解決方案: 如在最終編輯所建議的亞龍,我刪除SecurityElementBinding從自定義綁定和使用定製消息檢查器(IClientMessageInspector)注入安全標籤插入到報頭。

這允許解釋僅來自SOAP正文的響應,我可以讀取我的IClientMessageInspector實現的AfterReceiveReply中的SOAP響應標頭。

回答

1

服務器在響應中返回一個x.509標記,並且WCF不確定如何處理它(此標記在用戶名認證中不需要)。我看到兩個選項:

  1. 在編碼帶出了安全標籤從響應

    OR

  2. 所有在該編碼器(或消息檢查,如果你不使用安全喜歡的)推動用戶名/密碼頭請求

編輯:你說的這個標記應在進一步調用客戶端使用。我不確定什麼是正確的方式來處理這個問題,所以我會給出一個快速的方法,它會工作(但感覺有點片面)。根本不要定義任何安全性(從綁定中移除安全性元素)。然後使用自定義消息檢查器(或編碼器,但更難)以正確的格式推送用戶/傳遞的消息(請參閱使用安全綁定時它們是如何發送的)。這應該不難。那麼WCF將不會在響應中驗證令牌。您可以使用已有的相同消息檢查器來檢查響應並提取令牌。您的主類(初始化代理)也是初始化檢查器的類,因此它應該有權訪問其數據成員以訪問令牌並重新發送它。

如果服務器將令牌發送給主體而不是頭部,它將會變得如此簡單。 也可能有辦法通過實現自定義令牌/行爲來實現它,但在我看來,這增加了更多的抽象,最好是具體的。

+0

響應包含安全性> BinarySecurityToken中的身份驗證令牌。我不確定它沒用。 –

+0

你可以建議一些方法來處理安全標籤沒有這個例外嗎? –

+0

好的,現在我看到這不是一個常規的x.509標記,而是一個叫做oblix:ObSSOCookie的東西。這個cookie是WCF無法處理的東西。無論是您還是供應商都知道如何去做,在這種情況下,您應該實施WCF自定義令牌,或者您決定不關心它並按上面的建議將其移除。您需要與供應商討論這個cookie的含義以及您應該如何處理/驗證它。繼承人如何創建自定義令牌,這是正確的方法, –