部署在负载均衡器

时间:2016-11-01 22:59:02

标签: iis asp.net-core antiforgerytoken

我在Asp.Net Core 1.0网站上设置了AntiForgery令牌,如下所示:

  services.AddAntiforgery(options =>
        {
            options.HeaderName = "X-XSRF-Token"; //Angular's default header name for sending the xsrf token
        });
app.Use(next => context =>
        {
            //2 tokens are generated.  A Cookie token, which goes in an ASP cookie called something like .AspNetCore.Antiforgery.****** and a request token.  The request token gets passed in the http request
            //headers back to the server when executing a POST and is validated agains't the cookie token.  By taking the request token and putting it in an HTTP-Only cookie called XSRF-TOKEN, Angular will 
            //automatically take the cookie and add it to an X-XSRF-Token header for each request.   The request token received in the header is then validated against the cookie token. In ConfigureServices() above, 
            //ASP's antiforgery system is setup to look for the request token in the X-XSRF-Token header.  For form posts (i.e. not posts done by Angular), the form has a token associated with it that gets passed in the POST
            // which is used in place of the header token  
            var tokens = antiforgery.GetAndStoreTokens(context);
            context.Response.Cookies.Append("XSRF-TOKEN", tokens.RequestToken, new CookieOptions() { HttpOnly = false });

            return next(context);
        });

        app.UseAntiForgeryValidation();
public class AntiForgeryValidation
{
    private readonly RequestDelegate _next;
    IAntiforgery _antiforgery;
    private ILogger<AntiForgeryValidation> _logger;

    public AntiForgeryValidation(RequestDelegate next, IAntiforgery antiforgery, ILoggerFactory loggerFactory)
    {
        _next = next;
        _antiforgery = antiforgery;
        _logger = loggerFactory.CreateLogger<AntiForgeryValidation>();
    }

    public async Task Invoke(HttpContext context)
    {
        //don't need to validate anti-forgery tokens for GET
        if (string.Equals("POST", context.Request.Method, StringComparison.OrdinalIgnoreCase)
            || string.Equals("PUT", context.Request.Method, StringComparison.OrdinalIgnoreCase)
            || string.Equals("DELETE", context.Request.Method, StringComparison.OrdinalIgnoreCase))
        {

            await _antiforgery.ValidateRequestAsync(context);
        }

        await _next(context);
    }
}

public static partial class MiddlewareExtensionMethods
{
    public static void UseAntiForgeryValidation(this IApplicationBuilder builder)
    {
        builder.UseMiddleware<AntiForgeryValidation>();
    }
}

在我的开发环境中,当发布到IIS时,这很有效。我的网站前面有一个负载均衡器,当我通过负载均衡器提供的VIP访问它时,我的防伪验证开始失败并出现以下错误:

密钥环中找不到

{7f02de42-e781-4c27-a2e5-fce932f4b7a4}。 Unprotect操作无法继续

应用程序抛出了未处理的异常。无法解密防伪令牌。

(更多日志在下面)。

我还应该指出,尽管有一个负载均衡器,但它背后只有一个Web服务器,所以在服务器之间分配请求不应该有任何问题。如果有人知道为什么在通过负载均衡器访问时会发生这种情况而不是直接访问(通过主机条目绕过负载均衡器),我会很乐意帮助。

