写在前面

是这样的,我们现在接口使用了Ocelot做网关,Ocelot里面集成了基于IdentityServer4开发的授权中心用于对Api资源的保护。问题来了,我们的Api用了SwaggerUI做接口的自文档,那就蛋疼了,你接入了IdentityServer4的Api,用SwaggerUI调试、调用接口的话,妥妥的401,未授权啊。那有小伙伴就会说了,你SwaggerUI的Api不经过网关不就ok了?诶,好办法。但是:

  1. 我不想改变Url规则啊,我是/api开头的Url都是经过网关的,如果不经过网关要加端口或者改变Url规则,会给其他部门的同事带来麻烦(多个Url规则容易混淆);
  2. 另外是,因为生产环境是接入了IdentityServer4,我想测试环境从一开始就需要调用方熟悉接口的接入,避免平时用没有经过授权中心的Url调试,一到生产就出问题。

ok,废话讲得有点多,我们就直奔主题。

下面我们需要创建两个示例项目:

1、IdentityServer4的授权中心;

2、使用SwaggerUI做自文档的WebApi项目;

写得有点乱,本文源码地址:

https://github.com/gebiWangshushu/cnblogs-demos/tree/master/SwggerUI.IdentityServer4.Example

构建基于IdentityServer4授权中心

1、新建空白解决方案,并添加一个空的WebApi项目,IdentityServer

2、引用包。

  1. Install-Package IdentityServer4

3、添加配置类:Config.cs

  1. using IdentityServer4;
  2. using IdentityServer4.Models;
  3. using IdentityServer4.Test;
  4. using System;
  5. using System.Collections.Generic;
  6. using System.Linq;
  7. using System.Threading.Tasks;
  8. namespace IdentityServer
  9. {
  10. public static class Config
  11. {
  12. public static List<TestUser> GetUsers()
  13. {
  14. return new List<TestUser>
  15. {
  16. new TestUser
  17. {
  18. SubjectId = "1",
  19. Username = "alice",
  20. Password = "alice"
  21. }
  22. };
  23. }
  24. public static IEnumerable<IdentityResource> GetIdentityResources()
  25. {
  26. return new IdentityResource[]
  27. {
  28. new IdentityResources.OpenId(),
  29. new IdentityResources.Profile(),
  30. };
  31. }
  32. /// <summary>
  33. /// API信息
  34. /// </summary>
  35. /// <returns></returns>
  36. public static IEnumerable<ApiResource> GetApis()
  37. {
  38. return new[]
  39. {
  40. new ApiResource("swagger_api", "Demo SwaggerUI integrat Idp")
  41. };
  42. }
  43. /// <summary>
  44. /// 客服端信息
  45. /// </summary>
  46. /// <returns></returns>
  47. public static IEnumerable<Client> GetClients()
  48. {
  49. return new[]
  50. {
  51. new Client
  52. {
  53. ClientId = "swagger_client",//客服端名称
  54. ClientName = "Swagger UI client",//描述
  55. AllowedGrantTypes = GrantTypes.Implicit,//Implicit 方式
  56. AllowAccessTokensViaBrowser = true,//是否通过浏览器为此客户端传输访问令牌
  57. RedirectUris =
  58. {
  59. "http://localhost:5001/swagger/oauth2-redirect.html"
  60. },
  61. AllowedScopes = { "swagger_api" }
  62. }
  63. };
  64. }
  65. }
  66. }

4、修改Startup.cs

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Threading.Tasks;
  5. using Microsoft.AspNetCore.Builder;
  6. using Microsoft.AspNetCore.Hosting;
  7. using Microsoft.AspNetCore.Mvc;
  8. using Microsoft.Extensions.Configuration;
  9. using Microsoft.Extensions.DependencyInjection;
  10. using Microsoft.Extensions.Logging;
  11. using Microsoft.Extensions.Options;
  12. namespace IdentityServer
  13. {
  14. public class Startup
  15. {
  16. public IHostingEnvironment Environment { get; }
  17. public Startup(IHostingEnvironment environment)
  18. {
  19. Environment = environment;
  20. }
  21. public void ConfigureServices(IServiceCollection services)
  22. {
  23. services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
  24. var builder = services.AddIdentityServer()
  25. .AddInMemoryIdentityResources(Config.GetIdentityResources())
  26. .AddInMemoryApiResources(Config.GetApis())
  27. .AddInMemoryClients(Config.GetClients())
  28. .AddTestUsers(Config.GetUsers());
  29. if (Environment.IsDevelopment())
  30. {
  31. builder.AddDeveloperSigningCredential();
  32. }
  33. else
  34. {
  35. throw new Exception("need to configure key material");
  36. }
  37. }
  38. // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
  39. public void Configure(IApplicationBuilder app, IHostingEnvironment env)
  40. {
  41. if (env.IsDevelopment())
  42. {
  43. app.UseDeveloperExceptionPage();
  44. }
  45. app.UseIdentityServer();
  46. app.UseIdentityServer();
  47. app.UseMvcWithDefaultRoute();
  48. }
  49. }
  50. }

