Отправка oauth-токена из Android вызывает KeyNotFoundException

1

В настоящее время мы открываем приложение, которое использует библиотеку 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
Теги:
soap
wcf
dotnetopenauth

1 ответ

1
Лучший ответ

Нам понадобится колл-стоп исключения, чтобы точно знать. Вероятно, это исключение является лишь внутренним исключением (у ASP.NET есть привычка сообщать внутренние исключения, а не внешние), и внешнее исключение, скорее всего, добавит и контекст, который нам нужен. Я надеюсь, что с тех пор, как вы уже включили ведение журнала, вы сможете получить все детали исключения.

Если символы / и + не кодируются в URL-адресе HTTP, это ошибка в клиенте, которая должна быть исправлена.

  • 0
    Я добавил файлы log4net - или, по крайней мере, большинство из них. К сожалению, все это слишком велико для публикации (более 30000 символов). Надеюсь, это поможет пролить свет на некоторые вещи.
  • 0
    Ах, похоже, мы нашли решение. Вы были правы, это было в кодировке клиента. В основном, с помощью java.net.URLEncoder, проблема решена - больше нет исключений при отправке вызова с платформы Android, даже когда oauth_token содержит «+» или «/».

Ещё вопросы

Сообщество Overcoder
Наверх
Меню