我们有多个应用程序,我们的用户可以通过我们的IdentityServer登录。他们都使用Cookie身份验证来保护网站,并使用令牌来保护其相关API。由于某些网站的功能,Cookie需要滑动才能运行。
引起的问题是,当cookie滑动时,它不会与我们的IdentityServer联系,这意味着服务器上的cookie可能会超时。当用户仅停留在已经使用过的应用程序中时,这很好,但是一旦用户连接到另一个应用程序,它将击中IdentityServer(其cookie超时)并被提示再次登录,尽管在其他应用程序中处于活动状态。 / p>
所以我想发生的事情是,每当客户端cookie滑动时,它仍然会击中IdentityServer,以使其cookie随之滑动。我愿意接受其他建议,但是我自己没有其他想法,并且由于我们的应用程序跨越各种.net平台(WebForms,MVC,Core)和工具集(尤其是Teleelek),因此我尝试提出像这样的通用解决方案。
代码:
IdentityServer cookie
// Configure auth cookie services.AddAuthentication(cookieSettings.CookieName) .AddCookie(cookieSettings.CookieName, options => { options.ExpireTimeSpan = TimeSpan.FromMinutes(cookieSettings.Expiration); // 4 hours options.SlidingExpiration = cookieSettings.AllowSliding; //true });
客户
public static void ConfigureOAuthForWebForms(this IAppBuilder app, OAuthSettings configuration)
{
// Use Cookies to Store JWT Token for Web Browsers
var cookieAuthenticationOptions = new CookieAuthenticationOptions
{
AuthenticationType = CookieAuthenticationDefaults.AuthenticationType,
CookieDomain = configuration.CookieDomain,
CookieName = configuration.CookieName,
CookieHttpOnly = configuration.CookieHttpOnly,
ExpireTimeSpan = configuration.AuthTimeout,
SlidingExpiration = configuration.AllowSlidingAuthTimeout
};
app.UseCookieAuthentication(cookieAuthenticationOptions);
// Turn off the JWT claim type mapping to allow well-known claims (e.g. ‘sub’ and ‘idp’) to flow through
JwtSecurityTokenHandler.InboundClaimTypeMap.Clear();
var openIdConnectAuthenticationOptions = new OpenIdConnectAuthenticationOptions
{
AuthenticationType = OpenIdConnectAuthenticationDefaults.AuthenticationType,
Authority = configuration.AuthorizationServerUri,
ClientId = configuration.Client,
PostLogoutRedirectUri = configuration.RedirectUri,
RedirectUri = configuration.RedirectUri,
ResponseType = configuration.ResponseType,
Scope = configuration.Scope,
SignInAsAuthenticationType = CookieAuthenticationDefaults.AuthenticationType,
UseTokenLifetime = configuration.UseAuthServerLifetime, // false
Notifications = new OpenIdConnectAuthenticationNotifications
{
SecurityTokenValidated = async n =>
{
var claimsToExclude = new[] { "aud", "iss", "nbf", "exp", "nonce", "iat", "at_hash", "c_hash", "idp", "amr" };
var claimsToKeep = n.AuthenticationTicket.Identity.Claims.Where(x => false == claimsToExclude.Contains(x.Type)).ToList();
claimsToKeep.Add(new Claim(AuthConstants.AuthenticationToken, n.ProtocolMessage.IdToken));
if (n.ProtocolMessage.AccessToken != null)
{
// Add access_token so we don't need to request it when calling APIs
claimsToKeep.Add(new Claim(AuthConstants.AccessToken, n.ProtocolMessage.AccessToken));
var userInfoClient = new UserInfoClient(new Uri(n.Options.Authority + "connect/userinfo").ToString());
var userInfoResponse = await userInfoClient.GetAsync(n.ProtocolMessage.AccessToken);
var userInfoClaims = userInfoResponse.Claims
.Where(x => x.Type != "sub") // filter sub since we're already getting it from id_token
.Select(x => new Claim(x.Type, x.Value));
claimsToKeep.AddRange(userInfoClaims);
}
var ci = new ClaimsIdentity(n.AuthenticationTicket.Identity.AuthenticationType, "name", "role");
ci.AddClaims(claimsToKeep);
if (!configuration.UseAuthServerLifetime)
{
n.AuthenticationTicket.Properties.IsPersistent = true;
n.AuthenticationTicket.Properties.ExpiresUtc = DateTimeOffset.UtcNow.Add(configuration.AuthTimeout); // 2 hours
n.AuthenticationTicket.Properties.AllowRefresh = configuration.AllowSlidingAuthTimeout; // true
}
n.AuthenticationTicket = new AuthenticationTicket(ci, n.AuthenticationTicket.Properties);
},
RedirectToIdentityProvider = n =>
{
if (n.ProtocolMessage.RequestType == OpenIdConnectRequestType.LogoutRequest)
n.ProtocolMessage.IdTokenHint = n.OwinContext.Authentication.User.FindFirst(AuthConstants.AuthenticationToken)?.Value;
return Task.FromResult(0);
}
}
};
// Authenticate to Auth Server
app.UseOpenIdConnectAuthentication(openIdConnectAuthenticationOptions);
app.UseStageMarker(PipelineStage.Authenticate);
}
答案 0 :(得分:1)
我只想延长IDP上的会话时长,然后就无需滑动它了。您可以使用max_age参数控制用户是否应该从任何给定的客户端再次进行身份验证。
答案 1 :(得分:0)
对于后代/未来使用,这是使用oidc-client调用Auth服务器并延长超时的延长超时的另一种方法。
1)从here
添加oidc-client.min.js2)将对新Oidc.UserManager()。signinSilent()的调用添加到document.ready上的母版页上
3)添加一个回调处理程序页面来处理该调用的返回结果
4)将回调页面添加到IdentityServer Clients回发uri
我还没有对这个解决方案进行全面的测试,但是我可以在需要时使其正常运行。但是现在,我可能只会使用@mackie的增加Auth服务器超时的解决方案。