免费网站应用,登录腾讯邮箱企业邮箱入口,包装设计灵感网站,做黑彩票的网站赚钱吗关于IdentityServer4与ocelot博客园里已经有很多介绍我这里就不再重复了。ocelot与IdentityServer4组合认证博客园里也有很多#xff0c;但大多使用ocelot内置的认证#xff0c;而且大多都是用来认证API的#xff0c;查找了很多资料也没看到如何认证oidc#xff0c;所以这里… 关于IdentityServer4与ocelot博客园里已经有很多介绍我这里就不再重复了。ocelot与IdentityServer4组合认证博客园里也有很多但大多使用ocelot内置的认证而且大多都是用来认证API的查找了很多资料也没看到如何认证oidc所以这里的ocelot实际只是作为统一入口而不参与认证认证的完成依然在客户端。代码是使用IdentityServer4的Quickstart5_HybridAndApi 示例修改的。项目结构如下 一 ocelot网关我们先在示例添加一个网关。修改launchSettings.json中的端口为54660配置文件如下{ ReRoutes: [ { // MvcClient DownstreamPathTemplate: /MvcClient/{route}, DownstreamScheme: http, DownstreamHostAndPorts: [ { Host: localhost, Port: 50891 } ], UpstreamPathTemplate: /MvcClient/{route}, UpstreamHeaderTransform: { X-Forwarded-For: {RemoteIpAddress} } }, { // signin-oidc DownstreamPathTemplate: /signin-oidc, DownstreamScheme: http, DownstreamHostAndPorts: [ { Host: localhost, Port: 50891 } ], UpstreamPathTemplate: /signin-oidc, UpstreamHeaderTransform: { X-Forwarded-For: {RemoteIpAddress} } }, { // signout-callback-oidc DownstreamPathTemplate: /signout-callback-oidc, DownstreamScheme: http, DownstreamHostAndPorts: [ { Host: localhost, Port: 50891 } ], UpstreamPathTemplate: /signout-callback-oidc, UpstreamHeaderTransform: { X-Forwarded-For: {RemoteIpAddress} } }, { // MyApi DownstreamPathTemplate: /MyApi/{route}, DownstreamScheme: http, DownstreamHostAndPorts: [ { Host: localhost, Port: 50890 } ], UpstreamPathTemplate: /MyApi/{route}, UpstreamHeaderTransform: { X-Forwarded-For: {RemoteIpAddress} } }, { // IdentityServer DownstreamPathTemplate: /{route}, DownstreamScheme: http, DownstreamHostAndPorts: [ { Host: localhost, Port: 50875 } ], UpstreamPathTemplate: /IdentityServer/{route}, UpstreamHeaderTransform: { X-Forwarded-For: {RemoteIpAddress} } }, { // IdentityServer DownstreamPathTemplate: /{route}, DownstreamScheme: http, DownstreamHostAndPorts: [ { Host: localhost, Port: 50875 } ], UpstreamPathTemplate: /{route}, UpstreamHeaderTransform: { X-Forwarded-For: {RemoteIpAddress} } } ]}这里我们定义3个下游服务MvcClientMyApiIdentityServer并使用路由特性把signin-oidcsignout-callback-oidc导航到MvcClient由MvcClient负责生成最后的Cooike。并将默认路由指定到IdentityServer服务。在ConfigureServices中添加Ocelot服务。services.AddOcelot() .AddCacheManager(x { x.WithDictionaryHandle(); }) .AddPolly()在Configure中使用Ocelot中间件app.UseOcelot().Wait();Ocelot网关就部署完成了。二 修改QuickstartIdentityServer配置首先依然是修改launchSettings.json中的端口为50875在ConfigureServices中修改AddIdentityServer配置中的PublicOrigin和IssuerUri的Url为http://localhost:54660/IdentityServer/services.AddIdentityServer(Option { Option.PublicOrigin http://localhost:54660/IdentityServer/; Option.IssuerUri http://localhost:54660/IdentityServer/; }) .AddDeveloperSigningCredential() .AddInMemoryIdentityResources(Config.GetIdentityResources()) .AddInMemoryApiResources(Config.GetApiResources()) .AddInMemoryClients(Config.GetClients()) .AddTestUsers(Config.GetUsers());这样一来发现文档中的IdentityServer地址就变为网关的地址了进一步实现IdentityServer的负载均衡也是没有问题的。修改Config.cs中mvc客户端配置如下ClientId mvc, ClientName MVC Client, AllowedGrantTypes GrantTypes.HybridAndClientCredentials, ClientSecrets { new Secret(secret.Sha256()) }, // AccessTokenType AccessTokenType.Reference, RequireConsent true, RedirectUris { http://localhost:54660/signin-oidc }, PostLogoutRedirectUris { http://localhost:54660/signout-callback-oidc }, AllowedScopes { IdentityServerConstants.StandardScopes.OpenId, IdentityServerConstants.StandardScopes.Profile, api1 }, AllowOfflineAccess true, //直接返回客户端需要的Claims AlwaysIncludeUserClaimsInIdToken true,主要修改RedirectUris和PostLogoutRedirectUris为网关地址在网关也设置了signin-oidc和signout-callback-oidc转发请求到Mvc客户端。三 修改MvcClient修改MvcClient的launchSettings.json端口为50891。修改MvcClient的Authority地址为http://localhost:54660/IdentityServer和默认路由地址MvcClient/{controllerHome}/{actionindex}/{id?}JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear(); services.AddAuthentication(options { options.DefaultScheme Cookies; options.DefaultChallengeScheme oidc; //options.DefaultSignInScheme CookieAuthenticationDefaults.AuthenticationScheme; }) .AddCookie(Cookies,options { options.ExpireTimeSpan TimeSpan.FromMinutes(30); options.SlidingExpiration true; }) .AddOpenIdConnect(oidc, options { options.SignInScheme Cookies; options.Authority http://localhost:54660/IdentityServer; options.RequireHttpsMetadata false; options.ClientId mvc; options.ClientSecret secret; options.ResponseType code id_token; options.SaveTokens true; options.GetClaimsFromUserInfoEndpoint true; options.Scope.Add(api1); options.Scope.Add(offline_access); });app.UseMvc(routes { routes.MapRoute( name: default, template: MvcClient/{controllerHome}/{actionindex}/{id?}); });修改HomeController将相关地址修改为网关地址public async TaskIActionResult CallApiUsingClientCredentials() { var tokenClient new TokenClient(http://localhost:54660/IdentityServer/connect/token, mvc, secret); var tokenResponse await tokenClient.RequestClientCredentialsAsync(api1); var client new HttpClient(); client.SetBearerToken(tokenResponse.AccessToken); var content await client.GetStringAsync(http://localhost:54660/MyApi/identity); ViewBag.Json JArray.Parse(content).ToString(); return View(json); } public async TaskIActionResult CallApiUsingUserAccessToken() { var accessToken await HttpContext.GetTokenAsync(access_token); //OpenIdConnectParameterNames var client new HttpClient(); client.SetBearerToken(accessToken); var content await client.GetStringAsync(http://localhost:54660/MyApi/identity); ViewBag.Json JArray.Parse(content).ToString(); return View(json); }四 修改Api项目Api项目修改多一点。将MvcClient的HomeController和相关视图复制过来模拟MVC与API同时存在的项目。修改Api的launchSettings.json端口为50890。修改Startuppublic class Startup { public void ConfigureServices(IServiceCollection services) { services.AddDataProtection(options options.ApplicationDiscriminator 00000).SetApplicationName(00000); services.AddMvc(); JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear(); services.AddAuthentication(options { options.DefaultScheme Cookies; options.DefaultChallengeScheme oidc; }).AddCookie(Cookies) .AddOpenIdConnect(oidc, options { options.SignInScheme Cookies; options.Authority http://localhost:54660/IdentityServer; options.RequireHttpsMetadata false; options.ClientId mvc; options.ClientSecret secret; options.ResponseType code id_token; options.SaveTokens true; options.GetClaimsFromUserInfoEndpoint true; options.Scope.Add(api1); options.Scope.Add(offline_access); }) .AddIdentityServerAuthentication(Bearer, options { options.Authority http://localhost:54660/IdentityServer; options.RequireHttpsMetadata false; options.ApiSecret secret123; options.ApiName api1; options.SupportedTokens SupportedTokens.Both; }); services.AddAuthorization(option { //默认 只写 [Authorize]表示使用oidc进行认证 option.DefaultPolicy new AuthorizationPolicyBuilder(oidc).RequireAuthenticatedUser().Build(); //ApiController使用这个 [Authorize(Policy ApiPolicy)]使用jwt认证方案 option.AddPolicy(ApiPolicy, policy { policy.AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme); policy.RequireAuthenticatedUser(); }); }); } public void Configure(IApplicationBuilder app, IHostingEnvironment env) { //var options new ForwardedHeadersOptions //{ // ForwardedHeaders ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto | ForwardedHeaders.XForwardedHost, // ForwardLimit 1 //}; //options.KnownNetworks.Clear(); //options.KnownProxies.Clear(); //app.UseForwardedHeaders(options); //if (env.IsDevelopment()) //{ // app.UseDeveloperExceptionPage(); //} //else //{ // app.UseExceptionHandler(/Home/Error); //} app.UseAuthentication(); app.UseStaticFiles(); app.UseMvc(routes { routes.MapRoute( name: default, template: MyApi/{controllerMAccount}/{actionLogin}/{id?}); }); } }主要添加了oidc认证配置和配置验证策略来同时支持oidc认证和Bearer认证。修改IdentityController中的[Authorize]特性为[Authorize(Policy ApiPolicy)] 依次使用调试-开始执行(不调试)并选择项目名称启动QuickstartIdentityServerGatewayMvcClientApi启动方式如图应该可以看到Gateway启动后直接显示了IdentityServer的默认首页 在浏览器输入http://localhost:54660/MVCClient/Home/index进入MVCClient 点击Secure进入需要授权的页面这时候会跳转到登陆页面才怪实际上我们会遇到一个错误这是因为ocelot做网关时下游服务获取到的Host实际为localhost:50891而在IdentityServer中设置的RedirectUris为网关的54660我们可以通过ocelot转发X-Forwarded-Host头并在客户端通过UseForwardedHeaders中间件来获取头。但是UseForwardedHeaders中间件为了防止IP欺骗攻击需要设置KnownNetworks和KnownProxies以实现严格匹配。当然也可以通过清空KnownNetworks和KnownProxies的默认值来不执行严格匹配这样一来就有可能受到攻击。所以这里我直接使用硬编码的方式设置Host实际使用时应从配置文件获取同时修改MvcClient和Api相关代码app.Use(async (context, next) { context.Request.Host HostString.FromUriComponent(new Uri(http://localhost:54660/)); await next.Invoke(); }); //var options new ForwardedHeadersOptions //{ // ForwardedHeaders ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto | ForwardedHeaders.XForwardedHost, // ForwardLimit 1 //}; //options.KnownNetworks.Clear(); //options.KnownProxies.Clear(); //app.UseForwardedHeaders(options);在反向代理情况下通过转发X-Forwarded-Host头来获取Host地址应该时常见设置不知道还有没有其他更好的解决办法。再次启动MVCClient并输入http://localhost:54660/MvcClient/Home/Secure。 使用bobpassword登陆一下点击Yes, Allow返回http://localhost:54660/MvcClient/Home/Secure此时可以查看到登陆后的信息 分别点击Call API using user token和Call API using application identity来验证一下通过access_token和ClientCredent模式请求来请求API 成功获取到返回值。 输入http://localhost:54660/myapi/Home/index来查看API情况求成功。点击Secure从API项目查看用户信息此时展示信息应该和MvcClient一致 嗯并没有看到用户信息而是又到了授权页.....这是因为.netCore使用DataProtection来保护数据点击查看详细信息Api项目不能解析由MvcClient生成的Cookie而被重定向到了IdentityServer服务中。在MvcClient和Api的ConfigureServices下添加如下代码来同步密钥环。 services.AddDataProtection(options options.ApplicationDiscriminator 00000).SetApplicationName(00000); 再次启动MvcClient和Api项目并在浏览器中输入http://localhost:54660/MvcClient/home/Secure此时被要求重新授权点击Yes, Allow后看到用户信息再输入http://localhost:54660/myapi/Home/Secure从API项目查看用户信息 分别点击Call API using user token和Call API using application identity来验证一下通过access_token和ClientCredent模式请求来请求API请求成功。 如此我们便实现了通过ocelot实现统一入口通过IdentityServer4来实现认证的需求 源代码 https://github.com/saber-wang/Quickstart5_HybridAndApi参考https://www.cnblogs.com/stulzq/category/1060023.htmlhttps://www.cnblogs.com/xiaoti/p/10118930.htmlhttps://www.cnblogs.com/jackcao/tag/identityserver4/原文地址https://www.cnblogs.com/nasha/p/10160695.html.NET社区新闻深度好文欢迎访问公众号文章汇总 http://www.csharpkit.com