我将身份验证服务生成的令牌用于我的应用程序。这没什么问题。现在,我已经引入Swashbuckle来记录我的API,我可以通过使用下面的代码向每个请求发送JWT来进行如下身份验证;
services.AddSwaggerGen(c =>
{
var a = new ApiKeyScheme();
//c.AddSecurityDefinition("Bearer", new ApiKeyScheme()
//{ In = "header", Description = "Please insert JWT with Bearer into field", Name = "Authorization", Type = "apiKey" });
c.OperationFilter<AuthorizationHeaderParameterOperationFilter>();
c.SwaggerDoc("v2", new Info
{
Version = "v2",
Title = "MyTitle",
Description = "An interface for ...",
TermsOfService = "None",
Contact = new Contact() { Name = "MyApp", Email = "a@example.com", Url = "www.example.com" }
});
// Set the comments path for the Swagger JSON and UI.
var basePath = AppContext.BaseDirectory;
var xmlPath = Path.Combine(basePath, "cpDataCore.xml");
c.IncludeXmlComments(xmlPath);
});
public class AuthorizationHeaderParameterOperationFilter : IOperationFilter
{
public void Apply(Operation operation, OperationFilterContext context)
{
var filterPipeline = context.ApiDescription.ActionDescriptor.FilterDescriptors;
var isAuthorized = filterPipeline.Select(filterInfo => filterInfo.Filter).Any(filter => filter is AuthorizeFilter);
var allowAnonymous = filterPipeline.Select(filterInfo => filterInfo.Filter).Any(filter => filter is IAllowAnonymousFilter);
if (isAuthorized && !allowAnonymous)
{
if (operation.Parameters == null)
operation.Parameters = new List<IParameter>();
operation.Parameters.Add(new NonBodyParameter
{
Name = "Authorization",
In = "header",
Description = "access token",
Required = true,
Type = "string"
});
}
}
}
这给了我下面的头--不出所料
accept:application/json
Accept-Encoding:gzip, deflate, br
Accept-Language:en-AU,en;q=0.9
Authorization:Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9naXZlbm5hbWUiOiJEZW5uaXMiLCJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9zdXJuYW1lIjoiR2FzY29pZ25lIiwiaHR0cDovL3NjaGVtYXMueG1sc29hcC5vcmcvd3MvMjAwNS8wNS9pZGVudGl0eS9jbGFpbXMvbmFtZSI6ImRlbm5pc2ciLCJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9zaWQiOiI1NCIsIlJlZnJlc2hUb2tlbiI6IjY5OTA1NTFmLTNhOTQtNDVmYi1hYjc2LTZlOTQyNGE3NjJmOCIsIkFsbERhdGFSZWFkT25seUZvckFwcHJvdmVycyI6IlRydWUiLCJQcm9qZWN0SUQiOiI2IiwiaHR0cDovL3NjaGVtYXMubWljcm9zb2Z0LmNvbS93cy8yMDA4LzA2L2lkZW50aXR5L2NsYWltcy9yb2xlIjoic3lzYWRtaW4iLCJuYmYiOjE1MTk2MzY2NDIsImV4cCI6MTUxOTYzODQ0MiwiaXNzIjoiaHR0cHM6Ly9kYXRhLmNpdmlscHJvc29mdHdhcmUuY29tLyIsImF1ZCI6Imh0dHBzOi8vcm1zLmNpdmlscHJvc29mdHdhcmUuY29tLyJ9.nBEZgzcmZVGhFJmKI8u7p7g7xPU13HEAGJu_lrWylnc
Connection:keep-alive
Cookie:username=demo; jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9naXZlbm5hbWUiOiJUcm95IiwiaHR0cDovL3NjaGVtYXMueG1sc29hcC5vcmcvd3MvMjAwNS8wNS9pZGVudGl0eS9jbGFpbXMvc3VybmFtZSI6IkVsZGVyIiwiaHR0cDovL3NjaGVtYXMueG1sc29hcC5vcmcvd3MvMjAwNS8wNS9pZGVudGl0eS9jbGFpbXMvbmFtZSI6InRyb3kiLCJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9zaWQiOiI1IiwiUmVmcmVzaFRva2VuIjoiMTNhNzRmNDQtNmVmOC00MDQ3LTlmYWYtOWQ3MzI4MmNhZjQ4IiwiUHJvamVjdElEIjoiLTEiLCJuYmYiOjE1MDUwOTc3MjEsImV4cCI6MTUwNTA5ODYyMSwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo2MDAwMC8iLCJhdWQiOiJodHRwOi8vbG9jYWxob3N0OjYwMDAwLyJ9.8You0XiUlvdHb2TRuDzaiXv6r74v7ga1Av_Z3ikmblU
Host:localhost:60000
Referer:http://localhost:60000/swagger/
User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.167 Safari/537.36
虽然,我不确定Cookie是从哪里来的。这与我的代码没有任何关系。我只是忽略它--到目前为止一切都很好。
问题是,这意味着每个请求都必须输入令牌,这是一件痛苦的事情。理想情况下,我希望使用内置的swagger接口进行身份验证-根据几篇文章,我应该能够做到这一点;
c.AddSecurityDefinition("Bearer", new ApiKeyScheme()
{ In = "header", Description = "Please insert JWT with Bearer into field", Name = "Authorization", Type = "apiKey" });
这可以很好地工作,我可以添加令牌,只是似乎缺少一个步骤来将令牌添加到每个请求的头部。如果我只是添加auth,那么就会得到下面的头信息,这当然会导致身份验证失败。
GET /api/ApprovalItemTypes HTTP/1.1
Host: localhost:60000
Connection: keep-alive
accept: application/json
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.167 Safari/537.36
Referer: http://localhost:60000/swagger/
Accept-Encoding: gzip, deflate, br
Accept-Language: en-AU,en;q=0.9
Cookie: username=demo; jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW5_xxx__LTEiLCJuYmYiOjE1MDUwOTc3MjEsImV4cCI6MTUwNTA5ODYyMSwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo2MDAwMC8iLCJhdWQiOiJodHRwOi8vbG9jYWxob3N0OjYwMDAwLyJ9.8You0XiUlvdHb2TRuDzaiXv6r74v7ga1Av_Z3ikmblU
为了让请求包含每个后续请求的令牌,我还需要做些什么?
发布于 2020-04-22 04:04:06
最后,我转到了NSwag,所以我不确定最初的问题是什么。Nswag中的解决方案如下;
services.AddSwaggerDocument(document =>
{
document.DocumentName = "CPSwagger";
document.Title = "My Mobile API";
document.Version = "v10.3.4";
document.Description = "An interface for some software.";
document.DocumentProcessors.Add(
new SecurityDefinitionAppender("JWT token", new NSwag.OpenApiSecurityScheme
{
Type = NSwag.OpenApiSecuritySchemeType.ApiKey,
Name = "Authorization",
Description = "Copy 'Bearer ' + valid JWT token into field",
In = NSwag.OpenApiSecurityApiKeyLocation.Header
}));
document.OperationProcessors.Add(new OperationSecurityScopeProcessor("JWT token"));
});
发布于 2018-03-19 17:22:28
如果您在您的方法上指定了过滤器,Swagger将添加authorzation头。如果您在全局范围内需要授权,我猜swagger无法识别它们。
您需要在ConfigureServices中添加一个如下所示的SecurityRequirement:
c.AddSecurityRequirement(new Dictionary<string, IEnumerable<string>>()
{
{ "Bearer", new string[]{ } }
});
如果设置了令牌,这将要求在每个请求中使用发送报头。如果您没有设置标题之前,它将不会发送它,但您仍然会有挂锁标志旁边的api描述。
发布于 2019-02-14 17:32:11
如果您在代码中定义
c.AddSecurityDefinition("jwt", new ApiKeyScheme()
{
In = "header", Description = "Please insert JWT with Bearer into field", Name = "Authorization", Type = "apiKey" });
然后在.Security中而不是在.Parameters中使用它
operation.Security = new List<IDictionary<string, IEnumerable<string>>> {
new Dictionary<string, IEnumerable<string>>
{
{"jwt", _scopes }
}
那么一切都应该正常工作:
我做的和你做的一样,但是你应该添加如下内容(对于oauth2或jwt持有者令牌身份验证):
public static class ServiceCollectionExtension
{
private static string XmlCommentsFilePath
{
get
{
var basePath = PlatformServices.Default.Application.ApplicationBasePath;
var fileName = Assembly.GetEntryAssembly().GetName().Name + ".xml";
return Path.Combine(basePath, fileName);
}
}
public static void AddMySwagger(
this IServiceCollection services,
ApiVersion defaultApiVersion,
Func<ApiVersionDescription, Info> info,
string authority = null,
Dictionary<string, string> scopes = null)
{
services.AddMvcCore().AddVersionedApiExplorer(o => o.GroupNameFormat = "'v'VVV");
services.AddApiVersioning(o =>
{
o.ReportApiVersions = true;
o.AssumeDefaultVersionWhenUnspecified = true;
o.DefaultApiVersion = defaultApiVersion;
});
services.AddSwaggerGen(
options =>
{
var provider = services.BuildServiceProvider()
.GetRequiredService<IApiVersionDescriptionProvider>();
foreach (var description in provider.ApiVersionDescriptions)
{
if (!description.IsDeprecated)
options.SwaggerDoc(description.GroupName, info(description));
}
options.OperationFilter<DefaultValues>();
options.IncludeXmlComments(XmlCommentsFilePath);
if (!string.IsNullOrEmpty(authority))
{
options.AddSecurityDefinition("jwt", new ApiKeyScheme()
{
Description = "JWT Authorization header using the Bearer scheme. Example: \"Bearer {token}\"",
Name = "Authorization",
In = "header",
Type = "apiKey"
});
//options.AddSecurityDefinition("oauth2", new OAuth2Scheme
//{
// Flow = "implicit",
// AuthorizationUrl = $"{authority}/connect/authorize",
// Scopes = scopes ?? new Dictionary<string, string>()
//});
options.OperationFilter<AuthorizeCheckOperationFilter>(scopes?.Select(_ => _.Key).ToList() ?? new List<string>());
}
});
}
class AuthorizeCheckOperationFilter : IOperationFilter
{
private readonly IEnumerable<string> _scopes;
public AuthorizeCheckOperationFilter(IEnumerable<string> scopes)
{
_scopes = scopes;
}
public void Apply(Operation operation, OperationFilterContext context)
{
var hasAuthorize = context.ApiDescription.ControllerAttributes().OfType<AuthorizeAttribute>().Any() ||
context.ApiDescription.ActionAttributes().OfType<AuthorizeAttribute>().Any();
if (hasAuthorize)
{
operation.Responses.Add("401", new Response { Description = "Unauthorized" });
operation.Responses.Add("403", new Response { Description = "Forbidden" });
operation.Security = new List<IDictionary<string, IEnumerable<string>>> {
new Dictionary<string, IEnumerable<string>>
{
//{"oauth2", _scopes},
{"jwt", _scopes }
}
};
}
}
}
}
用法:
services.AddMySwagger(
new ApiVersion(1, 0),
__description => new Info { Title = $"API v{__description.ApiVersion}", Version = __description.ApiVersion.ToString() },
Configuration.GetValue<string>("Authentication:Authority"),
new Dictionary<string, string> { { Configuration.GetValue<string>("Authentication:Scope"), "Partnership API" } }
);
https://stackoverflow.com/questions/48985240
复制相似问题