-
Notifications
You must be signed in to change notification settings - Fork 9
Expand file tree
/
Copy pathDocumentGenerator.Security.cs
More file actions
117 lines (100 loc) · 4.06 KB
/
DocumentGenerator.Security.cs
File metadata and controls
117 lines (100 loc) · 4.06 KB
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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
/*
* _____ ______
* /_ / ____ ____ ____ _________ / __/ /_
* / / / __ \/ __ \/ __ \/ ___/ __ \/ /_/ __/
* / /__/ /_/ / / / / /_/ /\_ \/ /_/ / __/ /_
* /____/\____/_/ /_/\__ /____/\____/_/ \__/
* /____/
*
* Authors:
* 钟峰(Popeye Zhong) <zongsoft@qq.com>
*
* Copyright (C) 2020-2025 Zongsoft Studio <http://www.zongsoft.com>
*
* This file is part of Zongsoft.Web.OpenApi library.
*
* The Zongsoft.Web.OpenApi is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3.0 of the License,
* or (at your option) any later version.
*
* The Zongsoft.Web.OpenApi is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with the Zongsoft.Web.OpenApi library. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
using System.Collections.Generic;
using Microsoft.OpenApi;
using Zongsoft.Configuration;
namespace Zongsoft.Web.OpenApi;
partial class DocumentGenerator
{
private static readonly HashSet<string> HTTP_SCHEMES = new(StringComparer.OrdinalIgnoreCase)
{
"Basic",
"Bearer",
"Digest",
"NTLM",
"Negotiate",
};
internal static void GenerateSecuritySchemes(this DocumentContext context)
{
var authentication = context.Configuration.GetOption<Configuration.AuthenticationOption>("/Web/OpenAPI/Authentication");
if(authentication == null || authentication.Authenticators.Count == 0)
return;
context.Document.Components.SecuritySchemes ??= new Dictionary<string, IOpenApiSecurityScheme>(StringComparer.OrdinalIgnoreCase);
foreach(var authenticator in authentication.Authenticators)
{
var scheme = new OpenApiSecurityScheme()
{
Name = authenticator.Name,
Type = authenticator.Kind.ToType(),
In = authenticator.Location.ToLocation(),
Scheme = authenticator.Scheme,
};
//处理特殊安全方案
Specialize(scheme, authenticator.Properties);
foreach(var property in authenticator.Properties)
scheme.AddExtension($"x-{property.Key}", Extensions.Helper.String(property.Value));
context.Document.Components.SecuritySchemes[authenticator.Name] = scheme;
}
}
private static void Specialize(OpenApiSecurityScheme scheme, IDictionary<string, string> properties)
{
if(scheme.Type == SecuritySchemeType.Http)
{
scheme.In = ParameterLocation.Header;
if(string.IsNullOrWhiteSpace(scheme.Scheme))
scheme.Scheme = "Basic";
if(HTTP_SCHEMES.Contains(scheme.Scheme))
return;
scheme.Name = "Authorization";
scheme.Type = SecuritySchemeType.ApiKey;
}
else if(scheme.Type == SecuritySchemeType.ApiKey)
{
if(!string.IsNullOrEmpty(scheme.Scheme))
scheme.Name = scheme.Scheme;
}
}
private static SecuritySchemeType ToType(this Configuration.AuthenticationOption.AuthenticatorKind kind) => kind switch
{
Configuration.AuthenticationOption.AuthenticatorKind.Http => SecuritySchemeType.Http,
Configuration.AuthenticationOption.AuthenticatorKind.Custom => SecuritySchemeType.ApiKey,
Configuration.AuthenticationOption.AuthenticatorKind.OAuth2 => SecuritySchemeType.OAuth2,
Configuration.AuthenticationOption.AuthenticatorKind.OpenID => SecuritySchemeType.OpenIdConnect,
_ => SecuritySchemeType.Http,
};
private static ParameterLocation ToLocation(this Configuration.AuthenticationOption.AuthenticatorLocation location) => location switch
{
Configuration.AuthenticationOption.AuthenticatorLocation.Path => ParameterLocation.Path,
Configuration.AuthenticationOption.AuthenticatorLocation.Query => ParameterLocation.Query,
Configuration.AuthenticationOption.AuthenticatorLocation.Header => ParameterLocation.Header,
Configuration.AuthenticationOption.AuthenticatorLocation.Cookie => ParameterLocation.Cookie,
_ => ParameterLocation.Header,
};
}