簡體   English   中英

在 ASP.NET Web Forms 中使用 OpenId Connect 時的身份驗證 Cookie 超時

[英]Authentication Cookie Timeout when using OpenId Connect in ASP.NET Web Forms

作為學習和加快 OpenID Connect 速度的問題,我正在嘗試使用 Azure AD 作為舊版 Web Forms 應用程序添加身份驗證和授權。

幾天來我一直停留在一個方面,無法取得任何進展。 我想做一些我認為應該很簡單的事情。 與大多數不同,我希望應用程序超時並將用戶重定向回 Azure 登錄。 理想情況下,我想從應用程序配置本身控制這個超時。 每個人似乎都在問如何在到期時不被引導登錄,但我想這樣做是為了學習目的,並且只知道我可以控制它。

我的“問題”是,當身份驗證 cookie 過期(或從瀏覽器中刪除)時,我的 Request.IsAuthenticated 檢查永遠不會失敗,並且只會刷新令牌。 我永遠無法強制登錄。 我覺得我已經嘗試了一切,但找不到任何意味着什么的過期。 我什至不知道令牌是如何刷新的。

我已將此代碼放在頁面基礎 class 中。 我希望在某個時候身份驗證 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);
                    }
                }
            });
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM