我們目前正在使用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
我已經添加了log4net文件 - 或者至少,大部分。不幸的是,整個事情太大而無法發佈(超過30000個字符)。希望這可以揭示一些事情。 – Nico
啊,看來我們已經找到了解決辦法。你是對的,這是客戶端的一種編碼。基本上,通過使用java.net.URLEncoder,問題就解決了 - 即使在oauth_token包含'+'或'/'時,從android平臺發送調用時也不會出現更多異常。 – Nico