ASP.NET Core Swagger接入使用IdentityServer4 的 WebApi
写在前面
是这样的,我们现在接口使用了Ocelot做网关,Ocelot里面集成了基于IdentityServer4开发的授权中心用于对Api资源的保护。问题来了,我们的Api用了SwaggerUI做接口的自文档,那就蛋疼了,你接入了IdentityServer4的Api,用SwaggerUI调试、调用接口的话,妥妥的401,未授权啊。那有小伙伴就会说了,你SwaggerUI的Api不经过网关不就ok了?诶,好办法。但是:
- 我不想改变Url规则啊,我是
/api
开头的Url都是经过网关的,如果不经过网关要加端口或者改变Url规则,会给其他部门的同事带来麻烦(多个Url规则容易混淆); - 另外是,因为生产环境是接入了IdentityServer4,我想测试环境从一开始就需要调用方熟悉接口的接入,避免平时用没有经过授权中心的Url调试,一到生产就出问题。
ok,废话讲得有点多,我们就直奔主题。
下面我们需要创建两个示例项目:
1、IdentityServer4的授权中心;
2、使用SwaggerUI做自文档的WebApi项目;
写得有点乱,本文源码地址:
https://github.com/gebiWangshushu/cnblogs-demos/tree/master/SwggerUI.IdentityServer4.Example
构建基于IdentityServer4授权中心
1、新建空白解决方案,并添加一个空的WebApi项目,IdentityServer
2、引用包。
Install-Package IdentityServer4
3、添加配置类:Config.cs
using IdentityServer4;
using IdentityServer4.Models;
using IdentityServer4.Test;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace IdentityServer
{
public static class Config
{
public static List<TestUser> GetUsers()
{
return new List<TestUser>
{
new TestUser
{
SubjectId = "1",
Username = "alice",
Password = "alice"
}
};
}
public static IEnumerable<IdentityResource> GetIdentityResources()
{
return new IdentityResource[]
{
new IdentityResources.OpenId(),
new IdentityResources.Profile(),
};
}
/// <summary>
/// API信息
/// </summary>
/// <returns></returns>
public static IEnumerable<ApiResource> GetApis()
{
return new[]
{
new ApiResource("swagger_api", "Demo SwaggerUI integrat Idp")
};
}
/// <summary>
/// 客服端信息
/// </summary>
/// <returns></returns>
public static IEnumerable<Client> GetClients()
{
return new[]
{
new Client
{
ClientId = "swagger_client",//客服端名称
ClientName = "Swagger UI client",//描述
AllowedGrantTypes = GrantTypes.Implicit,//Implicit 方式
AllowAccessTokensViaBrowser = true,//是否通过浏览器为此客户端传输访问令牌
RedirectUris =
{
"http://localhost:5001/swagger/oauth2-redirect.html"
},
AllowedScopes = { "swagger_api" }
}
};
}
}
}
4、修改Startup.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
namespace IdentityServer
{
public class Startup
{
public IHostingEnvironment Environment { get; }
public Startup(IHostingEnvironment environment)
{
Environment = environment;
}
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
var builder = services.AddIdentityServer()
.AddInMemoryIdentityResources(Config.GetIdentityResources())
.AddInMemoryApiResources(Config.GetApis())
.AddInMemoryClients(Config.GetClients())
.AddTestUsers(Config.GetUsers());
if (Environment.IsDevelopment())
{
builder.AddDeveloperSigningCredential();
}
else
{
throw new Exception("need to configure key material");
}
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseIdentityServer();
app.UseIdentityServer();
app.UseMvcWithDefaultRoute();
}
}
}
ok,跑起来了
使用SwaggerUI做自文档的WebApi项目
1、添加WebApi项目,SwaggerUIApi
现在项目结构这样:
2、先添加SwaggerUI,先不接入IdentityServer
修改Startup.cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Swashbuckle.AspNetCore.Swagger;
namespace SwggerUIApi
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new Info
{
Version = "v1",
Title = "ToDo API",
Description = "A simple example ASP.NET Core Web API",
TermsOfService = "None",
Contact = new Contact
{
Name = "Shayne Boyer",
Email = string.Empty,
Url = "https://twitter.com/spboyer"
},
License = new License
{
Name = "Use under LICX",
Url = "https://example.com/license"
}
});
var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
c.IncludeXmlComments(xmlPath);
});
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseSwagger();
// Enable middleware to serve swagger-ui (HTML, JS, CSS, etc.),
// specifying the Swagger JSON endpoint.
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
});
app.UseMvc();
}
}
}
得到这样的SwaggerUI:
我们调用一下接口:
杠杠的200:
3、接口项目我们接入IdentityServer4
修改:Startup.cs ,ConfigureServices方法,
services.AddAuthentication(IdentityServerAuthenticationDefaults.AuthenticationScheme)
.AddIdentityServerAuthentication(options =>
{
options.Authority = "http://localhost:5000"; // IdentityServer服务器地址
options.ApiName = "swagger_api"; // 用于针对进行身份验证的API资源的名称
options.RequireHttpsMetadata = false; // 指定是否为HTTPS
});
修改:Startup.cs ,Configure方法
app.UseAuthentication();
Ok,可以看到我们接口接入IdentityServer了。提示401,未授权;
3、接入IdentityServer
1、添加授权响应操作的过滤器,AuthResponsesOperationFilter.cs
using Microsoft.AspNetCore.Authorization;
using Swashbuckle.AspNetCore.Swagger;
using Swashbuckle.AspNetCore.SwaggerGen;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace SwggerUIApi
{
public class AuthResponsesOperationFilter : IOperationFilter
{
public void Apply(Operation operation, OperationFilterContext context)
{
//获取是否添加登录特性
var authAttributes = context.MethodInfo.DeclaringType.GetCustomAttributes(true)
.Union(context.MethodInfo.GetCustomAttributes(true))
.OfType<AuthorizeAttribute>().Any();
if (authAttributes)
{
operation.Responses.Add("401", new Response { Description = "暂无访问权限" });
operation.Responses.Add("403", new Response { Description = "禁止访问" });
operation.Security = new List<IDictionary<string, IEnumerable<string>>>
{
new Dictionary<string, IEnumerable<string>> {{"oauth2", new[] { "swagger_api" } }}
};
}
}
}
}
2、修改Startup.cs ,ConfigureServices方法的,services.AddSwaggerGen()
配置成这样:
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new Info
{
Version = "v1",
Title = "ToDo API",
Description = "A simple example ASP.NET Core Web API",
TermsOfService = "None",
Contact = new Contact
{
Name = "Shayne Boyer",
Email = string.Empty,
Url = "https://twitter.com/spboyer"
},
License = new License
{
Name = "Use under LICX",
Url = "https://example.com/license"
}
});
var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
c.IncludeXmlComments(xmlPath);
//接入identityserver
c.AddSecurityDefinition("oauth2", new OAuth2Scheme
{
Flow = "implicit", // 只需通过浏览器获取令牌(适用于swagger)
AuthorizationUrl = "http://localhost:5000/connect/authorize",//获取登录授权接口
Scopes = new Dictionary<string, string> {
{ "swagger_api_scopde", "swagger_api access" }//指定客户端请求的api作用域。 如果为空,则客户端无法访问
}
});
c.OperationFilter<AuthResponsesOperationFilter>();
});
3、我们还需给授权中心添加一个登陆界面
下载这个两个文件夹,复制丢到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的更多相关文章
- Asp.Net Core SwaggerUI 接入
Asp.Net Core SwaggerUI 接入 简单了解 swagger的目的简单来说就是,不用为每个接口手动写接口文档,因为它是根据接口自动生成的,接口更改时文档也同步更新,减少了手动更新的麻烦 ...
- ASP.NET Core身份认证服务框架IdentityServer4(2)-整体介绍
一.整体情况 现代应用程序看起来更像这个: 最常见的相互作用: 浏览器与Web应用程序的通信 Browser -> Web App Web应用程序与Web API通信 基于浏览器的应用程序与We ...
- asp.net core swagger使用及注意事项
Swagger 是一个规范和完整的框架,用于生成.描述.调用和可视化 RESTful 风格的 Web 服务.是一款RESTFUL接口的文档在线自动生成+功能测试软件.主要目的是构建标准的.稳定的.可重 ...
- ASP.NET Core身份认证服务框架IdentityServer4 介绍
IdentityServer4是ASP.NET Core 2的OpenID Connect和OAuth 2.0框架.它可以在您的应用程序中提供以下功能: 它使你的应用程序具有如下特点: 认证即服务 适 ...
- Asp.Net Core: Swagger 与 Identity Server 4
Swagger不用多说,可以自动生成Web Api的接口文档和客户端调用代码,方便开发人员进行测试.通常我们只需要几行代码就可以实现这个功能: ... builder.Services.AddSwag ...
- ASP.NET Core 奇淫技巧之动态WebApi
一.前言 接触到动态WebApi(Dynamic Web API)这个词的已有几年,是从ABP框架里面接触到的,当时便对ABP的这个技术很好奇,后面分析了一波,也尝试过从ABP剥离一个出来作为独立组件 ...
- ASP.NET Core 2.2 基础知识(十三) WebAPI 概述
我们先创建一个 WebAPI 项目,看看官方给的模板到底有哪些东西 官方给出的模板: [Route("api/[controller]")] [ApiController] pub ...
- 记Asp.Net Core Swagger 使用 并带域接口处理
引用作者原话:Asp.Net的WebApi中使用Swagger作为说明和测试的页面是非常不错的,比起WebApiTestClient来至少在界面上的很大的提升.但是使用Swagger时如果只是一般的控 ...
- ASP.NET CORE Swagger
Package 添加并配置Swagger中间件 将Swagger生成器添加到方法中的服务集合中Startup.ConfigureServices: public void ConfigureServi ...
随机推荐
- 《 .NET并发编程实战》实战习题集 - 2 - 替换算法
先发表生成URL以印在书里面.等书籍正式出版销售后会公开内容.
- 使用XSSFWorkbook 读取excel
工作中用到 使用XSSFWorkbook 读取excel 具体代码如下, private (List<(string columnName, string colomnDescription)& ...
- sql比较字符串,比的到底是什么?
sql里有nvarchar类型的日期数据time1:2019-10-09 00:00:00, 现给定string类型日期time2:2019-10-01 23:59:59,比较两个日期的大小, 发现可 ...
- oracle 10 升级补丁
Ooacle 10g补丁安装方法 Windows 平台 方法: 1. 备份数据库:关闭数据库,拷贝,安装软件目录,数据文件拷到另一个地方 2. 关闭停止所有oracle 服务+Distribute ...
- 【Visio】亲测Visio2013激活,破解工具下载
破解方法地址: https://blog.csdn.net/qq_38276669/article/details/85046615
- vim 如何复制文件中多行到另一个文件
1.打开文件 vim a.txt b.tx 或者 vim *.txt 2.文件间切换 :n 切换到下一个文件 :wn 保存再切换 :N 到上一个文件 :wN 保存再切换 :.= 看当前行 3.假定当前 ...
- 配置Java,jdk环境变量
注意:所有的都是配系统变量 变量名:JAVA_HOME 变量值:D:\Program Files\Java\jdk1.8.0_202(以自己的为准)变量名:Path 变量值:%JAVA_HOME%\b ...
- C++运算符重载学习总结
在C ++中,我们可以使运算符适用于用户定义的类. 这意味着C ++能够为运算符提供数据类型的特殊含义,这种能力称为运算符重载. 例如,我们可以在像String这样的类中重载运算符'+',这样我们就可 ...
- Java面经入口(持续更新...)
大数据面经 https://zhuanlan.zhihu.com/go-for-it Java 基础知识复习 您可能不知道Java基础40道常见面试题及详细答案 hashcode详解 Java St ...
- 01GitLab的使用——创建项目并上传到GitLab
借鉴:https://jingyan.baidu.com/article/9c69d48fe68cce13c9024e9c.html 登录GitLab网站,创建一个项目上传地址:https://blo ...