ok,跑起来了

使用SwaggerUI做自文档的WebApi项目

1、添加WebApi项目,SwaggerUIApi

现在项目结构这样:

2、先添加SwaggerUI,先不接入IdentityServer

修改Startup.cs

  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using System.Linq;
  5. using System.Reflection;
  6. using System.Threading.Tasks;
  7. using Microsoft.AspNetCore.Builder;
  8. using Microsoft.AspNetCore.Hosting;
  9. using Microsoft.AspNetCore.Mvc;
  10. using Microsoft.Extensions.Configuration;
  11. using Microsoft.Extensions.DependencyInjection;
  12. using Microsoft.Extensions.Logging;
  13. using Microsoft.Extensions.Options;
  14. using Swashbuckle.AspNetCore.Swagger;
  15. namespace SwggerUIApi
  16. {
  17. public class Startup
  18. {
  19. public Startup(IConfiguration configuration)
  20. {
  21. Configuration = configuration;
  22. }
  23. public IConfiguration Configuration { get; }
  24. // This method gets called by the runtime. Use this method to add services to the container.
  25. public void ConfigureServices(IServiceCollection services)
  26. {
  27. services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
  28. services.AddSwaggerGen(c =>
  29. {
  30. c.SwaggerDoc("v1", new Info
  31. {
  32. Version = "v1",
  33. Title = "ToDo API",
  34. Description = "A simple example ASP.NET Core Web API",
  35. TermsOfService = "None",
  36. Contact = new Contact
  37. {
  38. Name = "Shayne Boyer",
  39. Email = string.Empty,
  40. Url = "https://twitter.com/spboyer"
  41. },
  42. License = new License
  43. {
  44. Name = "Use under LICX",
  45. Url = "https://example.com/license"
  46. }
  47. });
  48. var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
  49. var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
  50. c.IncludeXmlComments(xmlPath);
  51. });
  52. }
  53. // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
  54. public void Configure(IApplicationBuilder app, IHostingEnvironment env)
  55. {
  56. if (env.IsDevelopment())
  57. {
  58. app.UseDeveloperExceptionPage();
  59. }
  60. app.UseSwagger();
  61. // Enable middleware to serve swagger-ui (HTML, JS, CSS, etc.),
  62. // specifying the Swagger JSON endpoint.
  63. app.UseSwaggerUI(c =>
  64. {
  65. c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
  66. });
  67. app.UseMvc();
  68. }
  69. }
  70. }

得到这样的SwaggerUI:

我们调用一下接口:

杠杠的200:

3、接口项目我们接入IdentityServer4

修改:Startup.cs ,ConfigureServices方法,

  1. services.AddAuthentication(IdentityServerAuthenticationDefaults.AuthenticationScheme)
  2. .AddIdentityServerAuthentication(options =>
  3. {
  4. options.Authority = "http://localhost:5000"; // IdentityServer服务器地址
  5. options.ApiName = "swagger_api"; // 用于针对进行身份验证的API资源的名称
  6. options.RequireHttpsMetadata = false; // 指定是否为HTTPS
  7. });

修改:Startup.cs ,Configure方法

  1. app.UseAuthentication();

Ok,可以看到我们接口接入IdentityServer了。提示401,未授权;

3、接入IdentityServer

