2012-05-18 112 views
1

我們目前正在使用DotNetOpenAuth庫通過OAuth來保護wcf SOAP web服務的應用程序正在刪除。整個事情在IIS7上運行。 Web服務和DotNetOpenAuth庫運行平穩,至少在PC上運行時是如此。然而,從android平臺調用服務會導致一些hickup。有時它會運行得很好,有時它會引起異常,說「序列不包含任何元素」。從android發送oauth令牌原因KeyNotFoundException

不幸的是我沒有所有的細節,因爲我自己實際上並沒有可用的android。但是,在閱讀由我的同事創建的日誌文件時,有幾件事情脫穎而出。

Windows事件日誌表明這是一個KeyNotFoundException,這是因爲令牌被識別而發生的(令牌,實際上,存在於數據庫中,所以這不應該發生 - 我已經檢查過)。

此外,真正有趣的是,只有在oauth_token參數中存在+或/符號時纔會發生此異常。我有點傾向於認爲這是一個編碼問題,其中兩個字符編碼不正確。在檢查Windows事件日誌時,只要oauth_token參數包含+或/,它將被空格替換。然而,我不知道這是在哪裏編碼,爲什麼這兩個字符被替換爲一個空間,最重要的是現在,如何解決它。

我也啓用了log4net logging,它顯示oauth_token變量與數據庫中的內容相同。但是,它顯示構建的簽名基本字符串以包含oauth_token,只有/字符被替換爲%252F。然而,稍低幾行,oauth_token變量單獨顯示(即不是作爲基本字符串的一部分,而是變量的摘要),並且其中的/實際上顯示爲/。

任何有關這個問題的幫助將不勝感激。

編輯

日誌從log4net的

2012-05-18 13:05:21,588 (GMT+2) [5] DEBUG DotNetOpenAuth.Messaging.Channel - Preparing to send UnauthorizedTokenResponse (1.0.1) message. 
    2012-05-18 13:05:22,099 (GMT+2) [5] DEBUG DotNetOpenAuth.Messaging.Bindings - Binding element DotNetOpenAuth.OAuth.ChannelElements.TokenHandlingBindingElement applied to message. 
    2012-05-18 13:05:22,100 (GMT+2) [5] DEBUG DotNetOpenAuth.Messaging.Bindings - Binding element DotNetOpenAuth.OAuth.ChannelElements.OAuthHttpMethodBindingElement did not apply to message. 
2012-05-18 13:05:22,102 (GMT+2) [5] DEBUG DotNetOpenAuth.Messaging.Bindings - Binding element DotNetOpenAuth.Messaging.Bindings.StandardReplayProtectionBindingElement did not apply to message. 
2012-05-18 13:05:22,104 (GMT+2) [5] DEBUG DotNetOpenAuth.Messaging.Bindings - Binding element DotNetOpenAuth.Messaging.Bindings.StandardExpirationBindingElement did not apply to message. 
2012-05-18 13:05:22,109 (GMT+2) [5] DEBUG DotNetOpenAuth.Messaging.Bindings - Binding element DotNetOpenAuth.OAuth.ChannelElements.SigningBindingElementChain did not apply to message. 
2012-05-18 13:05:22,113 (GMT+2) [5] INFO DotNetOpenAuth.Messaging.Channel - Prepared outgoing UnauthorizedTokenResponse (1.0.1) message for <response>: 
    oauth_token: LgelzDbE0hd8Z+HrRQWD63SzNA8= 
    oauth_token_secret: eK1sVTQvF6LrHqrtDGXe4LpLunI= 
    oauth_callback_confirmed: true 

