Envoy实现.NET架构的网关(四)集成IdentityServer4实现OAuth2认证
.NET網關與Gateway實戰-Envoy與kong課程
什么是OAuth2認證
簡單說,OAuth 就是一種授權機制。數據的所有者告訴系統,同意授權第三方應用進入系統,獲取這些數據。系統從而產生一個短期的進入令牌(token),用來代替密碼,供第三方應用使用。
而IdentityServer4就是一個開源的OAuth2認證系統。網關與IdentityServer4集成之后,我們可以避免為內部的每個微服務集成IdentityServer4,可以避免很多重復的工作,而這也是網關的一個重要優勢。
新建IdentityServer4服務
1新增WebApi,并引用Nuget包IdentityServer4
2.新增校驗證書,其中的證書文件通過openssl創建
? ? ?2.1安裝生成證書程序:https://slproweb.com/products/Win32OpenSSL.html(對應操作系統)
? ? ?2.2找到openssl安裝位置生成證書,Country Name (2 letter code) [AU]:跳過所有步驟
openssl?req?-newkey?rsa:2048?-nodes?-keyout?chester.key?-x509?-days?365?-out?chester.ceropenssl?pkcs12?-export?-in?chester.cer?-inkey?chester.key?-out?chester.pfx3.新增配置信息
public class Config{public static IEnumerable<ApiResource> GetApiResources(){return new List<ApiResource>{new ApiResource("api1", "我的第一個API"){UserClaims ={JwtClaimTypes.Audience},Scopes = new List<string>{"api"},}};}public static IEnumerable<Client> GetClients(){return new List<Client>{new Client{ClientId="client",//定義客戶端IDClientSecrets={new Secret("secret".Sha256())//定義客戶端秘鑰},AllowedGrantTypes = GrantTypes.ResourceOwnerPassword,//授權方式為用戶密碼模式授權,類型可參考GrantTypes枚舉AllowedScopes={ "api" }//允許客戶端訪問的范圍}};}public static IEnumerable<ApiScope> ApiScopes =>new ApiScope[] { new ApiScope("api") };public static IEnumerable<IdentityResource> GetIdentityResources(){return new IdentityResource[]{new IdentityResources.OpenId()};}}4.注入IdentityServer4
public void ConfigureServices(IServiceCollection services){services.AddIdentityServer()//注冊服務//.AddDeveloperSigningCredential().AddSigningCredential(new X509Certificate2("chester.pfx","123456") ).AddInMemoryApiResources(Config.GetApiResources())//配置類定義的授權范圍.AddInMemoryClients(Config.GetClients())//配置類定義的授權客戶端.AddInMemoryApiScopes(Config.ApiScopes).AddTestUsers(new List<TestUser> { new TestUser { Username = "Admin", Password = "123456", SubjectId = "001", IsActive = true } });//模擬測試用戶,這里偷懶了,用戶可以單獨管理,最好不要直接在這里Newservices.AddControllers();}5.開啟IdentityServer4中間件
app.UseIdentityServer();//添加中間件6.然后啟動IdentityServer4服務
配置Envoy
我們需要用到Envoy的envoy.filters.http.jwt_authn,需要注意的有以下幾點
Envoy的過濾器加載是自上而下的,因此我們需要將此過濾器放到envoy.filters.http.router前
另外我們需要在配置文件中配置jwt的jwks地址/.well-known/openid-configuration/jwks,jwks是JSON Web密鑰集—一種用于共享公鑰的JSON表示法,用于驗證JWT簽名
并且我們需要配置ids4服務的cluster。
具體配置如下,需要注意的地方已標紅
admin:address:socket_address:protocol: TCPaddress: 0.0.0.0port_value: 9902 static_resources:listeners:- name: listener_0address:socket_address:protocol: TCPaddress: 0.0.0.0port_value: 10000filter_chains:- filters:- name: envoy.filters.network.http_connection_managertyped_config:"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManagerscheme_header_transformation:scheme_to_overwrite: httpstat_prefix: ingress_httproute_config:name: local_routevirtual_hosts:- name: local_servicedomains: ["*"]routes:- match:prefix: "/"route:host_rewrite_literal: 192.168.43.94cluster: service_envoyproxy_iohttp_filters:- name: envoy.filters.http.jwt_authntyped_config:"@type": type.googleapis.com/envoy.extensions.filters.http.jwt_authn.v3.JwtAuthenticationproviders:jwt_provider:issuer: "http://192.168.43.94:7000"audiences:- "api1"forward: trueremote_jwks:http_uri:uri: "http://192.168.43.94:7000/.well-known/openid-configuration/jwks"cluster: jwtservertimeout: 5srules:- match:prefix: "/"requires:provider_name: jwt_provider- name: envoy.filters.http.routerclusters:- name: jwtserverconnect_timeout: 0.25stype: STRICT_DNSlb_policy: ROUND_ROBINload_assignment:cluster_name: jwtserverendpoints:- lb_endpoints:- endpoint:address:socket_address:address: 192.168.43.94port_value: 7000- name: service_envoyproxy_ioconnect_timeout: 30stype: strict_dns# Comment out the following line to test on v6 networksdns_lookup_family: V4_ONLYlb_policy: ROUND_ROBINload_assignment:cluster_name: service_envoyproxy_ioendpoints:- lb_endpoints:- endpoint:address:socket_address:address: 192.168.43.94port_value: 5000啟動envoy
docker?run?--rm?-it?-p?9902:9902?-p?10000:10000?-v?D:/gateway/envoy/config/static/:/etc/envoy/?-v?D:/gateway/envoy/logs:/logs?envoyproxy/envoy-dev??-c?/etc/envoy/envoy-jwt.yaml驗證jwt
我們直接訪問http://192.168.43.94:10000/Name,不攜帶token,可以看到請求被拒絕,返回401
?下面我們調用ids4的/connect/token接口獲取token
將獲取到的token放到Name接口的Header里,再次調用成功!!!
至此,我們通過Envoy+IdentityServer4實現了網關的JWT認證,可以節省內部微服務與IdentityServer4重復的集成工作,實現了統一處理認證邏輯。
總結
以上是生活随笔為你收集整理的Envoy实现.NET架构的网关(四)集成IdentityServer4实现OAuth2认证的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 基于事件驱动架构构建微服务第9部分:处理
- 下一篇: 浅谈.Net异步编程的前世今生----异