1 原理说明
在后端编程时,通常使用swagger文档来呈现接口文档。为了接口的安全性,可通过输入用户名和密码的方式来进行验证。
这里用到了Basic认证方式。原理图如下:
- 步骤 1: 当请求的资源需要 B A S I C \textcolor{red}{BASIC} BASIC 认证时,服务器会随状态码 401 \textcolor{red}{401} 401 Authorization Required,返回带 WWW-Authenticate 首部字段的响应。
- 步骤 2: 接收到状态码 401 的客户端为了通过 BASIC 认证,需要将用户 ID 及密码发送给服务器。发送的字符串内容是由用户 ID 和密码构成,两者中间以冒号(:)连接后,再经 B a s e 64 \textcolor{red}{Base64 } Base64 编码处理。 后把这串字符串写入首部字段 Authorization 后发送请求。
- 步骤 3: 接收到包含首部字段 Authorization 请求的服务器,会对认证信息的正确性进行验证。
2 代码实现
2.1 自定义验证中间件
public class SwaggerBasicAuthMiddleware
{
private readonly RequestDelegate next;
//服务器端定义用户名和密码
private readonly string UserName="swagger";
private readonly string Password = "swagger";
public SwaggerBasicAuthMiddleware(RequestDelegate next)
{
this.next = next;
}
public async Task InvokeAsync(HttpContext context)
{
if (context.Request.Path.StartsWithSegments("/swagger"))
{
string authHeader = context.Request.Headers["Authorization"];
if (authHeader != null && authHeader.StartsWith("Basic"))
{
// Get the credentials from request header
var header = AuthenticationHeaderValue.Parse(authHeader);
var inBytes = Convert.FromBase64String(header.Parameter);
var credentials = Encoding.UTF8.GetString(inBytes).Split(':');
var username = credentials[0];
var password = credentials[1];
// validate credentials
if (username.Equals(UserName) && password.Equals(Password))
{
await next.Invoke(context).ConfigureAwait(false);
return;
}
}
//告知服务器端需要进行Basic认证
context.Response.Headers["WWW-Authenticate"] = "Basic";
context.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
}
else
{
await next.Invoke(context).ConfigureAwait(false);
}
}
}
/// <summary>
/// 中间件拓展类
/// </summary>
public static class MiddlerwareExtention
{
public static IApplicationBuilder UseSwaggerBasicAuth(this IApplicationBuilder app) {
return app.UseMiddleware<SwaggerBasicAuthMiddleware>();
}
}
2.2 请求管道中增加授权中间件
本文章忽略Swagger和NetCore的整合,仅提供关键步骤的代码段。
app.UseSwaggerBasicAuth();
app.UseSwagger();
app.UseSwaggerUI(options => {
//忽略ui配置
});
3 总结
通过Basic认证,实现了在访问swagger接口文档前需要输入用户名和密码信息进行验证。在一定程度上保证了接口访问的安全性。但由于该认证方式的局限性(认证信息仅经过Base64 编码,未做任何的加密处理,明文解码后容易被人盗取,再进行一次 BASIC 认证时,一般的浏览器无法实现认证注销操作),大家可以采取更安全的方式来处理这个功能的实现。