1、添加授权响应操作的过滤器,AuthResponsesOperationFilter.cs

  1. using Microsoft.AspNetCore.Authorization;
  2. using Swashbuckle.AspNetCore.Swagger;
  3. using Swashbuckle.AspNetCore.SwaggerGen;
  4. using System;
  5. using System.Collections.Generic;
  6. using System.Linq;
  7. using System.Threading.Tasks;
  8. namespace SwggerUIApi
  9. {
  10. public class AuthResponsesOperationFilter : IOperationFilter
  11. {
  12. public void Apply(Operation operation, OperationFilterContext context)
  13. {
  14. //获取是否添加登录特性
  15. var authAttributes = context.MethodInfo.DeclaringType.GetCustomAttributes(true)
  16. .Union(context.MethodInfo.GetCustomAttributes(true))
  17. .OfType<AuthorizeAttribute>().Any();
  18. if (authAttributes)
  19. {
  20. operation.Responses.Add("401", new Response { Description = "暂无访问权限" });
  21. operation.Responses.Add("403", new Response { Description = "禁止访问" });
  22. operation.Security = new List<IDictionary<string, IEnumerable<string>>>
  23. {
  24. new Dictionary<string, IEnumerable<string>> {{"oauth2", new[] { "swagger_api" } }}
  25. };
  26. }
  27. }
  28. }
  29. }

2、修改Startup.cs ,ConfigureServices方法的,services.AddSwaggerGen()

配置成这样:

  1. services.AddSwaggerGen(c =>
  2. {
  3. c.SwaggerDoc("v1", new Info
  4. {
  5. Version = "v1",
  6. Title = "ToDo API",
  7. Description = "A simple example ASP.NET Core Web API",
  8. TermsOfService = "None",
  9. Contact = new Contact
  10. {
  11. Name = "Shayne Boyer",
  12. Email = string.Empty,
  13. Url = "https://twitter.com/spboyer"
  14. },
  15. License = new License
  16. {
  17. Name = "Use under LICX",
  18. Url = "https://example.com/license"
  19. }
  20. });
  21. var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
  22. var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
  23. c.IncludeXmlComments(xmlPath);
  24. //接入identityserver
  25. c.AddSecurityDefinition("oauth2", new OAuth2Scheme
  26. {
  27. Flow = "implicit", // 只需通过浏览器获取令牌(适用于swagger)
  28. AuthorizationUrl = "http://localhost:5000/connect/authorize",//获取登录授权接口
  29. Scopes = new Dictionary<string, string> {
  30. { "swagger_api_scopde", "swagger_api access" }//指定客户端请求的api作用域。 如果为空,则客户端无法访问
  31. }
  32. });
  33. c.OperationFilter<AuthResponsesOperationFilter>();
  34. });

3、我们还需给授权中心添加一个登陆界面

去: https://github.com/IdentityServer/IdentityServer4/tree/master/samples/Quickstarts/3_ImplicitFlowAuthentication/src/IdentityServer

下载这个两个文件夹,复制丢到IdentityServer项目下面:

项目结构:

4、我们运行看看

先启动Identityserver项目

运行SwaggerUI可以看到,这两个地方了个小锁头,表示已启用安全保护:

我们点一下上面的按钮:

哇,我们跳到了这里:

输入:alice/alice,点登录:

哇哇:

当然是Yes啦,然后这边变成这样了:

这是已获得授权状态,我们再次调用看看:

这里我们看到已经调用成功,仔细看请求,与前面简短的请求不同的是,现在请求里面带了access_token了,

这才是我们折腾这么久得来的宝贝。

总结

写得有点匆忙,希望大家能看得懂[捂脸];

源码地址:https://github.com/gebiWangshushu/cnblogs-demos/tree/master/SwggerUI.IdentityServer4.Example

参考

https://github.com/domaindrivendev/Swashbuckle.AspNetCore

https://github.com/IdentityServer/IdentityServer4

