В настоящее время мы открываем приложение, которое использует библиотеку DotNetOpenAuth для защиты веб-сервиса SOAP через WAF через OAuth. Все это работает на IIS7. Веб-служба и библиотека DotNetOpenAuth работают бесперебойно, по крайней мере, при работе на ПК. Вызов службы с платформы Android, однако, вызывает несколько hickup. Иногда это будет нормально работать, и иногда это вызывает исключение, говорящее, что "последовательность не содержит элементов".
К сожалению, у меня нет всех подробностей, так как у меня на самом деле нет доступного андроида. Однако при чтении файлов журналов, созданных моими коллегами, выделяется несколько вещей.
Журнал событий Windows указывает, что это исключение KeyNotFoundException, которое происходит, потому что токен распознается (токен, по сути, присутствует в базе данных, поэтому это не должно happen-, которое я проверил).
Кроме того, что действительно интересно, заключается в том, что это исключение происходит только тогда, когда символ + или/присутствует в параметре 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
Нам понадобится колл-стоп исключения, чтобы точно знать. Вероятно, это исключение является лишь внутренним исключением (у ASP.NET есть привычка сообщать внутренние исключения, а не внешние), и внешнее исключение, скорее всего, добавит и контекст, который нам нужен. Я надеюсь, что с тех пор, как вы уже включили ведение журнала, вы сможете получить все детали исключения.
Если символы /
и +
не кодируются в URL-адресе HTTP, это ошибка в клиенте, которая должна быть исправлена.