97 lines
3.2 KiB
C#
97 lines
3.2 KiB
C#
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接口基础认证
|
|
/// <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) {
|
|
if(this.Options == null) {
|
|
await ToNext(context);
|
|
return;
|
|
}
|
|
if(!this.Options.UseAuth) {
|
|
await ToNext(context);
|
|
return;
|
|
}
|
|
var protectPaths = new List<string> { };
|
|
var pf = this.Options.Prefix.StartsWith("/") ? this.Options.Prefix : "/" + this.Options.Prefix;
|
|
protectPaths.Add(pf);
|
|
protectPaths.Add(pf + "/index.html");
|
|
if(!protectPaths.Contains(context.Request.Path)) {
|
|
await ToNext(context);
|
|
return;
|
|
}
|
|
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;
|
|
}
|
|
|
|
}
|
|
}
|