我有一个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,但似乎没有任何效果。我做错了吗?是否存在一些内置的方式来处理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>();
}