SignalR CryptographicException на AzureWebsites

Я получил это исключение с SignalR, развернутым на веб-сайтах Azure. Он отлично работает в среде отладки. Это SignalR 1.0.1, и я использую .NET MVC и WebApi.

The data protection operation was unsuccessful. This may have been caused by not having the user profile loaded for the current thread's user context, which may be the case when the thread is impersonating.

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. 

Exception Details: System.Security.Cryptography.CryptographicException: The data protection operation was unsuccessful. This may have been caused by not having the user profile loaded for the current thread's user context, which may be the case when the thread is impersonating.

Source Error: 

An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.

Stack Trace: 
[CryptographicException: The data protection operation was unsuccessful. This may have     been caused by not having the user profile loaded for the current thread's user context, which may be the case when the thread is impersonating.]
Microsoft.Owin.Host.SystemWeb.<>c__DisplayClass1.<GetRethrowWithNoStackLossDelegate>b__0(Exception ex) +27
Microsoft.Owin.Host.SystemWeb.Utils.RethrowWithOriginalStack(Exception ex) +15
Microsoft.Owin.Host.SystemWeb.CallContextAsyncResult.End(IAsyncResult result) +47
Microsoft.Owin.Host.SystemWeb.OwinHttpHandler.EndProcessRequest(IAsyncResult result) +7
System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +9629708
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +155

Есть ли у вас какие-либо идеи ? Спасибо


person Raph    schedule 13.03.2013    source источник
comment
Я предполагаю, что вы используете настраиваемый преобразователь зависимостей и не зарегистрировали правильные IProtectedData или внедрили Register, когда не должны были.   -  person davidfowl    schedule 14.03.2013
comment
Я использую Ninject и не регистрирую IProtectedData. Нужно ли мне ? Как ?   -  person Raph    schedule 14.03.2013
comment
Неважно, я пойду на Azure Cloud, спасибо   -  person Raph    schedule 14.03.2013
comment
Конечно? Я не уверен, какое отношение Azure Cloud имеет к этой проблеме. Вы делаете что-то не так, несмотря ни на что. Вы отменили регистрацию? Если вы это сделали, не делайте этого, и, скорее всего, это будет работать на лазурных веб-сайтах.   -  person davidfowl    schedule 15.03.2013
comment
Я не знаю как, но это работает с облачными вычислениями Azure. Я не отменил регистрацию.   -  person Raph    schedule 15.03.2013
comment
Я знаю, почему это работает, но это не значит, что ваш код исправлен. Если вас это устраивает, как есть, то все в порядке.   -  person davidfowl    schedule 15.03.2013


Ответы (4)


Для других, заходящих на эту страницу, у меня была та же проблема, но решение было намного проще. Как упоминалось в комментариях выше, принятый ответ плохой. Также упоминается, что SignalR по умолчанию использует MachineKeyDataProtector для IProtectedData. MapHubs и MapConnection вызывают функцию InitializeProtectedData, которая регистрирует MachineKeyDataProtector в распознавателе зависимостей.

Моя проблема заключалась в том, что я сопоставлял свои маршруты SignalR, а ЗАТЕМ настраивал преобразователь зависимостей.

RouteTable.Routes.MapConnection<SomeEndpoint>("SomeEndpoint", "SomeEndpointUrl");
GlobalHost.DependencyResolver = 
                     new StructureMapDependencyResolver(ObjectFactory.Container);

Таким образом, в основном регистрация преобразователя IProtectedData, выполненная MapConnection -> InitializeProtectedData, была снесена, когда я зарегистрировал свой собственный преобразователь. Простое исправление, установите преобразователь ДО сопоставления соединения.

GlobalHost.DependencyResolver = 
                     new StructureMapDependencyResolver(ObjectFactory.Container);
RouteTable.Routes.MapConnection<SomeEndpoint>("SomeEndpoint", "SomeEndpointUrl");
person Simon Fox    schedule 13.09.2013

Это единственный пост, который позволил мне решить ту же проблему, используя следующий код. Упоминание dfowlers о регистрации экземпляра IProtectedData привело меня к поиску и поиску определения здесь.

Обратите внимание, что эта проблема возникла не при использовании сервера разработки Visual Studio, а при переходе к работе. Я рад, что нашел этот пост, так как понятия не имею, как иначе я мог бы узнать о реализации IProtectedData. Может быть, в документации есть что-то более глубокое.

Является ли это 100% правильным решением, я не уверен, но это сработало для меня. Я создал класс, реализующий IProtectedData, а затем зарегистрировал его в Ninject.

Класс:

using Microsoft.AspNet.SignalR.Infrastructure;

namespace Fwr.DataTeamUploader.Logic
{
    public class ProtectedData : IProtectedData
    {

        // Obviously this isn't doing much to protect the data,
        // assume custom encryption required here

        // To reiterate, no encryption is VERY^4 BAD, see comments.

        public string Protect(string data, string purpose)
        {
            return data;
        }

        public string Unprotect(string protectedValue, string purpose)
        {
            return protectedValue;
        }
    }
}

Нинжект регистрация:

/// <summary>
/// Load your modules or register your services here
/// </summary>
/// <param name="kernel">The kernel.</param>
private static void RegisterServices(IKernel kernel)
{
    ...

    kernel.Bind<IProtectedData>().To<ProtectedData>();

    ...
person gb2d    schedule 03.04.2013
comment
Я бы не стал показывать такой код, потому что когда вы удаляете шифрование. Это ОЧЕНЬ ОЧЕНЬ ОЧЕНЬ ОЧЕНЬ ПЛОХО, так как теперь вы совершенно незащищены. Я знаю, вы упомянули, что у вас должна быть собственная криптография, но даже показывать ее с этим кодом просто плохо. Причина, по которой эта проблема возникает, заключается в том, что по какой-то странной причине используется неправильная защита данных. Предполагается использовать провайдера машинного ключа, который вызывает MapHubs в распознавателе зависимостей. - person davidfowl; 19.04.2013
comment
Спасибо dfowler. Я понимаю, что это означает, что связь не защищена в соответствии с примечаниями. Этот пост просто демонстрирует обходной путь самым простым способом. Эта ошибка обнаружилась при переходе от разработки с использованием SignalR 1.0.1 на компьютере с Win 7 к производственному серверу Win Server 2008 R2. Не имея другой информации об источнике проблемы, это был мой единственный способ ее исправить (с помощью специального шифрования). Можете ли вы предложить исправление, которое решает проблему лучше? Я отредактирую пост соответственно. - person gb2d; 19.04.2013
comment
Я согласен с @dfowler, но у меня была такая же проблема в среде DEV (Win 7 - VS 2010 - Unity IoC), и это единственное исправление, которое я нашел до сих пор. Любое предложение приветствуется! - person ab_732; 24.06.2013
comment
Скорее всего, виноват ваш Unity IoC. Скорее всего, вы по ошибке заменили защищенные данные, зарегистрированные при вызове MapHub, данными по умолчанию. Вызов MapHubs() регистрирует реализацию защищенных данных на основе машинного ключа вместо реализации по умолчанию, которая вызовет это исключение в Windows Azure. Если вы сможете понять, почему он заменяется, вы поймете проблему. - person davidfowl; 25.06.2013

Теперь в этом случае вы можете использовать метод расширения MapsHubs() из пакета Microsoft.AspNet.SignalR.SystemWeb.

MachineKeyProtectedData будет использоваться вместо реализации по умолчанию.

person Ben    schedule 03.09.2013

Я не верю, что веб-сайты Azure могут взаимодействовать с сертификатами/криптографическим API. Аналогичные проблемы возникают при попытке вызвать API управления Azure. Пользовательский контекст, в котором работают Сайты, не имеет для этого достаточных разрешений.

person Igorek    schedule 13.03.2013