2012-05-18 13:05:22,113 (GMT+2) [5] DEBUG DotNetOpenAuth.Messaging.Channel - Sending message: UnauthorizedTokenResponse 
2012-05-18 13:05:22,463 (GMT+2) [5] INFO DotNetOpenAuth.Messaging.Channel - Scanning incoming request for messages: https://websrv.hszuyd.nl/serviceprovider/v2/OAuth.ashx?oauth_token=LgelzDbE0hd8Z+HrRQWD63SzNA8= 
2012-05-18 13:05:22,996 (GMT+2) [5] ERROR DotNetOpenAuth.OAuthServiceProvider - An unhandled exception occurred in ASP.NET processing: DotNetOpenAuth.Messaging.ProtocolException: A token in the message was not recognized by the service provider. ---> System.Collections.Generic.KeyNotFoundException: Unrecognized token ---> System.InvalidOperationException: Sequence contains no elements 
    at System.Data.Linq.SqlClient.SqlProvider.Execute(Expression query, QueryInfo queryInfo, IObjectReaderFactory factory, Object[] parentArgs, Object[] userArgs, ICompiledSubQuery[] subQueries, Object lastResult) 
    at System.Data.Linq.SqlClient.SqlProvider.ExecuteAll(Expression query, QueryInfo[] queryInfos, IObjectReaderFactory factory, Object[] userArguments, ICompiledSubQuery[] subQueries) 
    at System.Data.Linq.SqlClient.SqlProvider.System.Data.Linq.Provider.IProvider.Execute(Expression query) 
    at System.Data.Linq.Table`1.System.Linq.IQueryProvider.Execute[TResult](Expression expression) 
    at System.Linq.Queryable.First[TSource](IQueryable`1 source, Expression`1 predicate) 
    at OAuthServiceProvider.Code.DatabaseTokenManager.GetRequestToken(String token) in C:\Program Files\TimeTableWebService\sp\Code\DatabaseTokenManager.cs:line 31 
    --- End of inner exception stack trace --- 
    at OAuthServiceProvider.Code.DatabaseTokenManager.GetRequestToken(String token) in C:\Program Files\TimeTableWebService\sp\Code\DatabaseTokenManager.cs:line 35 
    at DotNetOpenAuth.OAuth.ChannelElements.OAuthServiceProviderMessageFactory.GetNewRequestMessage(MessageReceivingEndpoint recipient, IDictionary`2 fields) in c:\BuildAgent\work\a02b428f36957bca\src\DotNetOpenAuth\OAuth\ChannelElements\OAuthServiceProviderMessageFactory.cs:line 80 
    --- End of inner exception stack trace --- 
    at DotNetOpenAuth.OAuth.ChannelElements.OAuthServiceProviderMessageFactory.GetNewRequestMessage(MessageReceivingEndpoint recipient, IDictionary`2 fields) in c:\BuildAgent\work\a02b428f36957bca\src\DotNetOpenAuth\OAuth\ChannelElements\OAuthServiceProviderMessageFactory.cs:line 100 
    at OAuthServiceProvider.Code.CustomOAuthMessageFactory.GetNewRequestMessage(MessageReceivingEndpoint recipient, IDictionary`2 fields) in C:\Program Files\TimeTableWebService\sp\Code\CustomOAuthTypeProvider.cs:line 24 
    at DotNetOpenAuth.Messaging.Channel.Receive(Dictionary`2 fields, MessageReceivingEndpoint recipient) in c:\BuildAgent\work\a02b428f36957bca\src\DotNetOpenAuth\Messaging\Channel.cs:line 713 
    at DotNetOpenAuth.OAuth.ChannelElements.OAuthChannel.ReadFromRequestCore(HttpRequestInfo request) in c:\BuildAgent\work\a02b428f36957bca\src\DotNetOpenAuth\OAuth\ChannelElements\OAuthChannel.cs:line 194 
    at DotNetOpenAuth.Messaging.Channel.ReadFromRequest(HttpRequestInfo httpRequest) in c:\BuildAgent\work\a02b428f36957bca\src\DotNetOpenAuth\Messaging\Channel.cs:line 422 
    at OAuth.ProcessRequest(HttpContext context) in d:\oauthSiteTest\serviceprovider\v2\OAuth.ashx:line 21 
    at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() 
    at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) 
DotNetOpenAuth.Messaging.ProtocolException: A token in the message was not recognized by the service provider. ---> System.Collections.Generic.KeyNotFoundException: Unrecognized token ---> System.InvalidOperationException: Sequence contains no elements 
    at System.Data.Linq.SqlClient.SqlProvider.Execute(Expression query, QueryInfo queryInfo, IObjectReaderFactory factory, Object[] parentArgs, Object[] userArgs, ICompiledSubQuery[] subQueries, Object lastResult) 
    at System.Data.Linq.SqlClient.SqlProvider.ExecuteAll(Expression query, QueryInfo[] queryInfos, IObjectReaderFactory factory, Object[] userArguments, ICompiledSubQuery[] subQueries) 
    at System.Data.Linq.SqlClient.SqlProvider.System.Data.Linq.Provider.IProvider.Execute(Expression query) 
    at System.Data.Linq.Table`1.System.Linq.IQueryProvider.Execute[TResult](Expression expression) 
    at System.Linq.Queryable.First[TSource](IQueryable`1 source, Expression`1 predicate) 
    at OAuthServiceProvider.Code.DatabaseTokenManager.GetRequestToken(String token) in C:\Program Files\TimeTableWebService\sp\Code\DatabaseTokenManager.cs:line 31 
    --- End of inner exception stack trace --- 
    at OAuthServiceProvider.Code.DatabaseTokenManager.GetRequestToken(String token) in C:\Program Files\TimeTableWebService\sp\Code\DatabaseTokenManager.cs:line 35 
    at DotNetOpenAuth.OAuth.ChannelElements.OAuthServiceProviderMessageFactory.GetNewRequestMessage(MessageReceivingEndpoint recipient, IDictionary`2 fields) in c:\BuildAgent\work\a02b428f36957bca\src\DotNetOpenAuth\OAuth\ChannelElements\OAuthServiceProviderMessageFactory.cs:line 80 
    --- End of inner exception stack trace --- 
    at DotNetOpenAuth.OAuth.ChannelElements.OAuthServiceProviderMessageFactory.GetNewRequestMessage(MessageReceivingEndpoint recipient, IDictionary`2 fields) in c:\BuildAgent\work\a02b428f36957bca\src\DotNetOpenAuth\OAuth\ChannelElements\OAuthServiceProviderMessageFactory.cs:line 100 
    at OAuthServiceProvider.Code.CustomOAuthMessageFactory.GetNewRequestMessage(MessageReceivingEndpoint recipient, IDictionary`2 fields) in C:\Program Files\TimeTableWebService\sp\Code\CustomOAuthTypeProvider.cs:line 24 
    at DotNetOpenAuth.Messaging.Channel.Receive(Dictionary`2 fields, MessageReceivingEndpoint recipient) in c:\BuildAgent\work\a02b428f36957bca\src\DotNetOpenAuth\Messaging\Channel.cs:line 713 
    at DotNetOpenAuth.OAuth.ChannelElements.OAuthChannel.ReadFromRequestCore(HttpRequestInfo request) in c:\BuildAgent\work\a02b428f36957bca\src\DotNetOpenAuth\OAuth\ChannelElements\OAuthChannel.cs:line 194 
    at DotNetOpenAuth.Messaging.Channel.ReadFromRequest(HttpRequestInfo httpRequest) in c:\BuildAgent\work\a02b428f36957bca\src\DotNetOpenAuth\Messaging\Channel.cs:line 422 
    at OAuth.ProcessRequest(HttpContext context) in d:\oauthSiteTest\serviceprovider\v2\OAuth.ashx:line 21 
    at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() 
    at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) 


