IdentityServer4受權和認證

IdentityServer4 簡稱ids4html

oidc瞭解:http://www.jessetalk.cn/2018/04/04/oidc-asp-net-core/git

是一個去中心化的網上身份認證系統,集成了認證和受權github

博客園已經有不少大佬寫過了。我也是跟着學,記錄下學習成果服務器

受權服務器代碼:微信

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 中的cookie

IdentityServerConstants.StandardScopes.OpenId,
                        IdentityServerConstants.StandardScopes.Profile必須的網絡

也能夠不用枚舉類型。直接寫:「openid」,"profile"app

 

爲何說是必須定義的呢。由於ids4代碼的封裝。默認就添加了「openid」,"profile"兩個scopeide

由於只有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);
                    }
                };
            });
View Code

 

配置其實跟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裏拿的。這裏有兩個區別:

  1. userinfo endpoint是屬於認證服務器實現的,並不是資源服務器,有歸屬的區別
  2. 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;
View Code

 

當用戶沒有受權,跳轉到受權服務器的登錄地址,贊成受權地址,都是默認值

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

相關文章
相關標籤/搜索