如何解决在 ASP.NET Web 窗体中使用 OpenId Connect 时的身份验证 Cookie 超时
为了学习和掌握 OpenID Connect 的速度,我正在尝试向使用 Azure AD 作为身份验证服务器的旧版 Web 窗体应用程序添加身份验证和授权。
我已经在一个方面卡住了好几天,无法取得任何进展。我想做一些我认为应该很简单的事情。与大多数情况不同,我希望应用程序超时并将用户重定向回 Azure 登录。理想情况下,我想从应用程序配置本身控制这个超时。每个人似乎都在问如何在到期时不被指示登录,但我想这样做是为了学习目的,并且只知道我可以控制它。
我的“问题”是,当身份验证 cookie 过期(或从浏览器中删除)时,我的 Request.IsAuthenticated 检查永远不会失败,并且令牌只是刷新。我永远无法让它强制登录。我觉得我已经尝试了一切,但找不到任何有意义的到期日。我什至不知道令牌是如何刷新的。
我已将此代码放在页面基类中。我希望在某个时候身份验证 cookie 会过期,并且此代码逻辑会像我第一次启动应用程序时一样强制执行挑战。我在这里尝试了各种方法。这可能会导致令牌刷新前的时间更短,但它永远不会过期。
private void Page_PreInit(object sender,EventArgs e)
{
if (!Request.IsAuthenticated)
{
HttpContext.Current.GetOwinContext().Authentication.Challenge(
new AuthenticationProperties
{
RedirectUri = "/",IsPersistent = true,//ExpiresUtc = DateTime.UtcNow.AddMinutes(1)
},OpenIdConnectAuthenticationDefaults.AuthenticationType); ;
Response.End();
}
}
以及启动配置:
public partial class Startup
{
public void ConfigureAuth(IAppBuilder app)
{
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = "Cookies",CookieManager = new Microsoft.Owin.Host.SystemWeb.SystemWebChunkingCookieManager(),//ExpireTimeSpan = new TimeSpan(0,1,0),SlidingExpiration = false,//Provider = new CookieAuthenticationProvider
//{
// OnResponseSignIn = context =>
// {
// context.Properties.AllowRefresh = false;
// context.Properties.ExpiresUtc = DateTimeOffset.UtcNow.AddMinutes(1);
// },//}
});
app.UseOpenIdConnectAuthentication(
new OpenIdConnectAuthenticationOptions
{
ClientId = AuthenticationConfig.ClientId,ClientSecret = AuthenticationConfig.ClientSecret,Authority = AuthenticationConfig.Authority,RedirectUri = AuthenticationConfig.RedirectUri,PostLogoutRedirectUri = AuthenticationConfig.PostLogoutRedirectUri,Scope = AuthenticationConfig.BasicSignInScopes + ' ' +
AuthenticationConfig.APIResourceUri + "access_as_user",SignInAsAuthenticationType = "cookie",RequireHttpsMetadata = false,UseTokenLifetime = true,// Needed to override default and allow custom auth cookie timout
RedeemCode = true,SaveTokens = true,ResponseType = OpenIdConnectResponseType.Code,ResponseMode = "query",// ValidateIssuer set to false to allow personal and work accounts from any organization to sign in to your application
// To only allow users from a single organizations,set ValidateIssuer to true and 'tenant' setting in web.config to the tenant name
// To allow users from only a list of specific organizations,set ValidateIssuer to true and use ValidIssuers parameter
TokenValidationParameters = new TokenValidationParameters()
{
ValidateIssuer = true,// This is a simplification
NameClaimType = AuthenticationConfig.NameClaimType,RoleClaimType = AuthenticationConfig.RoleClaimType
},Notifications = new OpenIdConnectAuthenticationNotifications()
{
SecurityTokenValidated = Startup.SecurityTokenValidated
}
});
// This makes any middleware defined above this line run before the Authorization rule is applied in web.config
app.UseStageMarker(PipelineStage.Authenticate);
}
public static Task SecurityTokenValidated(SecurityTokenValidatedNotification<OpenIdConnectMessage,OpenIdConnectAuthenticationOptions> notification)
{
var identity = notification.AuthenticationTicket.Identity;
identity.AddClaim(claim: new Claim(type: "expires_at",value: notification.ProtocolMessage.ExpiresIn));
identity.AddClaim(claim: new Claim(type: "id_token",value: notification.ProtocolMessage.IdToken));
identity.AddClaim(claim: new Claim(type: "access_token",value: notification.ProtocolMessage.AccessToken));
identity.AddClaim(claim: new Claim(type: "refresh_token",value: notification.ProtocolMessage.RefreshToken));
return Task.CompletedTask;
}
private static string EnsureTrailingSlash(string value)
{
if (value == null)
{
value = string.Empty;
}
if (!value.EndsWith("/",StringComparison.Ordinal))
{
return value + "/";
}
return value;
}
}
我很想知道如何使强制登录重定向的身份验证过期。我唯一的猜测是中间件在预初始化代码运行之前起作用。如果有什么问题,那么我可以在哪里进行此类检查?
解决方法
我不确定您是否解决了这个问题,但这是我们的配置,当用户未通过身份验证时会自动重定向用户。
public void ConfigureAuth(IAppBuilder app)
{
var secrets = DIFactory.GetInstance<IApplicationSecrets>();
var clientId = secrets.Ida_ClientId().Result;
var aadInstance = secrets.Ida_AADInstance().Result;
var tenantId = secrets.Ida_TenantId().Result;
var authority = string.Format(CultureInfo.InvariantCulture,aadInstance,tenantId);
/* Set authentication type to "Cookies" */
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
/* Add a cookie-based authentication middleware to the OWIN pipeline */
app.UseCookieAuthentication(
new CookieAuthenticationOptions
{
CookieName = "RemoteAuthCookie",AuthenticationType = "Cookies",CookieSecure = CookieSecureOption.Always,ExpireTimeSpan = TimeSpan.FromMinutes(2.0),SlidingExpiration = false,CookieSameSite = SameSiteMode.None,CookieManager = new SystemWebCookieManager(),// new SameSiteCookieManager(new SystemWebCookieManager()),});
app.UseOpenIdConnectAuthentication(
new OpenIdConnectAuthenticationOptions
{
ClientId = clientId,Authority = authority,Scope = "openid profile",//CookieManager = new SameSiteCookieManager(new SystemWebCookieManager()),// ResponseType is set to request the id_token - which contains basic information about the signed-in user
ResponseType = OpenIdConnectResponseTypes.IdToken,Notifications = new OpenIdConnectAuthenticationNotifications
{
RedirectToIdentityProvider = (context) =>
{
// This ensures that the address used for sign in and sign out is picked up dynamically from the request
var currentUrl = context.Request.Scheme + "://" + context.Request.Host + context.Request.Path;
context.ProtocolMessage.RedirectUri = currentUrl;
return Task.FromResult(0);
}
}
});
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。