ASP.NET Core Web API SwaggerUI 集成 IdentityServer4 OAuth 授权

ASP.NET Core Web API SwaggerUI 集成 IdentityServer4 OAuth 授权

创建 IdentityServer 项目

配置 Startup.cs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
public void ConfigureServices(IServiceCollection services)
{
// 这是添加 MVC 和 视图,因为我们需要使用 QuickStart.UI
services.AddControllersWithViews();

// 这只是允许 IdentityServer4 输出一些事件日志
services.AddIdentityServer(options =>
{
options.Events.RaiseInformationEvents = true;
options.Events.RaiseErrorEvents = true;
options.Events.RaiseSuccessEvents = true;
options.Events.RaiseFailureEvents = true;

options.Authentication.CheckSessionCookieSameSiteMode = SameSiteMode.Lax;

// 如果在客户端跳转登录时,出现无法回到客户端页面时,多半是 Cookie 的 SameSiteMode 导致的
// 添加下面这一行可以解决
options.Authentication.CookieSameSiteMode = SameSiteMode.Lax;
})
// 添加用于开发环境的 JWT 签名密钥
.AddDeveloperSigningCredential()
// 这是在内存中配置一些资源,方便测试
.AddInMemoryIdentityResources(Config.IdentityResources)
.AddInMemoryApiResources(Config.ApiResources)
.AddInMemoryApiScopes(Config.ApiScopes)

// 这是添加的测试客户端
.AddInMemoryClients(Config.Clients)

// 这是添加的测试用户
.AddTestUsers(TestUsers.Users);
}

public void Configure(IApplicationBuilder app)
{
// 因为是 MVC 所以需要静态文件
app.UseStaticFiles();

// 这是启用路由中间件
app.UseRouting();

// 这是启用 IdentityServer 的认证中间件
app.UseIdentityServer();

// 这是启用授权中间件,便于使用 [Authorize]
app.UseAuthorization();

app.UseEndpoints(endpoints =>
{
// 这是 MVC 的默认路由
endpoints.MapDefaultControllerRoute();
});
}

配置 Config.cs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
public static class Config
{
public static List<IdentityResource> IdentityResources => new()
{
new IdentityResources.OpenId(),
new IdentityResources.Profile(),
};

public static List<ApiResource> ApiResources => new()
{

};

public static List<ApiScope> ApiScopes => new()
{
new ApiScope("webapi")
};

public static List<Client> Clients => new()
{
// 这个就是 SwaggerUI 的 Client,使用的 OAuth 授权码模式
new Client()
{
ClientName = "Swagger UI",
ClientId = "swagger",
ClientSecrets =
{
new Secret("swagger".Sha256())
},
AllowedGrantTypes = GrantTypes.Code,
//AllowAccessTokensViaBrowser = true,
RequirePkce = true,
RequireConsent = true,
RedirectUris =
{
"http://localhost:5000/swagger/oauth2-redirect.html"
},
AllowedCorsOrigins =
{
"http://localhost:5000"
},
AllowedScopes =
{
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile,
"webapi" // 这是我们的 WebApi 的 Scope
},
}
};
}

创建 WebAPI 项目

配置 Startup.cs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
services.AddAuthentication("Bearer") // 这是设置默认的认证方案
// 这是添加一个名称为 "Bearer" 的 JWT 认证方案
.AddJwtBearer("Bearer", options =>
{
// 远程认证的地址,即 IdentityServer 项目的地址
options.Authority = authority;

// 这是为了避免因未使用 HTTPS 协议的情况下可能导致的一些错误
options.RequireHttpsMetadata = false;

// 这是配置 JWT 的验证参数
options.TokenValidationParameters = new TokenValidationParameters
{
// 不验证 JWT 的受众,即不验证 JWT 中的 aud 属性
ValidateAudience = false
};
});

最后在 Controller 的 Action 打上 [Authorize] 即可

注意事项

  1. 为什么 ApiController 加了 [Authorize],但 SwaggerUI 中的 Action 最右边没有 一把锁 的图标?
    答:因为 [Authorize] 必须加在 ApiController 的 Action 方法上,才能在 SwaggerUI 中展示锁图标(坑)。