Web服务器场(PCF)中的NetCore身份验证

时间:2019-03-21 16:38:03

标签: session authentication .net-core authorization pivotal-cloud-foundry

我有一个NetCore 2.1 API应用程序服务于Angular 5 UI前端。这两个应用程序均已部署到Pivotal Cloud Foundry(pcf)。

通过cookie authentication without Identity

实现身份验证
        services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
            .AddCookie(options =>
            {                   
                options.Cookie.Name = MyCookie;
                options.ExpireTimeSpan = TimeSpan.FromMinutes(30);
                options.Cookie.Expiration = TimeSpan.FromMinutes(30);
                options.Events.OnRedirectToLogin = context =>
                {
                    context.Response.StatusCode = 401;
                    ErrorHandlerUtility.HandleUnauthorizedError(context.HttpContext);
                    return Task.CompletedTask;
                };
                options.Events.OnRedirectToAccessDenied = context =>
                {
                    context.Response.StatusCode = 403;
                    ErrorHandlerUtility.HandleUnauthorizedError(context.HttpContext);
                    return Task.CompletedTask;
                };
            });`

然后在登录时:

        var principal = CreateClaimsPrincipal(claims);         
        context.User = principal;
        Thread.CurrentPrincipal = principal;

        await context.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, principal);

在注销时:

  if (Request?.Cookies != null)
        {
            await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
        }

一切正常,直到我将pcf实例放大(从1扩展到2)

当运行多个实例时,我似乎再也无法使用经过身份验证的用户来调用控制器(我被重定向到未经授权)。

//[Authorize(Policy = PolicyOwnerRequired)]
[Authorize]
public class SomeController : Controller

我研究了基于Cookie Authentication Early Expiration的redis会话,身份验证会话(ITicketStore)中可能缓存的用户

基于DataProtection with redis

查看了DataProtection

,但似乎没有任何效果。我做错了吗?是否存在一些内置的方式来处理Web场上运行的HttpContext的多个实例?还是应该研究一些自定义身份验证,而我只是从请求标头中读取Cookie?

谢谢

更新!!!

我当时正在使用SteelToe软件包来保存Redis的密钥。

services.AddDataProtection()
        .PersistKeysToRedis(redis, "DataProtection-Keys")
        .SetApplicationName("my_auth");

我更新为Microsoft.AspNetCore.DataProtection.StackExchangeRedis

它似乎正在工作。有人可以验证我的做法吗?目标是让多个用户能够登录和注销,而不受多个浏览器在多个实例之间的干扰

var redisConnection = ConnectionMultiplexer.Connect(RedisUtility.GetRedisConfigurations());
        var protectionProvider = CreateRedisProvider(redisConnection);

        // Data protection keys to persist in redis for authentication
        services.AddDataProtection().PersistKeysToStackExchangeRedis(redisConnection, "DataProtection-Keys")
            .SetApplicationName(applicationName);

        // Configure Cookie authentication
        services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
            .AddCookie(options =>
            {
                options.DataProtectionProvider = protectionProvider;
                options.Cookie.Name = cookieName;
                options.ExpireTimeSpan = TimeSpan.FromMinutes(30);
                options.Cookie.Expiration = TimeSpan.FromMinutes(30);
                options.Events.OnRedirectToLogin = context =>
                {
                    context.Response.StatusCode = 401;
                    ErrorHandlerUtility.HandleUnauthorizedError(context.HttpContext);
                    return Task.CompletedTask;
                };
                options.Events.OnRedirectToAccessDenied = context =>
                {
                    context.Response.StatusCode = 403;
                    ErrorHandlerUtility.HandleUnauthorizedError(context.HttpContext);
                    return Task.CompletedTask;
                };
            });

private static IDataProtectionProvider CreateRedisProvider(IConnectionMultiplexer connection)
    {
        return new ServiceCollection()
            .AddDataProtection()
            .PersistKeysToStackExchangeRedis(connection)
            .Services
            .BuildServiceProvider()
            .GetRequiredService<IDataProtectionProvider>();
    }

0 个答案:

没有答案