ASP.NET Core Swagger接入使用IdentityServer4 的 WebApi的更多相关文章

  1. Asp.Net Core SwaggerUI 接入

    Asp.Net Core SwaggerUI 接入 简单了解 swagger的目的简单来说就是,不用为每个接口手动写接口文档,因为它是根据接口自动生成的,接口更改时文档也同步更新,减少了手动更新的麻烦 ...

  2. ASP.NET Core身份认证服务框架IdentityServer4(2)-整体介绍

    一.整体情况 现代应用程序看起来更像这个: 最常见的相互作用: 浏览器与Web应用程序的通信 Browser -> Web App Web应用程序与Web API通信 基于浏览器的应用程序与We ...

  3. asp.net core swagger使用及注意事项

    Swagger 是一个规范和完整的框架,用于生成.描述.调用和可视化 RESTful 风格的 Web 服务.是一款RESTFUL接口的文档在线自动生成+功能测试软件.主要目的是构建标准的.稳定的.可重 ...

  4. ASP.NET Core身份认证服务框架IdentityServer4 介绍

    IdentityServer4是ASP.NET Core 2的OpenID Connect和OAuth 2.0框架.它可以在您的应用程序中提供以下功能: 它使你的应用程序具有如下特点: 认证即服务 适 ...

  5. Asp.Net Core: Swagger 与 Identity Server 4

    Swagger不用多说,可以自动生成Web Api的接口文档和客户端调用代码,方便开发人员进行测试.通常我们只需要几行代码就可以实现这个功能: ... builder.Services.AddSwag ...

  6. ASP.NET Core 奇淫技巧之动态WebApi

    一.前言 接触到动态WebApi(Dynamic Web API)这个词的已有几年,是从ABP框架里面接触到的,当时便对ABP的这个技术很好奇,后面分析了一波,也尝试过从ABP剥离一个出来作为独立组件 ...

  7. ASP.NET Core 2.2 基础知识(十三) WebAPI 概述

    我们先创建一个 WebAPI 项目,看看官方给的模板到底有哪些东西 官方给出的模板: [Route("api/[controller]")] [ApiController] pub ...

  8. 记Asp.Net Core Swagger 使用 并带域接口处理

    引用作者原话:Asp.Net的WebApi中使用Swagger作为说明和测试的页面是非常不错的,比起WebApiTestClient来至少在界面上的很大的提升.但是使用Swagger时如果只是一般的控 ...

  9. ASP.NET CORE Swagger

    Package 添加并配置Swagger中间件 将Swagger生成器添加到方法中的服务集合中Startup.ConfigureServices: public void ConfigureServi ...

随机推荐

  1. net core 记录自定义端口多个方式

    1.直接修改 . 2.代码定义 public class Program { public static void Main(string[] args) { CreateWebHostBuilder ...

  2. saltstack手册(含官方pdf)

    官方手册 https://docs.saltstack.com/en/pdf/Salt-2019.2.1.pdf 快速入门 SALTSTACK是什么? Salt是一种和以往不同的基础设施管理方法,它是 ...

  3. sedlauncher.exe 磁盘爆满

    打开应用和功能,搜KB4023057,然后卸载. 快捷键WIN+R打开运行,输入services.msc回车打开系统服务,找到Windows Remediation Service (sedsvc)和 ...

  4. from import语句

    *)假如导入出现了问题,那么一定是导入的文件里的语法问题或者其他问题 参考链接:http://www.cnblogs.com/hwf-73/p/5493328.html 1)导入时重命名 as fro ...

  5. 2019 安易迅java面试笔试题 (含面试题解析)

      本人5年开发经验.18年年底开始跑路找工作,在互联网寒冬下成功拿到阿里巴巴.今日头条.安易迅等公司offer,岗位是Java后端开发,因为发展原因最终选择去了安易迅,入职一年时间了,也成为了面试官 ...

  6. android studio学习----通过libs来导入jar包

    百度经验有一种方法: 1 点击启动AndroidStudio,启动后的界面如图所示. 2 复制你需要添加的jar,并将其黏贴到app— —src— —main— —libs文件夹下,可运行的Andro ...

  7. MySQL数据物理备份之xtrabackup

    percona-xtrabackup 它是开源免费的支持MySQL 数据库热备份的软件,它能对InnoDB和XtraDB存储引擎的数据库非阻塞地备份.它不暂停服务创建Innodb热备份: 为mysql ...

  8. Mysql数据库之备份还原(mysqldump,LVM快照,select备份,xtrabackup)

    备份类型: 热备份:读写不受影响 温备份:仅可执行读备份 冷备份:离线备份,读写均不能执行,关机备份 物理备份和逻辑备份 物理备份:复制数据文件,速度快. 逻辑备份:将数据导出之文本文件中,必要时候, ...

  9. Python3+HTMLTestRunner+SMTP生成测试报告后发送邮件

    在前一篇https://www.cnblogs.com/zhengyihan1216/p/11549820.html 中记录了如何生成html格式的报告, 这篇记录下怎么将测试报告通过邮件发出 1.对 ...

  10. Jmeter(四十四)启动提示 Could not open/create prefs root node Software\JavaSoft\Prefs at root 0x80000002. Windows RegCreateKeyEx(...) returned error code 5.

    有已知的已知:有些事情我们自己知道自己知道: 我们也知道有已知的未知:这是指我们知道有些事情自己不知道: 但是还有未知的未知:有些事情我们不知道自己不知道:   ---美国国防部长 唐纳德·拉姆斯菲尔 ...