IdentityServer4 簡稱ids4
oidc了解:http://www.jessetalk.cn/2018/04/04/oidc-asp-net-core/
是一個去中心化的網上身份認證系統,集成了認證和授權
博客園已經有很多大佬寫過了。我也是跟着學,記錄下學習成果
授權服務器代碼:
var oidc = new Client { ClientId = "oidc", ClientName = "name", ClientSecrets = { new Secret("secret".Sha256()) }, ClientUri = "http://www.cnblogs.com", //客戶端 LogoUri = "https://www.cnblogs.com/images/logo_small.gif", //AllowedGrantTypes={GrantType.AuthorizationCode } /* 如果客戶端使用的認證是 */ AllowedGrantTypes = GrantTypes.Hybrid, AllowedScopes ={ IdentityServerConstants.StandardScopes.OpenId, IdentityServerConstants.StandardScopes.Profile, IdentityServerConstants.StandardScopes.Email, }, RedirectUris = { "http://localhost:5001/signin-oidc" }, PostLogoutRedirectUris = { "http://localhost:5001/signout-callback-oidc" } };
AllowedScopes 中的
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile必須的
也可以不用枚舉類型。直接寫:“openid”,"profile"
為什么說是必須定義的呢。因為ids4代碼的封裝。默認就添加了“openid”,"profile"兩個scope
因為只有openid才能確定唯一性
而profile是用戶資料信息
github地址:
https://github.com/aspnet/AspNetCore/blob/master/src/Security/Authentication/OpenIdConnect/src/OpenIdConnectOptions.cs
可以看到其他的默認配置,比如回調地址,登出地址
如果之前了解過授權和認證,對這個不陌生
//使用ids中間件
app.UseIdentityServer();
認證代碼,我自己寫了挺多注釋,可以忽略

services.AddAuthentication(options => { /* 要想使用認證系統,必要先注冊Scheme 而每一個Scheme必須指定一個Handler AuthenticationHandler 負責對用戶憑證的驗證 這里指定的默認認證是cookie認證 Scheme可以翻譯為方案,即默認的認證方案 因為這里用到了多個中間件,(AddAuthentication,AddCookie,AddOpenIdConnect) OpenIdConnectDefaults.DisplayName 的默認值是oidc 指定AddOpenIdConnect是默認中間件,在AddOpenIdConnect配置了很多選項 如果只用了一個中間件,則可以不寫,是否還記得cookie認證 // services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme) // .AddCookie(option => // { // ///Account/Login?ReturnUrl=%2Fadmin // option.LoginPath = "/login/index"; // //option.ReturnUrlParameter = "params"; //指定參數名稱 // //option.Cookie.Domain // option.AccessDeniedPath = "/login/noAccess"; // option.Cookie.Expiration = TimeSpan.FromSeconds(4); // option.Events = new CookieAuthenticationEvents // { // OnValidatePrincipal = LastChangedValidator.ValidateAsync // }; // }); */ //options.DefaultScheme = "Cookies"; //默認的認證方案:cookie認證,信息是保存在cookie中的 options.DefaultAuthenticateScheme = "Cookies"; //oidc 就是openidConnect //名字隨便取,只要AddOpenIdConnect中的的oidc名字一樣即可, //這樣才能找到 options.DefaultChallengeScheme = "oidc"; //默認使用oidc中間件 //options.DefaultChallengeScheme = OpenIdConnectDefaults.DisplayName; }).AddCookie("Cookies") .AddOpenIdConnect("oidc", options => { options.SignInScheme = "Cookies"; options.Authority = "http://localhost:5003"; options.RequireHttpsMetadata = false; options.ClientId = "oidc"; options.ClientSecret = "secret"; options.SaveTokens = true; //options.Scope.Add("openid"); /* 默認值是:id_token */ //options.ResponseType = OpenIdConnectResponseType.CodeIdToken; options.Events = new OpenIdConnectEvents { /* 遠程異常觸發 在授權服務器取消登陸或者取消授權 */ OnRemoteFailure = OAuthFailureHandler => { //跳轉首頁 OAuthFailureHandler.Response.Redirect("/"); OAuthFailureHandler.HandleResponse(); return Task.FromResult(0); } }; });
配置其實跟OAuth2認證差不多,運行是沒有問題的
我這里主要講解ids4的授權和認證類型ResponseType
默認是 id_token ,源碼是個好東西,我們看看
客戶端端id_token對應服務端,會返回id_token
AllowedGrantTypes = GrantTypes.Implicit, 隱式模式
它返回id_token信息,包含了用戶信息的SubjectId,是TestUser配置的
參考:https://www.cnblogs.com/jesse2013/p/oidc-in-aspnetcore-with-identity-server.html
客戶端端code id_token對應服務端,會返回id_token和access_token
AllowedGrantTypes = GrantTypes.Hybrid, 混合模式
可以用access_token 去userinfo endpoint獲取用戶信息
access toke管的是權限,里面保存的是一些認證信息
,id token是身份信息
http://localhost:5003/.well-known/openid-configuration
可以查看userinfo endpoint配置
有人可能會注意到,在這里我們拿到的idtoken沒有派上用場,我們的用戶資料還是通過access_token從userinfo endpoint里拿的。這里有兩個區別:
- userinfo endpoint是屬於認證服務器實現的,並非資源服務器,有歸屬的區別
- id_token 是一個jwt,里面帶有用戶的唯一標識,我們在判斷該用戶已經存在的時候不需要再請求userinfo endpoint
下圖是對id_token進行解析得到的信息:sub即subject_id(用戶唯一標識 )
看網上很多例子都在Controller上打個Authorize標簽
當未授權就跳轉到授權服務器,這樣,這個網站那就必須使用授權服務器才能登陸
比如:我這個網站可以有自己的密碼登陸,也可以用第三方登陸。所以在沒有授權的時候是跳轉到登陸頁面,
讓用戶自己選擇是密碼登陸還是第三方授權登陸
如果是這樣,我沒有授權登陸。只有訪問這個Admin頁面就會跳轉到授權服務器,
那如果我們添加多個第三方認證,比如QQ,微博,微信等等,那起步亂套了
顯然這不是我想要的,應該像簡書這樣,集成第三方登陸
所以我們可以設置使用那個中間件options.DefaultChallengeScheme=“myCookies”
當沒有登陸的是,會走AddCookie,跳轉到到登陸頁面
比如我們這里注入了oidc授權,google授權
services.AddAuthentication(options => { //默認的認證方案:cookie認證,信息是保存在cookie中的 options.DefaultAuthenticateScheme = "Cookies"; options.DefaultChallengeScheme = "myCookies"; }).AddCookie("myCookies",options=> { options.LoginPath = "/Account/Login"; }) .AddGoogle("googole", options => { }) .AddOpenIdConnect("oidc", options => { }
當用戶單擊,使用微博登陸則:通過Challenge方法指定使用那個schemes
這樣就會跳轉到登陸頁面,用戶自己選擇了
可以用User.Identity.IsAuthenticated判斷是否驗證授權
沒有則手動觸發: Challenge("oidc")
oidc 為你想使用的第三方
比如:我設置了,cookie,微博,QQ,google,oidc等等
.AddCookie("cookie")
.AddGoogole("google")
.AddQQ("qq")
當你想用google授權,則Challenge(”google")
這樣做的好處是:我網站只是接入別第三方登陸。至於使用第三方登陸還是使用我網站注冊用戶登陸
都是由用戶選擇
網絡收集,沒有一一驗證:

/***********************************相關事件***********************************/ // 未授權時,重定向到OIDC服務器時觸發 //o.Events.OnRedirectToIdentityProvider = context => Task.CompletedTask; // 獲取到授權碼時觸發 //o.Events.OnAuthorizationCodeReceived = context => Task.CompletedTask; // 接收到OIDC服務器返回的認證信息(包含Code, ID Token等)時觸發 //o.Events.OnMessageReceived = context => Task.CompletedTask; // 接收到TokenEndpoint返回的信息時觸發 //o.Events.OnTokenResponseReceived = context => Task.CompletedTask; // 驗證Token時觸發 //o.Events.OnTokenValidated = context => Task.CompletedTask; // 接收到UserInfoEndpoint返回的信息時觸發 //o.Events.OnUserInformationReceived = context => Task.CompletedTask; // 出現異常時觸發 //o.Events.OnAuthenticationFailed = context => Task.CompletedTask; // 退出時,重定向到OIDC服務器時觸發 //o.Events.OnRedirectToIdentityProviderForSignOut = context => Task.CompletedTask; // OIDC服務器退出后,服務端回調時觸發 //o.Events.OnRemoteSignOut = context => Task.CompletedTask; // OIDC服務器退出后,客戶端重定向時觸發 //o.Events.OnSignedOutCallbackRedirect = context => Task.CompletedTask;
當用戶沒有授權,跳轉到授權服務器的登陸地址,同意授權地址,都是默認值
https://github.com/IdentityServer/IdentityServer4/blob/63a50d7838af25896fbf836ea4e4f37b5e179cd8/src/Constants.cs
我們可以修改自己想要的地址
然后添加Route
這樣就成功了
大佬文章:
https://www.cnblogs.com/jesse2013/p/oidc-in-aspnetcore-with-identity-server.html
https://www.cnblogs.com/RainingNight/p/7635534.html
https://www.cnblogs.com/xishuai/p/6274036.html
https://www.cnblogs.com/cgzl/p/9253667.html
https://cloud.tencent.com/developer/article/1048128
https://www.cnblogs.com/stulzq/p/7879101.html