日志 2016-11-01 15:28:01.3761 | 22 | TRACE | Microsoft.Extensions.Logging.LoggingExtensions.PerformingUnprotectOperationToKeyWithPurposes |对密钥{4441518f-1b1d-49a8-b06a-29724cb692ae}执行取消保护操作(&#39; C: \ temp \ wizard&#39;,&#39; Microsoft.AspNetCore.Antiforgery.AntiforgeryToken.v1&#39;)。 2016-11-01 15:28:01.4074 | 22 | TRACE | Microsoft.Extensions.Logging.LoggingExtensions.PerformingProtectOperationToKeyWithPurposes |对密钥{4441518f-1b1d-49a8-b06a-29724cb692ae}执行保护操作(&#39; C: \ temp \ wizard&#39;,&#39; Microsoft.AspNetCore.Antiforgery.AntiforgeryToken.v1&#39;)。 2016-11-01 15:28:01.4074 | 22 | DEBUG | Microsoft.AspNetCore.Antiforgery.Internal.DefaultAntiforgery.GetAndStoreTokens |重复使用防伪cookie令牌。 2016-11-01 15:28:01.4230 | 22 | TRACE | Microsoft.Extensions.Logging.LoggingExtensions.PerformingUnprotectOperationToKeyWithPurposes |执行取消保护操作以锁定{7f02de42-e781-4c27-a2e5-fce932f4b7a4}(&#39; C: \ temp \ wizard&#39;,&#39; Microsoft.AspNetCore.Antiforgery.AntiforgeryToken.v1&#39;)。 2016-11-01 15:28:01.4230 | 22 |在密钥环中找不到TRACE | Microsoft.Extensions.Logging.LoggingExtensions.KeyWasNotFoundInTheKeyRingUnprotectOperationCannotProceed | Key {7f02de42-e781-4c27-a2e5-fce932f4b7a4}。 Unprotect操作无法继续。 2016-11-01 15:28:01.4230 | 22 |错误| Microsoft.AspNetCore.Server.Kestrel.Internal.Http.Frame`1.RequestProcessingAsync |连接ID&#34; 0HL02KLA3LKUJ&#34;:未处理的异常被抛出应用程序。防伪令牌无法解密。 2016-11-01 15:28:01.4230 | 22 | INFO | Microsoft.AspNetCore.Hosting.Internal.HostingLoggerExtensions.RequestFinished |请求在44.7391ms完成200 2016-11-01 15:28:01.4230 | 22 | DEBUG | Microsoft.AspNetCore.Server.Kestrel.Internal.Http.Connection.Microsoft.AspNetCore.Server.Kestrel.Internal.Http.IConnectionControl.End | Connection id&#34 ; 0HL02KLA3LKUJ&#34;完成了保持活跃的反应。

更新

我已添加

 services.AddDataProtection()
            .PersistKeysToFileSystem(new DirectoryInfo(@"c:\temp\"));

并且密钥持久保存到c:\ temp \但我仍然遇到问题。更新的日志如下。关键:{f5087f37-37e3-4e52-b40b-77e32a285f3e}被写入c:\ temp并被选为默认密钥,但仍有一些神秘的密钥{4441518f-1b1d-49a8-b06a-29724cb692ae}应用程序试图用来解密无法找到的反伪造令牌。

2016-11-02 07:19:28.7357 | 1 | DEBUG | Microsoft.AspNetCore.Hosting.Internal.HostingLoggerExtensions.Starting |主持开始 2016-11-02 07:19:28.8450 | 1 | DEBUG | Microsoft.AspNetCore.Hosting.Internal.HostingLoggerExtensions.Started |主机启动 2016-11-02 07:19:29.0326 | 7 | DEBUG | Microsoft.AspNetCore.Server.Kestrel.Internal.Http.Connection.Start |连接ID&#34; 0HL035D0UCHEL&#34;开始。 2016-11-02 07:19:29.1107 | 3 | INFO | Microsoft.AspNetCore.Hosting.Internal.HostingLoggerExtensions.RequestStarting |请求启动HTTP / 1.1 POST http://apidev.brewster.ca/ application / x-www-form-urlencoded 218 2016-11-02 07:19:29.1263 | 3 | DEBUG | Microsoft.AspNetCore.HttpOverrides.ForwardedHeadersMiddleware.ApplyForwarders | X-Forwarded-For和X-Forwarded-Proto之间的参数计数不匹配。 2016-11-02 07:19:29.1732 | 3 | TRACE | Microsoft.Extensions.Logging.LoggingExtensions.PerformingUnprotectOperationToKeyWithPurposes |对密钥{4441518f-1b1d-49a8-b06a-29724cb692ae}执行取消保护操作(&#39; C: \ webpublish \ wizard&#39;,&#39; Microsoft.AspNetCore.Antiforgery.AntiforgeryToken.v1&#39;)。 2016-11-02 07:19:29.1888 | 3 | DEBUG | Microsoft.AspNetCore.DataProtection.Repositories.FileSystemXmlRepository.ReadElementFromFile |从文件中读取数据&c; \ temp \ key-f5087f37-37e3-4e52-b40b- 77e32a285f3e.xml&#39 ;. 2016-11-02 07:19:29.1888 | 3 | DEBUG | Microsoft.Extensions.Logging.LoggingExtensions.FoundKey |找到密钥{f5087f37-37e3-4e52-b40b-77e32a285f3e}。 2016-11-02 07:19:29.2200 | 3 | DEBUG | Microsoft.Extensions.Logging.LoggingExtensions.ConsideringKeyWithExpirationDateAsDefaultKey |考虑密钥{f5087f37-37e3-4e52-b40b-77e32a285f3e},截止日期2017-01-31 14:11: 02Z为默认密钥。 2016-11-02 07:19:29.2357 | 3 | DEBUG | Microsoft.Extensions.Logging.LoggingExtensions.OpeningCNGAlgorithmFromProviderWithChainingModeCBC |打开CNG算法&#39; AES&#39;来自提供商&#39;&#39;与链接模式CBC。 2016-11-02 07:19:29.2513 | 3 | DEBUG | Microsoft.Extensions.Logging.LoggingExtensions.OpeningCNGAlgorithmFromProviderWithHMAC |打开CNG算法&#39; SHA256&#39;来自提供商&#39;&#39;与HMAC。 2016-11-02 07:19:29.2670 | 3 | DEBUG | Microsoft.Extensions.Logging.LoggingExtensions.UsingKeyAsDefaultKey |使用密钥{f5087f37-37e3-4e52-b40b-77e32a285f3e}作为默认密钥。 2016-11-02 07:19:29.2670 | 3 | TRACE | Microsoft.Extensions.Logging.LoggingExtensions.KeyWasNotFoundInTheKeyRingUnprotectOperationCannotProceed | Key {4441518f-1b1d-49a8-b06a-29724cb692ae}在密钥环中找不到。 Unprotect操作无法继续。 2016-11-02 07:19:29.2670 | 3 |错误| Microsoft.AspNetCore.Antiforgery.Internal.DefaultAntiforgery.GetCookieTokenDoesNotThrow |反序列化令牌时抛出异常。无法解密防伪令牌。 2016-11-02 07:19:29.2982 | 3 | TRACE | Microsoft.Extensions.Logging.LoggingExtensions.PerformingProtectOperationToKeyWithPurposes |对目的进行保护操作{f5087f37-37e3-4e52-b40b-77e32a285f3e}(&#39; C: \ webpublish \ wizard&#39;,&#39; Microsoft.AspNetCore.Antiforgery.AntiforgeryToken.v1&#39;)。 2016-11-02 07:19:29.2982 | 3 | TRACE | Microsoft.Extensions.Logging.LoggingExtensions.PerformingProtectOperationToKeyWithPurposes |对目的进行保护操作{f5087f37-37e3-4e52-b40b-77e32a285f3e}(&#39; C: \ webpublish \ wizard&#39;,&#39; Microsoft.AspNetCore.Antiforgery.AntiforgeryToken.v1&#39;)。 2016-11-02 07:19:29.3138 | 3 | DEBUG | Microsoft.AspNetCore.Antiforgery.Internal.DefaultAntiforgery.GetAndStoreTokens |创建了一个新的防伪cookie令牌。 2016年11月2日07:19:29.3296 | 3 | DEBUG | VTR.Common.Utilities.Middleware.AntiForgeryValidation.Invoke | AntiForgeryCookie:[.AspNetCore.Antiforgery.2mRY6wjt_Lw,CfDJ8I9RQUQdG6hJsGopcky2kq4ayXKUx4xErDElnyDij0J31qSLHyt3oKyqJ1ocoRHYoIkK7WSpze9SVEzOan0LQTFs3SwwtvMUw_e6EUPvaPxWjH_1_pQ5DiT8hu7TM8UNWjjFT_XSkNZz-uBVHdh2CmY] 2016年11月2日07:19:29.3296 | 3 | DEBUG | VTR.Common.Utilities.Middleware.AntiForgeryValidation.Invoke | XSRF饼干:CfDJ8I9RQUQdG6hJsGopcky2kq45_O5j5bzBP5QyxbzIKXaSbb8K04mez2Czsa_OdCYn84bvSz2v8M-nkN_O6yorN8qfyy4mV3HdGJV3BQgWSHSFrziJfQonBKmiF4fsrmpHVX7jA6iugirWL8yNJPO35xY 2016年11月2日07:19:29.3607 | 3 | DEBUG | VTR.Common.Utilities.Middleware.AntiForgeryValidation.Invoke |形式表征:CfDJ8ELeAn-B5ydMouX86TL0t6R3a1YFIaw2K3Wf6xpsbQPGztGb2uACGCdnofeFKd-woGFkwTjWQEC4Qag1E2A2RCxtvry4DJAvPSZnbKZGMd248exLwt9CX1bhWsYj8Cs6N9MvEQ38gqEXmEArDXFYMM0 2016-11-02 07:19:29.3607 | 3 | DEBUG | VTR.Common.Utilities.Middleware.AntiForgeryValidation.Invoke | Header Token: 2016-11-02 07:19:29.3768 | 3 | TRACE | Microsoft.Extensions.Logging.LoggingExtensions.PerformingUnprotectOperationToKeyWithPurposes |执行取消保护操作以锁定{7f02de42-e781-4c27-a2e5-fce932f4b7a4}(&#39; C: \ webpublish \ wizard&#39;,&#39; Microsoft.AspNetCore.Antiforgery.AntiforgeryToken.v1&#39;)。 2016-11-02 07:19:29.3768 | 3 | TRACE | Microsoft.Extensions.Logging.LoggingExtensions.KeyWasNotFoundInTheKeyRingUnprotectOperationCannotProceed | Key {7f02de42-e781-4c27-a2e5-fce932f4b7a4}未在密钥环中找到。 Unprotect操作无法继续。 2016-11-02 07:19:29.3768 | 3 |错误| Microsoft.AspNetCore.Server.Kestrel.Internal.Http.Frame`1.RequestProcessingAsync |连接ID&#34; 0HL035D0UCHEL&#34;:抛出未处理的异常应用程序。防伪令牌无法解密。 2016-11-02 07:19:29.3768 | 3 | INFO | Microsoft.AspNetCore.Hosting.Internal.HostingLoggerExtensions.RequestFinished |请求在286.4265ms完成200 2016-11-02 07:19:29.4233 | 3 | DEBUG | Microsoft.AspNetCore.Server.Kestrel.Internal.Http.Connection.Microsoft.AspNetCore.Server.Kestrel.Internal.Http.IConnectionControl.End | Connection id&#34 ; 0HL035D0UCHEL&#34;完成了保持活跃的反应。

1 个答案:

答案 0 :(得分:0)

问题是由负载均衡器上的缓存问题引起的。刷新缓存后,丢失的密钥问题就消失了