一般使用Swagger 都是開放式閱讀API文件,但有些特殊情況,並不想受任何人都可以閱讀API文件
所以需要增加登入驗證,才給予授權訪問該文件
環境
- VS2022
- Net 6
- WebApi專案
方向
- 製作登入
- 使用ClaimsIdentity存放Cookies
- 檢查是否有權限訪問SwaggerUI,無則導向登入
步驟
Program中修改
builder.Services.AddControllers
為
builder.Services.AddControllersWithViews();
新增LoginController並在該Class上加入
[Route("[controller]")]
[ApiExplorerSettings(IgnoreApi = true)]
[Route("[controller]")]
[ApiExplorerSettings(IgnoreApi = true)]
public class LoginController : Controller
{
public IActionResult Index()
{
var dd = HttpContext;
return View(new ViewModels.Index());
}
/// <summary>
/// 登入POST
/// </summary>
/// <returns></returns>
[HttpPost]
public async Task<IActionResult> Index(ViewModels.Index model)
{
var claims = new List<Claim>
{
new Claim("Authorized", model.Account!),
};
var claimsIdentity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(claimsIdentity),
new AuthenticationProperties()
{
IsPersistent = true,
ExpiresUtc = DateTimeOffset.UtcNow.AddMinutes(30),
AllowRefresh = true
});
return Redirect("/swagger");
}
}
建立ViewModel
public class Index
{
[Required(ErrorMessage = "帳號未填寫")]
public string? Account { get; set; }
[Required(ErrorMessage = "密碼未填寫")]
public string? Password { get; set; }
}
建立View
<html lang="zh-TW">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>登入</title>
</head>
<body >
<form action="Login" method="post">
<input Id="Account" name="Account" type="text" placeholder="Account">
<input Id="Password" name="Password" type="password" placeholder="Password">
<button type="submit">
<span>登入</span>
</button>
</form>
</body>
</html>
Program中增加
builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme).AddCookie(option =>
{
option.LoginPath = new PathString("/Login/Index");
option.LogoutPath = new PathString("/Login/Index");
option.AccessDeniedPath = new PathString("/Login/Index");
option.ExpireTimeSpan = TimeSpan.FromMinutes(30);
option.Cookie.HttpOnly = true;
});
app.UseAuthentication();
建立SwaggerInterceptor 檢查訪問權限
public class SwaggerInterceptor
{
private readonly RequestDelegate _next;
public SwaggerInterceptor(RequestDelegate next)
{
_next = next;
}
public async Task Invoke(HttpContext context)
{
var uri = context.Request.Path.ToString().ToUpper();
if (uri.StartsWith("/swagger".ToUpper()))
{
var role = context.User.Claims.FirstOrDefault(x => x.Type == "Authorized")?.Value;
if (role == null || role == null)
{
context.Response.Redirect("/Login");
return;
}
}
await _next.Invoke(context);
}
}
Program中增加UseMiddleware
注意需擺在UseAuthentication下方,UseSwagger上方,執行順序問題
app.UseAuthentication();
app.UseMiddleware<SwaggerInterceptor>();
app.UseSwagger();
app.UseSwaggerUI();
建立完成後會看到系統導向登入而非預設的SwaggerUI
登入成功後才可進入SwaggerUI
資料參考來源