先來看下下面的配置:
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear(); services.AddAuthentication( options => { options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme; options.DefaultChallengeScheme = "oidc"; } ) .AddCookie(options=> { options.ExpireTimeSpan = TimeSpan.FromMinutes(60); options.Cookie.Name = "lym.Cookies"; }) //監控瀏覽器Cookies不難發現有這樣一個 .AspNetCore.lym.Cookies 記錄了加密的授權信息 .AddOpenIdConnect("oidc", options => { options.Authority = customUrl; options.ClientId = "lym.clienttest"; options.ClientSecret = "lym.clienttest"; options.RequireHttpsMetadata = false; options.SaveTokens = true; options.ResponseType = "code id_token"; //布爾值來設置處理程序是否應該轉到用戶信息端點檢索。額外索賠或不在id_token創建一個身份收到令牌端點。默認為“false” options.GetClaimsFromUserInfoEndpoint = true; options.Scope.Add("openid"); options.Scope.Add("profile"); options.Scope.Add("cloudservices"); });
idroptions.Authentication = new IdentityServer4.Configuration.AuthenticationOptions { //監控瀏覽器cookie不難發現lym.Cookies=8660972474e55224ff37f7421c79a530 實際是cookie記錄服務器session的名稱 CheckSessionCookieName = "lym.SessionId", // CookieAuthenticationDefaults.AuthenticationScheme,//用於檢查會話端點的cookie的名稱 CookieLifetime = new TimeSpan(1, 0, 0),//身份驗證Cookie生存期(僅在使用IdentityServer提供的Cookie處理程序時有效) CookieSlidingExpiration = true,//指定cookie是否應該滑動(僅在使用IdentityServer提供的cookie處理程序時有效) RequireAuthenticatedUserForSignOutMessage = true //指示是否必須對用戶進行身份驗證才能接受參數以結束會話端點。默認為false };
CheckSessionCookieName 是客戶端保留的SessionId,當我們登錄后記錄到瀏覽器中

而 AddAuthentication 中的設置 用作所有其他默認值的回退默認方案,就是在我們退出的時候會根據這個key去Signout
下來來看退出
HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme); HttpContext.SignOutAsync("oidc");
官方說明中這個值可以改變
修改方式:
services.AddAuthentication( options => { options.DefaultScheme = "lym.oauth.cookies"; options.DefaultChallengeScheme = "oidc"; } ) .AddCookie("lym.oauth.cookies", options=> { options.ExpireTimeSpan = TimeSpan.FromMinutes(60); options.Cookie.Name = "lym.idrserver"; })
在下種可以看到 我有 lym.Cookies 和 lym.WebSite 兩個cookies,其實這是我的兩個站點cookies 這是個SSO

值得注意的是這里兩個站點的cookies設置
.AddCookie(options => { options.ExpireTimeSpan = TimeSpan.FromMinutes(60); options.Cookie.Name = "lym.website"; })
.AddCookie(options=> { options.ExpireTimeSpan = TimeSpan.FromMinutes(60); options.Cookie.Name = "lym.Cookies"; })
這里cookies不能設置成一樣的key,如果設置一樣的會導致覆蓋問題,存在一個站點A覆蓋站點B的值 導致登錄一個站點A后 反問B 又需要重新登錄的情況,因為2個站點用的不同的客戶端,授權轉向的資源地址不同,所以ValidatorAuthorization的是沒有授權的,然后轉到登錄
接下來就是退出的SignOut的問題了,這里可以注意到 登錄狀態是由cookies保留,退出站點A的時候肯定不能清除站點B下的cookies,其實在IdentityServer3中給我們提供了一個logoutcallback這樣一個地址用戶清楚其他站點的cookies或者session, identityserver4中一樣的,需要注意的是使用Post方式請求,防止陪惡意Get請求,下面是IdentityServer3中的處理方式
[AllowAnonymous] public void LogOutCallBack(string sid) { var cp = User as ClaimsPrincipal; var claimsid = cp.FindFirst("sid"); if (claimsid != null && claimsid.Value == sid) { HttpContext.GetOwinContext().Authentication.SignOut("Cookies"); } }
在identiyserver3中調用SignOut后服務器端會根據client客戶端列表去請求回調地址清楚cookies
但是Identityserver4中怎么處理呢?官方demo好像是退出了就直接到logedOut頁面,然而貌似沒有,連轉到的ClientPostLogoutRedirectUris貌似都沒用了,所以還是自己跳吧,只需要處理清除其他站點的cookies就行了,保證統一退出
