Falcon.SugarApi/Falcon.SugarApi/Swagger/SwaggerBasicAuthMiddleware.cs

97 lines
3.2 KiB
C#
Raw Normal View History

using Microsoft.AspNetCore.Http;
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
namespace Falcon.SugarApi.Swagger
{
/// <summary>
/// Swagger接口基础认证
2024-04-19 14:00:38 +08:00
/// <para>安全认证只对swagger接口页面进行保护</para>
/// </summary>
public class SwaggerBasicAuthMiddleware
{
/// <summary>
/// 下一步请求
/// </summary>
private readonly RequestDelegate Next;
/// <summary>
/// 配置
/// </summary>
public SwaggerOptions Options { get; private set; }
/// <summary>
/// 构造中间件
/// </summary>
/// <param name="next">下一步</param>
/// <param name="options">配置</param>
public SwaggerBasicAuthMiddleware(RequestDelegate next,SwaggerOptions options) {
Next = next;
this.Options = options;
}
/// <summary>
/// 执行中间件
/// </summary>
/// <param name="context">HttpContext</param>
/// <returns>任务</returns>
public virtual async Task InvokeAsync(HttpContext context) {
2024-04-17 14:04:24 +08:00
if(this.Options == null) {
await ToNext(context);
return;
}
if(!this.Options.UseAuth) {
await ToNext(context);
return;
}
2024-04-19 14:00:38 +08:00
var protectPaths = new List<string> { };
var pf = this.Options.Prefix.StartsWith("/") ? this.Options.Prefix : "/" + this.Options.Prefix;
2024-04-19 14:00:38 +08:00
protectPaths.Add(pf);
protectPaths.Add(pf + "/index.html");
if(!protectPaths.Contains(context.Request.Path)) {
await ToNext(context);
return;
}
2024-04-19 14:00:38 +08:00
string? authHeader = context.Request.Headers["Authorization"];
if(authHeader == null || !authHeader.StartsWith("Basic ")) {
needAuth(context);
return;
}
var header = AuthenticationHeaderValue.Parse(authHeader);
if(header == null || header.Parameter == null) {
needAuth(context);
return;
}
var inBs = Convert.FromBase64String(header.Parameter);
var cred = Encoding.UTF8.GetString(inBs).Split(':');
var (un, pw) = (cred[0], cred[1]);
//var un = cred[0];
//var pw = cred[1];
if(un == this.Options.AuthName && pw == this.Options.AuthPassword) {
await ToNext(context);
return;
}
needAuth(context);
}
/// <summary>
/// 进入下一个中间件
/// </summary>
public virtual async Task ToNext(HttpContext context) {
await Next.Invoke(context).ConfigureAwait(false);
return;
}
/// <summary>
/// 需要认证
/// </summary>
public virtual void needAuth(HttpContext context) {
context.Response.Headers["WWW-Authenticate"] = "Basic";
context.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
}
}
}