Swagger 授权承载不发送
Swagger Authorization bearer not send
我在 dotnet core 3.1 web api 项目中使用 Swagger Swashbuckle,但无法向请求调用发送不记名授权。
我在我的 ConfigureServices
方法中定义了这个:
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo() { Title = "MyApi", Version = "v1" });
// Set the comments path for the Swagger JSON and UI.
var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
c.IncludeXmlComments(xmlPath);
c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
{
Type = SecuritySchemeType.OAuth2,
Flows = new OpenApiOAuthFlows()
{
Password = new OpenApiOAuthFlow()
{
TokenUrl = new Uri("/api/Account/Login", UriKind.Relative),
}
},
In = ParameterLocation.Header,
Name = "Authorization",
Scheme = "Bearer",
});
c.AddSecurityRequirement(new OpenApiSecurityRequirement()
{
{
new OpenApiSecurityScheme()
{
Reference = new OpenApiReference()
{
Type = ReferenceType.SecurityScheme,
Id = "Bearer"
},
Scheme = "Bearer",
Type = SecuritySchemeType.Http,
Name = "Bearer",
In = ParameterLocation.Header
}, new List<string>()
}
});
});
当 运行 时,我看到显示登录对话框的授权按钮:
登录后,API 路由显示锁定的挂锁,但当我尝试使用它们时,我看到调用已完成,但没有返回承载:
curl -X GET "http://localhost:5000/api/Account" -H "accept: */*" -H "Authorization: Bearer undefined"
我的定义有什么问题?
在 cURL 请求中您可以看到:-H“授权:承载未定义”。
这意味着当 Swagger-UI 尝试获取将添加到请求 header 的令牌时,找不到它。
那么,令牌是从哪里来的,为什么Swagger-UI找不到呢?该令牌来自您的登录端点 (json returned (/api/Account/Login)。
您必须确保从您的登录端点 returned json 符合 OAuth 密码流的预期格式,如 RFC6749 第 4.1.4 节中所述(访问令牌响应)。
您必须从您的登录端点 return 一个 json 响应,如下所示:
{
"access_token":"2YotnFZFEjr1zCsicMWpAA",
"token_type":"bearer"
}
这是一个常见的错误,当您序列化来自控制器的响应时,您不尊重 json 属性 名称。例如:您可以像这样 returning json:
{
"accessToken":"2YotnFZFEjr1zCsicMWpAA",
"tokenType":"bearer"
}
其中“accessToken”与“access_token”等不同。
这个小小的差异导致 Swagger-UI 在反序列化 returned json.
时找不到不记名令牌
提示:修饰您的响应的“AccessToken”属性 object,以便正确序列化。
[JsonPropertyName("access_token")]
[JsonProperty(PropertyName = "access_token")]
public string AccessToken { get; set; }
虽然解释的是你问题的重点,但我想告诉你,全局添加安全要求并不是最正确的做法。通过这种方式,您可以保护所有端点,无论它们是否装饰有 Authorize 属性。
在启动时,您只需设置一个“安全定义”,并添加一个处理“安全要求”的“OperationFilter”。然后“SecurityRequirement”引用“SecurityDefinition”,那么您就不会像您在示例中所做的那样在安全要求中重复安全定义配置(Scheme、Type、Name、In 等)。
请参阅 this github post 以了解正确的操作方法。
我在 dotnet core 3.1 web api 项目中使用 Swagger Swashbuckle,但无法向请求调用发送不记名授权。
我在我的 ConfigureServices
方法中定义了这个:
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo() { Title = "MyApi", Version = "v1" });
// Set the comments path for the Swagger JSON and UI.
var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
c.IncludeXmlComments(xmlPath);
c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
{
Type = SecuritySchemeType.OAuth2,
Flows = new OpenApiOAuthFlows()
{
Password = new OpenApiOAuthFlow()
{
TokenUrl = new Uri("/api/Account/Login", UriKind.Relative),
}
},
In = ParameterLocation.Header,
Name = "Authorization",
Scheme = "Bearer",
});
c.AddSecurityRequirement(new OpenApiSecurityRequirement()
{
{
new OpenApiSecurityScheme()
{
Reference = new OpenApiReference()
{
Type = ReferenceType.SecurityScheme,
Id = "Bearer"
},
Scheme = "Bearer",
Type = SecuritySchemeType.Http,
Name = "Bearer",
In = ParameterLocation.Header
}, new List<string>()
}
});
});
当 运行 时,我看到显示登录对话框的授权按钮:
登录后,API 路由显示锁定的挂锁,但当我尝试使用它们时,我看到调用已完成,但没有返回承载:
curl -X GET "http://localhost:5000/api/Account" -H "accept: */*" -H "Authorization: Bearer undefined"
我的定义有什么问题?
在 cURL 请求中您可以看到:-H“授权:承载未定义”。 这意味着当 Swagger-UI 尝试获取将添加到请求 header 的令牌时,找不到它。
那么,令牌是从哪里来的,为什么Swagger-UI找不到呢?该令牌来自您的登录端点 (json returned (/api/Account/Login)。
您必须确保从您的登录端点 returned json 符合 OAuth 密码流的预期格式,如 RFC6749 第 4.1.4 节中所述(访问令牌响应)。
您必须从您的登录端点 return 一个 json 响应,如下所示:
{
"access_token":"2YotnFZFEjr1zCsicMWpAA",
"token_type":"bearer"
}
这是一个常见的错误,当您序列化来自控制器的响应时,您不尊重 json 属性 名称。例如:您可以像这样 returning json:
{
"accessToken":"2YotnFZFEjr1zCsicMWpAA",
"tokenType":"bearer"
}
其中“accessToken”与“access_token”等不同。
这个小小的差异导致 Swagger-UI 在反序列化 returned json.
时找不到不记名令牌提示:修饰您的响应的“AccessToken”属性 object,以便正确序列化。
[JsonPropertyName("access_token")]
[JsonProperty(PropertyName = "access_token")]
public string AccessToken { get; set; }
虽然解释的是你问题的重点,但我想告诉你,全局添加安全要求并不是最正确的做法。通过这种方式,您可以保护所有端点,无论它们是否装饰有 Authorize 属性。
在启动时,您只需设置一个“安全定义”,并添加一个处理“安全要求”的“OperationFilter”。然后“SecurityRequirement”引用“SecurityDefinition”,那么您就不会像您在示例中所做的那样在安全要求中重复安全定义配置(Scheme、Type、Name、In 等)。
请参阅 this github post 以了解正确的操作方法。