2012-05-18 13:05:27,382 (GMT+2) [6] DEBUG DotNetOpenAuth.Messaging.Channel - Preparing to send UnauthorizedTokenResponse (1.0.1) message. 
2012-05-18 13:05:27,430 (GMT+2) [6] DEBUG DotNetOpenAuth.Messaging.Bindings - Binding element DotNetOpenAuth.OAuth.ChannelElements.TokenHandlingBindingElement applied to message. 
2012-05-18 13:05:27,430 (GMT+2) [6] DEBUG DotNetOpenAuth.Messaging.Bindings - Binding element DotNetOpenAuth.OAuth.ChannelElements.OAuthHttpMethodBindingElement did not apply to message. 
2012-05-18 13:05:27,430 (GMT+2) [6] DEBUG DotNetOpenAuth.Messaging.Bindings - Binding element DotNetOpenAuth.Messaging.Bindings.StandardReplayProtectionBindingElement did not apply to message. 
2012-05-18 13:05:27,430 (GMT+2) [6] DEBUG DotNetOpenAuth.Messaging.Bindings - Binding element DotNetOpenAuth.Messaging.Bindings.StandardExpirationBindingElement did not apply to message. 
2012-05-18 13:05:27,430 (GMT+2) [6] DEBUG DotNetOpenAuth.Messaging.Bindings - Binding element DotNetOpenAuth.OAuth.ChannelElements.SigningBindingElementChain did not apply to message. 
2012-05-18 13:05:27,430 (GMT+2) [6] INFO DotNetOpenAuth.Messaging.Channel - Prepared outgoing UnauthorizedTokenResponse (1.0.1) message for <response>: 
    oauth_token: tdKwMhsNOyQPTiz+K5th/RZr0F8= 
    oauth_token_secret: UtfdLNG0VqrTGinchsNfjbyFBtE= 
    oauth_callback_confirmed: true 

