asp.net - 在 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);
}
}
});
}
推荐阅读
- notifications - Android Pie 上的通知操作按钮文本总是全部大写
- java - 如何在 Java Weka API 中使用类不平衡技术 (SMOTE)?
- java - 在 JAVA 中读取非常大的动态嵌套 JSON 文件
- python - 使用 python 3.7 并通过 pip3 安装 pygame 但原子编辑器不会运行 pygame
- python - 在多面 Altair 图表中重复轴
- html - CSS宽度元素不做任何事情
- java - 我们如何在 Slim/Fitnesse 中获得断言的结果
- django - 'invalid_choice' 在字段外键 django
- sweetalert - 如何在 sweetalert2 队列中使用多个背景图像
- android - 启动时加载片段时应用程序崩溃