IdentityServer4專題之七:Authorization Code認證模式


(1)identityserver4授權服務器端

public static class Config

    {

       public static IEnumerable<IdentityResource> GetIdentityResources()

        {

            return new IdentityResource[]

            {

                new IdentityResources.OpenId(),

                new IdentityResources.Profile(),

                new IdentityResources.Email(),

                new IdentityResources.Phone(),

                new IdentityResources.Address(),

            };

        }

        public static IEnumerable<ApiResource> GetApis()

        {

            return new ApiResource[]

            {

                new ApiResource("api1", "My API #1")

            };

        }

        public static IEnumerable<Client> GetClients()

        {

            return new[]

            {              

                new Client

                {

                    ClientId="mvc client",

                    ClientName="ASP.NET Core MVC Client",

                    AllowedGrantTypes=GrantTypes.CodeAndClientCredentials,

                    ClientSecrets={new Secret( "mvc secret".Sha256())},

                    RedirectUris={"http://localhost:5002/signin-oidc"},

                    FrontChannelLogoutUri="http://localhost:5002/signout-oidc",

                    PostLogoutRedirectUris={"http://localhost:5002/signout-callback-oidc"},

                    AlwaysIncludeUserClaimsInIdToken=true,//將用戶所有的claims包含在IdToken內

                    AllowOfflineAccess=true,//offline_access,其實指的是能否用refreshtoken重新申請令牌

                    AllowedScopes =

                    {

                        "api1",

                        IdentityServerConstants.StandardScopes.OpenId,

                        IdentityServerConstants.StandardScopes.Profile,

                        IdentityServerConstants.StandardScopes.Address,

                        IdentityServerConstants.StandardScopes.Phone,

                        IdentityServerConstants.StandardScopes.Email

                    }

                }             

            };

        }

   }

 

(2)客戶端,還是需要安裝IdentityModel庫,

startup.csConfigurServices一節,需要做如下添加

//關閉默認映射,否則它可能修改從授權服務返回的各種claim屬性

JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();    

//添加認證服務,並設置其有關選項

       services.AddAuthentication(options =>

            {

//客戶端應用設置使用"Cookies"進行認證

                options.DefaultScheme =CookieAuthenticationDefaults.AuthenticationScheme ;   

//identityserver4設置使用"oidc"進行認證

             options.DefaultChallengeScheme =OpenIdConnectDefaults.AuthenticationScheme ;

            }).AddCookie(CookieAuthenticationDefaults.AuthenticationScheme)

//對使用的OpenIdConnect進行設置,此設置與Identityserver的config.cs中相應client配置一致才可能登錄授權成功

            .AddOpenIdConnect(OpenIdConnectDefaults.AuthenticationScheme, options=> {

                options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;

                options.Authority = "http://localhost:5000";

                options.RequireHttpsMetadata = false;

                options.ClientId = "mvc client";

                options.ClientSecret = "mvc secret";

                options.SaveTokens = true;

                options.ResponseType = "code";

 

                options.Scope.Clear();

                options.Scope.Add("api1");

                options.Scope.Add(OidcConstants.StandardScopes.OpenId);//"openid"

                options.Scope.Add(OidcConstants.StandardScopes.Profile);//"profile"

                options.Scope.Add(OidcConstants.StandardScopes.Address);

                options.Scope.Add(OidcConstants.StandardScopes.Email);

                options.Scope.Add(OidcConstants.StandardScopes.Phone);

// 與identity server的AllowOfflineAccess=true,對應。offline_access,指的是能否用refreshtoken重新申請令牌

                options.Scope.Add(OidcConstants.StandardScopes.OfflineAccess);               

            });

Confiure一節,app.UseMvc之前添加如下內容:

app.UseAuthentication();

然后,在controller中使用時,按如下方式:    通常需如下引用

using System;

using System.Collections.Generic;

using System.Diagnostics;

using System.Linq;

using System.Net.Http;

using System.Threading.Tasks;

using IdentityModel.Client;

using Microsoft.AspNetCore.Authentication;

using Microsoft.AspNetCore.Authentication.Cookies;

using Microsoft.AspNetCore.Authentication.OpenIdConnect;

using Microsoft.AspNetCore.Authorization;

using Microsoft.AspNetCore.Mvc;

using Microsoft.IdentityModel.Protocols.OpenIdConnect;

using MvcClient.Models;

 

//獲取AccessToken、IdToken、RefreshToken時:

[Authorize]

        public async Task<IActionResult> Privacy()

        {

            var accessToken = await HttpContext.GetTokenAsync(OpenIdConnectParameterNames.AccessToken);

            var idToken = await HttpContext.GetTokenAsync(OpenIdConnectParameterNames.IdToken);

            var refreshToken = await HttpContext.GetTokenAsync(OpenIdConnectParameterNames.RefreshToken);

            var authorizationCode = await HttpContext.GetTokenAsync(OpenIdConnectParameterNames.Code);

            ViewData["idToken"] = idToken;

            ViewData["refreshToken"] = refreshToken;

            ViewData["accessToken"] = accessToken; 

            return View();

        }

 

//訪問Api資源時

public async Task<IActionResult> AccessApi()

        {

            var client = new HttpClient();

            var disco = await client.GetDiscoveryDocumentAsync("http://localhost:5000");

            ViewData["disco"] = disco.Error;

            if (disco.IsError)

            {

                ViewData["disco"] = disco.Error;

                return View();

            }

            var accessToken = await HttpContext.GetTokenAsync(OpenIdConnectParameterNames.AccessToken);

            client.SetBearerToken(accessToken);

            var response = await client.GetAsync("http://localhost:5001/api/values");

            if (!response.IsSuccessStatusCode)

            {

                ViewData["response_error"] = response.StatusCode;

                return View();

            }

            ViewData["response-content"] = await response.Content.ReadAsStringAsync();

            return View();

        }

 

 

       從客戶端及identityserver4登出時:

        public async Task<IActionResult> Logout()

        {

            await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);

            await HttpContext.SignOutAsync(OpenIdConnectDefaults.AuthenticationScheme);

            return View();

        }

如果登出需要跳轉回到客戶端應用網站,則需在將IdentityServer4的命名空間IdentityServer4.Quickstart.UI下的AccountOptions類中

public static bool AutomaticRedirectAfterSignOut = true; 

這樣,從identityserver登出后,將自動跳轉到客戶應用頁面。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM