.Net Core微服務化ABP之五(續)——IdentityServer4權限服務(續 整合Ocelot)

上一篇介紹了在不整合Consul的狀況下,如何使用identity server。在實際應用環境中,內部服務通常是不對外暴露的,因此如今咱們把consul考慮進來,稍做修改就能夠了。html

環境介紹,咱們有一個OrderService和PartnerService,其中的/api/default是授權限保護的,還有一個ocelot網關和identity server4的權限服務。web

能夠參照以前的文章先把權限服務集成到consul。json

大體流程是:首先在網關注冊認證服務,修改認證服務資源,在api服務中集成認證api

API網關注冊認證服務

修改Startup架構

 // IdentityServer
            #region IdentityServerAuthenticationOptions => need to refactor
            Action<IdentityServerAuthenticationOptions> isaOptClient = option =>
            {
                option.Authority = Configuration["IdentityService:Uri"];
                option.ApiName = "serviceorder";
                option.RequireHttpsMetadata = Convert.ToBoolean(Configuration["IdentityService:UseHttps"]);
                option.SupportedTokens = SupportedTokens.Both;
                option.ApiSecret = Configuration["IdentityService:ApiSecrets:orderservice"];
            };

            Action<IdentityServerAuthenticationOptions> isaOptProduct = option =>
            {
                option.Authority = Configuration["IdentityService:Uri"];
                option.ApiName = "servicepartner";
                option.RequireHttpsMetadata = Convert.ToBoolean(Configuration["IdentityService:UseHttps"]);
                option.SupportedTokens = SupportedTokens.Both;
                option.ApiSecret = Configuration["IdentityService:ApiSecrets:partnerservice"];
            };
            #endregion

            services.AddAuthentication()
                .AddIdentityServerAuthentication("PartnerServiceKey", isaOptProduct)
                .AddIdentityServerAuthentication("OrderServiceKey", isaOptClient);

配置文件以下mvc

{
  "Swagger": {
    "DocName": "ZJ.ApiGateway",
    "Version": "v1",
    "Title": "API Gateway Service",
    "ServiceDocNames": "serviceorder,servicepartner,serviceauthorize" // Swagger doc name list
  },
  "Logging": {
    "LogLevel": {
      "Default": "Warning"
    }
  },
  "IdentityService": {
    "Uri": "http://192.168.8.157:5100",
    "UseHttps": false,
    "ApiSecrets": {
      "orderservice": "ordersecret",
      "partnerservice": "partnersecret"
    }
  },
  "AllowedHosts": "*"
}

 修改ocelotsettings.json,給權限服務加上路由,若是須要swagger,也加上app

// API:Service.Authorize
    // --> swagger part
    {
      "DownstreamPathTemplate": "/doc/serviceauthorize-gateway/swagger.json",
      "DownstreamScheme": "http",
      "ServiceName": "Service.Authorize",
      "LoadBalancer": "RoundRobin",
      "UseServiceDiscovery": true,
      "UpstreamPathTemplate": "/doc/serviceauthorize/swagger.json",
      "UpstreamHttpMethod": [ "GET", "POST", "DELETE", "PUT" ]
    },
    {
      "UseServiceDiscovery": true, // use Consul service discovery
      "DownstreamPathTemplate": "/{url}",
      "DownstreamScheme": "http",
      "ServiceName": "Service.Authorize",
      "LoadBalancerOptions": {
        "Type": "RoundRobin"
      },
      "UpstreamPathTemplate": "/api/Serviceauthorize/{url}",
      "UpstreamHttpMethod": [ "Get", "Post" ],
      "ReRoutesCaseSensitive": false, // non case sensitive
      "QoSOptions": {
        "ExceptionsAllowedBeforeBreaking": 2, // 容許多少個異常請求
        "DurationOfBreak": 5000, // 熔斷的時間,單位爲毫秒
        "TimeoutValue": 3000 // 若是下游請求的處理時間超過多少則視如該請求超時
      }
    }

 

修改權限服務

修改IdentityServerConfig類ide

public static class IdentityServerConfig
    {
        /// <summary>
        /// 容許使用認證服務的api列表
        /// </summary>
        /// <returns></returns>
        public static IEnumerable<ApiResource> GetApiResources()
        {
            return new List<ApiResource>
            {
                new ApiResource("serviceorder", "Default (all) API"),
                new ApiResource("servicepartner", "Default (all) API1"),
            };
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public static IEnumerable<IdentityResource> GetIdentityResources()
        {
            return new List<IdentityResource>
            {
                new IdentityResources.OpenId(),
                new IdentityResources.Profile(),
                new IdentityResources.Email(),
                new IdentityResources.Phone()
            };
        }

        /// <summary>
        /// 容許使用認證服務的應用客戶端
        /// </summary>
        /// <returns></returns>
        public static IEnumerable<Client> GetClients(IConfiguration Configuration)
        {
            return new List<Client>
            {
                new Client
                {
                    ClientId = "default_web_client",
                    ClientName="default_name",
                    AllowedGrantTypes = GrantTypes.ResourceOwnerPassword,
                    AllowedScopes =
                    {
                        "serviceorder",
                        "servicepartner",
                    },
                    ClientSecrets = new[]{ new Secret("secret1".Sha256())}
                },
                new Client
                {
                    ClientId = "default_app_client",
                    ClientName="default_name11",
                    AllowedGrantTypes = GrantTypes.ResourceOwnerPassword,
                    AllowedScopes =
                    {
                        "serviceorder",
                    },
                    ClientSecrets = new[]{ new Secret("secret2".Sha256())}
                },
                new Client
                {
                    ClientId = "default_mvc_client",
                    ClientName="default_name111",
                    AllowedGrantTypes = GrantTypes.Implicit,
                    RedirectUris = { Configuration["Clients:MvcClient:RedirectUri"] },
                    AllowedScopes =
                    {
                        "serviceorder",
                    },
                    ClientSecrets = new[]{ new Secret("secret3".Sha256())}
                }
            };
        }

    }

注意這裏的Clients,這麼設定的目的是當使用default_web_client時能夠訪問servicePartner以及serviceOrder,當使用default_app_client時只能訪問serviceorder微服務

 

修改api服務

修改ConfigureServices測試

 // identity server
            services.AddMvcCore().AddAuthorization().AddJsonFormatters();
            services.AddAuthentication(_appConfiguration["IdentityService:DefaultScheme"]).AddIdentityServerAuthentication(_appConfiguration["IdentityService:DefaultScheme"], options =>
            {
                options.Authority = _appConfiguration["IdentityService:Uri"];
                options.RequireHttpsMetadata = false;
                options.ApiName = "serviceorder"; // match with configuration in IdentityServer
            });

配置文件以下,注意defaultScheme必須和網關中配置的AddIdentityServerAuthentication一致

  "IdentityService": {
    "Uri": "http://192.168.8.157:5100",
    "DefaultScheme": "OrderServiceKey",
    "UseHttps": false,
    "ApiSecret": "clientsecret"
  }

發佈到iis開始測試,個人測試環境中order服務端口是5000,partner服務端口是5001,認證服務端口5100,api網關端口5555

首先請求token,地址填寫api網關地址,client_id、client_secret和權限服務中設置的一致,其餘按下圖填寫

 

 成功請求到token,按照咱們在權限服務中的配置,這個token是屬於default_web_client的,那麼它能夠用在serviceorder和servicepartner這兩個api中

請求serviceorder,能夠正常得到結果,注意在Auth選項卡中選擇Bearer Token並填寫剛纔取得的access_token

請求servicepartner,也能夠正常返回結果

如今咱們換一個clientId,換成default_app_client,理論上它只能請求serviceorder,而不能請求servicepartner

能夠看到請求servicepartner時返回了401 Unauthorized,測試經過。

隱藏client_secret

 上述方式有一個較大的問題,那就是client_id對應的client_secret會暴露在客戶端的請求體中。既然驗證請求要通過api網關,那能夠考慮在api網關作一次人工轉發,在請求體中加上這個client_secret,具體能夠看參考文章,此處再也不展開。

總結

到這一步,微服務架構已經基本成型,consul做爲服務中心統籌管理全部的api服務,獨立的權限服務經過consul提供權限驗證、用戶註冊、註銷等功能。下一步須要重構代碼,從新梳理項目結構,整理完成後接入CAP就基本能夠開始開發。

 

參考文章:

https://www.cnblogs.com/edisonchou/p/integration_authentication-authorization_service_foundation.html

相關文章
相關標籤/搜索