2012-05-18 13:05:27,430 (GMT+2) [6] DEBUG DotNetOpenAuth.Messaging.Channel - Sending message: UnauthorizedTokenResponse 
2012-05-18 13:05:27,503 (GMT+2) [6] INFO DotNetOpenAuth.Messaging.Channel - Scanning incoming request for messages: https://websrv.hszuyd.nl/serviceprovider/v2/OAuth.ashx?oauth_token=tdKwMhsNOyQPTiz+K5th/RZr0F8= 
2012-05-18 13:05:27,512 (GMT+2) [6] ERROR DotNetOpenAuth.OAuthServiceProvider - An unhandled exception occurred in ASP.NET processing: DotNetOpenAuth.Messaging.ProtocolException: A token in the message was not recognized by the service provider. ---> System.Collections.Generic.KeyNotFoundException: Unrecognized token ---> System.InvalidOperationException: Sequence contains no elements 
    at System.Data.Linq.SqlClient.SqlProvider.Execute(Expression query, QueryInfo queryInfo, IObjectReaderFactory factory, Object[] parentArgs, Object[] userArgs, ICompiledSubQuery[] subQueries, Object lastResult) 
    at System.Data.Linq.SqlClient.SqlProvider.ExecuteAll(Expression query, QueryInfo[] queryInfos, IObjectReaderFactory factory, Object[] userArguments, ICompiledSubQuery[] subQueries) 
    at System.Data.Linq.SqlClient.SqlProvider.System.Data.Linq.Provider.IProvider.Execute(Expression query) 
    at System.Data.Linq.Table`1.System.Linq.IQueryProvider.Execute[TResult](Expression expression) 
    at System.Linq.Queryable.First[TSource](IQueryable`1 source, Expression`1 predicate) 
    at OAuthServiceProvider.Code.DatabaseTokenManager.GetRequestToken(String token) in C:\Program Files\TimeTableWebService\sp\Code\DatabaseTokenManager.cs:line 31 
    --- End of inner exception stack trace --- 
    at OAuthServiceProvider.Code.DatabaseTokenManager.GetRequestToken(String token) in C:\Program Files\TimeTableWebService\sp\Code\DatabaseTokenManager.cs:line 35 
    at DotNetOpenAuth.OAuth.ChannelElements.OAuthServiceProviderMessageFactory.GetNewRequestMessage(MessageReceivingEndpoint recipient, IDictionary`2 fields) in c:\BuildAgent\work\a02b428f36957bca\src\DotNetOpenAuth\OAuth\ChannelElements\OAuthServiceProviderMessageFactory.cs:line 80 
    --- End of inner exception stack trace --- 
    at DotNetOpenAuth.OAuth.ChannelElements.OAuthServiceProviderMessageFactory.GetNewRequestMessage(MessageReceivingEndpoint recipient, IDictionary`2 fields) in c:\BuildAgent\work\a02b428f36957bca\src\DotNetOpenAuth\OAuth\ChannelElements\OAuthServiceProviderMessageFactory.cs:line 100 
    at OAuthServiceProvider.Code.CustomOAuthMessageFactory.GetNewRequestMessage(MessageReceivingEndpoint recipient, IDictionary`2 fields) in C:\Program Files\TimeTableWebService\sp\Code\CustomOAuthTypeProvider.cs:line 24 
    at DotNetOpenAuth.Messaging.Channel.Receive(Dictionary`2 fields, MessageReceivingEndpoint recipient) in c:\BuildAgent\work\a02b428f36957bca\src\DotNetOpenAuth\Messaging\Channel.cs:line 713 
    at DotNetOpenAuth.OAuth.ChannelElements.OAuthChannel.ReadFromRequestCore(HttpRequestInfo request) in c:\BuildAgent\work\a02b428f36957bca\src\DotNetOpenAuth\OAuth\ChannelElements\OAuthChannel.cs:line 194 
    at DotNetOpenAuth.Messaging.Channel.ReadFromRequest(HttpRequestInfo httpRequest) in c:\BuildAgent\work\a02b428f36957bca\src\DotNetOpenAuth\Messaging\Channel.cs:line 422 
    at OAuth.ProcessRequest(HttpContext context) in d:\oauthSiteTest\serviceprovider\v2\OAuth.ashx:line 21 
    at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() 
    at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) 
DotNetOpenAuth.Messaging.ProtocolException: A token in the message was not recognized by the service provider. ---> System.Collections.Generic.KeyNotFoundException: Unrecognized token ---> System.InvalidOperationException: Sequence contains no elements 
    at System.Data.Linq.SqlClient.SqlProvider.Execute(Expression query, QueryInfo queryInfo, IObjectReaderFactory factory, Object[] parentArgs, Object[] userArgs, ICompiledSubQuery[] subQueries, Object lastResult) 
    at System.Data.Linq.SqlClient.SqlProvider.ExecuteAll(Expression query, QueryInfo[] queryInfos, IObjectReaderFactory factory, Object[] userArguments, ICompiledSubQuery[] subQueries) 
    at System.Data.Linq.SqlClient.SqlProvider.System.Data.Linq.Provider.IProvider.Execute(Expression query) 
    at System.Data.Linq.Table`1.System.Linq.IQueryProvider.Execute[TResult](Expression expression) 
    at System.Linq.Queryable.First[TSource](IQueryable`1 source, Expression`1 predicate) 
    at OAuthServiceProvider.Code.DatabaseTokenManager.GetRequestToken(String token) in C:\Program Files\TimeTableWebService\sp\Code\DatabaseTokenManager.cs:line 31 
    --- End of inner exception stack trace --- 
    at OAuthServiceProvider.Code.DatabaseTokenManager.GetRequestToken(String token) in C:\Program Files\TimeTableWebService\sp\Code\DatabaseTokenManager.cs:line 35 
    at DotNetOpenAuth.OAuth.ChannelElements.OAuthServiceProviderMessageFactory.GetNewRequestMessage(MessageReceivingEndpoint recipient, IDictionary`2 fields) in c:\BuildAgent\work\a02b428f36957bca\src\DotNetOpenAuth\OAuth\ChannelElements\OAuthServiceProviderMessageFactory.cs:line 80 
    --- End of inner exception stack trace --- 
    at DotNetOpenAuth.OAuth.ChannelElements.OAuthServiceProviderMessageFactory.GetNewRequestMessage(MessageReceivingEndpoint recipient, IDictionary`2 fields) in c:\BuildAgent\work\a02b428f36957bca\src\DotNetOpenAuth\OAuth\ChannelElements\OAuthServiceProviderMessageFactory.cs:line 100 
    at OAuthServiceProvider.Code.CustomOAuthMessageFactory.GetNewRequestMessage(MessageReceivingEndpoint recipient, IDictionary`2 fields) in C:\Program Files\TimeTableWebService\sp\Code\CustomOAuthTypeProvider.cs:line 24 
    at DotNetOpenAuth.Messaging.Channel.Receive(Dictionary`2 fields, MessageReceivingEndpoint recipient) in c:\BuildAgent\work\a02b428f36957bca\src\DotNetOpenAuth\Messaging\Channel.cs:line 713 
    at DotNetOpenAuth.OAuth.ChannelElements.OAuthChannel.ReadFromRequestCore(HttpRequestInfo request) in c:\BuildAgent\work\a02b428f36957bca\src\DotNetOpenAuth\OAuth\ChannelElements\OAuthChannel.cs:line 194 
    at DotNetOpenAuth.Messaging.Channel.ReadFromRequest(HttpRequestInfo httpRequest) in c:\BuildAgent\work\a02b428f36957bca\src\DotNetOpenAuth\Messaging\Channel.cs:line 422 
    at OAuth.ProcessRequest(HttpContext context) in d:\oauthSiteTest\serviceprovider\v2\OAuth.ashx:line 21 
    at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() 
    at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) 
2012-05-18 13:05:30,486 (GMT+2) [5] INFO DotNetOpenAuth.Messaging.Channel - Scanning incoming request for messages: https://websrv.hszuyd.nl/serviceprovider/v2/OAuth.ashx 
2012-05-18 13:05:30,487 (GMT+2) [5] DEBUG DotNetOpenAuth.Messaging.Channel - Incoming request received: RequestScopedTokenMessage 
2012-05-18 13:05:30,487 (GMT+2) [5] INFO DotNetOpenAuth.Messaging.Channel - Processing incoming RequestScopedTokenMessage (1.0.1) message: 
    scope: http://tempuri.org/DataApi/retrieveTimeTable 
    oauth_callback: x-oauthflow://callback/ 
    oauth_consumer_key: sampleconsumer 
    oauth_nonce: 913320039 
    oauth_signature_method: HMAC-SHA1 
    oauth_signature: yfPMlcFo6/NgJltyCLc++RMyQCY= 
    oauth_version: 1.0 
    oauth_timestamp: 1337339130 

回答

1

檢索我們會需要對異常的調用堆棧肯定知道。可能這個異常只是一個內部異常(ASP.NET有習慣報告內部異常而不是外部異常),並且外部異常可能會添加我們需要的上下文。既然你已經enabled logging,我希望你應該能夠從那裏獲得所有的異常細節。

如果/+字符未在HTTP URL中進行編碼,那麼應該修復客戶端中的錯誤。

+0

我已經添加了log4net文件 - 或者至少,大部分。不幸的是,整個事情太大而無法發佈(超過30000個字符)。希望這可以揭示一些事情。 – Nico

+0

啊,看來我們已經找到了解決辦法。你是對的,這是客戶端的一種編碼。基本上,通過使用java.net.URLEncoder,問題就解決了 - 即使在oauth_token包含'+'或'/'時,從android平臺發送調用時也不會出現更多異常。 – Nico