电竞比分网-中国电竞赛事及体育赛事平台

分享

c# – 太多OpenID.nonce cookie導(dǎo)致“錯(cuò)誤請(qǐng)求”

 印度阿三17 2019-05-22

我使用IdentiServer3進(jìn)行身份驗(yàn)證的Silverlight應(yīng)用程序,當(dāng)我實(shí)現(xiàn)注銷(xiāo)功能時(shí),我剛開(kāi)始遇到這個(gè)問(wèn)題.請(qǐng)注意,該問(wèn)題與Silverlight無(wú)關(guān),因?yàn)榈卿浐妥N(xiāo)功能實(shí)際上是在服務(wù)器端實(shí)現(xiàn)的,這是一個(gè)傳統(tǒng)的ASP.Net Web表單. (.NET 4.5.1)

該應(yīng)用程序從未具有注銷(xiāo)功能,因此用戶(hù)只是用來(lái)關(guān)閉瀏覽器,所以我們以前從未遇到過(guò)這個(gè)問(wèn)題.我們現(xiàn)在有l(wèi)ogout.aspx頁(yè)面,Silverlight應(yīng)用程序有這個(gè)頁(yè)面的鏈接.

Logout.aspx頁(yè)面

public partial class Logout : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        if (Request.IsAuthenticated)
        {
            Session.Clear();
            Request.GetOwinContext().Authentication.SignOut();
        }
        Response.Redirect("/");
    }
}

Default.aspx頁(yè)面.這是首頁(yè)

public partial class Default : Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        // Send an OpenID Connect sign-in request.
        if (!System.Web.HttpContext.Current.Request.IsAuthenticated)
        {
            HttpContext.Current.GetOwinContext().Authentication.Challenge(new AuthenticationProperties { RedirectUri = "/" }, OpenIdConnectAuthenticationDefaults.AuthenticationType);
        }
    }
} 

配置OpenID連接的OWIN啟動(dòng)類(lèi)

  app.UseCookieAuthentication(new CookieAuthenticationOptions
        {
            AuthenticationType = "Cookies",
            LoginPath = new Microsoft.Owin.PathString("/Default.aspx")
        });

  app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
        {
            Authority = ConfigurationManager.AppSettings["Authority"],
            Scope = "openid profile",
            ClientId = ConfigurationManager.AppSettings["ClientId"],
            RedirectUri = ConfigurationManager.AppSettings["RedirectUri"],
            ResponseType = "id_token",
            SignInAsAuthenticationType = "Cookies",

            Notifications = new OpenIdConnectAuthenticationNotifications
            {
                SecurityTokenValidated = (context) =>
                {

                    var id = context.AuthenticationTicket.Identity;

                    // create new identity
                    var newIdentity = new ClaimsIdentity(id.AuthenticationType);

                    // we want to keep username and subjectid                        
                    var sub = id.FindFirst(ClaimTypes.NameIdentifier);
                    var username = id.FindFirst("preferred_username");
                    newIdentity.AddClaim(username);
                    newIdentity.AddClaim(sub);

                    // keep the id_token for logout
                    newIdentity.AddClaim(new Claim("id_token", context.ProtocolMessage.IdToken));

                    context.AuthenticationTicket = new AuthenticationTicket(
                        newIdentity,
                        context.AuthenticationTicket.Properties);

                    return Task.FromResult(0);
                },

                RedirectToIdentityProvider = (context) =>
                {
                    if (context.ProtocolMessage.RequestType == OpenIdConnectRequestType.LogoutRequest)
                    {
                        var idTokenHint = context.OwinContext.Authentication.User.FindFirst("id_token").Value;
                        context.ProtocolMessage.IdTokenHint = idTokenHint;
                    }
                    return Task.FromResult(0);
                },                    
            }

重現(xiàn)問(wèn)題的步驟:

>我鍵入網(wǎng)站URL,將我重定向到identityserver3登錄
頁(yè).
>我輸入憑據(jù)并點(diǎn)擊登錄.
>成功登錄后我
被重定向到網(wǎng)站,然后我點(diǎn)擊退出.
>我得到了記錄
成功了. Fiddler顯示以下呼叫

https://idsvr./identity/connect/endsession?id_token_hint=XXXXXXXXXXXXXX
https://idsvr./identity/logout?id=616dd9a4e4c6a55b0bb27faceb4df8dd
https://idsvr./identity/connect/endsessioncallback?sid=xxxxxx
>我按預(yù)期登陸https://idsvr./identity/logout?id=xxxxxxx頁(yè)面.
>現(xiàn)在我關(guān)閉瀏覽器(這一步很重要)
>現(xiàn)在再次鍵入網(wǎng)站URL,將我重定向到身份服務(wù)器登錄頁(yè)面. (如第1步)
>我輸入憑據(jù)并點(diǎn)擊登錄.
>成功登錄后,IdentityServer對(duì)網(wǎng)站進(jìn)行POST,網(wǎng)站創(chuàng)建AuthenticationTicket.但是,此處HttpContext.Current.Request.IsAuthenticated為false,因此Default.aspx頁(yè)面重定向到IdentityServer.我已登錄,因此Indetityserver重定向到客戶(hù)端網(wǎng)站并繼續(xù)循環(huán).

Fiddler展示了從identityServer到網(wǎng)站default.aspx頁(yè)面的幾次往返.每次往返都會(huì)不斷添加OpenIdConnect.nonce.OpenIdConnect cookie,最終由于最大請(qǐng)求大小而導(dǎo)致錯(cuò)誤的請(qǐng)求錯(cuò)誤.

因此,正如上面鏈接所示,我將Microsoft.Owin.Security.OpenIdConnect降級(jí)為客戶(hù)端應(yīng)用程序中的3.0.0.

但是,我仍然陷入持續(xù)循環(huán).唯一的區(qū)別是現(xiàn)在它沒(méi)有為每次往返添加新的OpenIdConnect.nonce.OpenIdConnect cookie. Fiddler每次往返只顯示一個(gè)餅干.但是HttpContext.Current.Request.IsAuthenticated仍然是假的.所以我陷入了連續(xù)循環(huán).

解決方法:

我的asp.net mvc應(yīng)用程序遇到了類(lèi)似的問(wèn)題.經(jīng)過(guò)一些研究后,我發(fā)現(xiàn)Microsoft的Owin實(shí)現(xiàn)System.Web存在一個(gè)錯(cuò)誤.在IIS上運(yùn)行Owin應(yīng)用程序時(shí)使用的那個(gè).如果我們?cè)贏SP.NET MVC5中使用基于Owin的新身份驗(yàn)證處理,那么我們99%的人可能會(huì)這樣做.

這個(gè)bug讓Owin設(shè)置的cookie在某些場(chǎng)合神秘地消失了.

這個(gè)中間件是該bug的修復(fù)程序.在任何處理中間件的cookie之前簡(jiǎn)單地添加它,它將保留身份驗(yàn)證cookie.

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶(hù)發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買(mǎi)等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶(hù) 評(píng)論公約

    類(lèi)似文章 更多