我正在开发一个带有Identity的ASP.NET Core 2.0应用程序来管理用户连接。
我有一些自定义的经理,商店和供应商,以满足我的应用程序的需要:
services.AddIdentity<Utilisateur, Profil>().AddUserManager<CustomUserManager<Utilisateur>>().AddRoleManager<CustomRoleManager>().AddDefaultTokenProviders();
services.AddTransient<IUserStore<Utilisateur>, UserStore>();
services.AddTransient<IRoleStore<Profil>, ProfileStore>();
services.AddTransient<IPermissionProvider, PermissionProvider>();
我已经为身份验证设置了应用程序cookie:
app.UseAuthentication();
和
services.ConfigureApplicationCookie(options =>
{
// Cookie settings
options.Cookie.HttpOnly = true;
options.ExpireTimeSpan = TimeSpan.FromMinutes(60);
// If the LoginPath isn't set, ASP.NET Core defaults the path to /Account/Login.
options.LoginPath = new PathString("/Connexion/Login");
options.LogoutPath = new PathString("/Connexion/SignedOut");
// If the AccessDeniedPath isn't set, ASP.NET Core defaults the path to /Account/AccessDenied.
options.AccessDeniedPath = new PathString("/Connexion/AccessDenied");
options.SlidingExpiration = true;
});
问题是,用户在30分钟后自动断开连接,即使他此时没有空闲并使用应用程序。
如何刷新或重新创建身份验证cookie以避免此问题?
我试图创建一个刷新cookie的方法,但似乎效果不太好。。。即使这样,用户也会断开连接。
[HttpPost]
[RefreshLogin]
[RequiresPermission("Pages.Modification")]
public IActionResult SavePagesOrder()
{...}
方法:
public class RefreshLoginAttribute : Microsoft.AspNetCore.Mvc.Filters.ActionFilterAttribute
{
public override async Task OnActionExecutionAsync(Microsoft.AspNetCore.Mvc.Filters.ActionExecutingContext context, Microsoft.AspNetCore.Mvc.Filters.ActionExecutionDelegate next)
{
await context.HttpContext.RefreshLoginAsync();
await next();
}
}
你有办法解决我的问题吗?
以下是我在IdentityServer 4中使用的解决方案。对不起,这可能很乱,但我希望你能领会要点。在这里,每次验证主体时,您都可以将您的访问权限和刷新令牌重写到cookie中。
services.AddAuthentication(options =>
{
options.DefaultScheme = "Cookies";
options.DefaultChallengeScheme = "oidc";
})
.AddCookie(CookieAuthenticationDefaults.AuthenticationScheme, options =>
{
options.Events = new CookieAuthenticationEvents
{
OnValidatePrincipal = async x =>
{
var now = DateTimeOffset.UtcNow;
var timeElapsed = now.Subtract(x.Properties.IssuedUtc.Value);
var timeRemaining = x.Properties.ExpiresUtc.Value.Subtract(now);
if (timeElapsed > timeRemaining)
{
var discoveryResponse = await DiscoveryClient.GetAsync(gatewaySettings.IdentitySeverAddress);
if (discoveryResponse.IsError)
{
throw new Exception(discoveryResponse.Error);
}
var identity = (ClaimsIdentity) x.Principal.Identity;
var accessTokenClaim = identity.FindFirst("access_token");
var refreshTokenClaim = identity.FindFirst("refresh_token");
var tokenClient = new TokenClient(discoveryResponse.TokenEndpoint, "MyApi", "secret");
var refreshToken = refreshTokenClaim.Value;
var tokenResponse = await tokenClient.RequestRefreshTokenAsync(refreshToken);
if (!tokenResponse.IsError)
{
identity.RemoveClaim(accessTokenClaim);
identity.RemoveClaim(refreshTokenClaim);
identity.AddClaims(new[]
{
new Claim("access_token", tokenResponse.AccessToken),
new Claim("refresh_token", tokenResponse.RefreshToken)
});
x.ShouldRenew = true;
}
}
}
};
})
也许它对你有帮助。