SignalR CryptographicException на веб-сайтах Azure

Я получил это исключение с 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

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

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");

Это единственный пост, который позволил мне решить эту проблему, используя следующий код. Упоминание 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;
        }
    }
}

Ninject регистрация:

/// <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>();

    ...

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

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

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

Другие вопросы по тегам