【发布时间】:2021-04-04 14:44:19
【问题描述】:
为了学习和熟悉 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;
}
}
我很想知道如何使身份验证过期以强制登录重定向。我在这里唯一的猜测是中间位置在预初始化代码运行之前起作用。如果有什么问题,那么我可以在哪里进行这样的检查?
【问题讨论】:
-
一个想法,您可能会自动登录,因为您可能与 IdentityProvider 有一个有效的会话。因此,当您的本地会话到期时,中间件可能会尝试要求您再次登录,但如果您在那里有有效的会话,那么您可能会自动再次登录。
-
是的,我认为这就是它的要点。在 Azure 上,当我第一次登录时,我从来没有选择记住选项(或者它的措辞)。如果我能找到一种强制它登录的方法,我会更好地理解这一点。
-
您可以尝试设置以下内容以强制身份提供者在客户端尝试重新验证时强制用户同意请求的范围: ...AddOpenIdConnect(options => { ... options .Prompt = "同意"; });
-
所以,我的问题是我无法弄清楚如何在本地注销,而且我真的不明白这是我需要做的。为了在本地注销,我需要做的是://仅本地注销! HttpContext.Current.GetOwinContext().Authentication.SignOut(CookieAuthenticationDefaults.AuthenticationType);我现在了解了不同的注销级别以及如何调用它们。
标签: asp.net webforms azure-active-directory openid-connect