通常 API 都會經過保護, 當 API 需要授權才能使用時,Swagger 就需要做一些調整才能正常的調用,設定好 Basic Auth 就會有驗證對話視窗
來看看怎麼完成的吧
開發環境
- VS 2017 Enterprise 15.9.5
- Swashbuckle 5.6.0
實作步驟
自訂 Header
上一篇,[Swagger] 在 Swagger UI 新增自訂 Header,知道了怎麼在 Swagger 自訂 Header,可以在 IOperationFilter 裡面加入 Authorization 的 Header
operation.parameters.Add(new Parameter { name = "Authorization", @in = "header", // specify that the value will be sent in the header description = "Basic U3dhZ2dlcjpUZXN0", // Basic Swagger:Test required = true, // parameter required type = "string" });
運行結果
這樣一來就能從 Swagger 帶入授權,不過,每一個有授權的 API 都來這麼一下,也挺累人的,接下來介紹 Swagger 預設支援的授權
BasicAuth
@ SwaggerRegister.cs
這一段寫著要實作 IDocumentFilter and/or IOperationFilter
// You can use "BasicAuth", "ApiKey" or "OAuth2" options to describe security schemes for the API. // See https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md for more details. // NOTE: These only define the schemes and need to be coupled with a corresponding "security" property // at the document or operation level to indicate which schemes are required for an operation. To do this, // you'll need to implement a custom IDocumentFilter and/or IOperationFilter to set these properties // according to your specific authorization implementation // c.OperationFilter<SwaggerAuthorizeOperationFilter>(); c.BasicAuth("basic").Description("Basic HTTP Authentication")
@ WebApiConfig.cs
加入 basic 授權
config.Filters.Add(new BasicAuthorizeAttribute());
甚麼是 basic 授權,簡單來講就是把帳號跟密碼,用 base64 編碼傳給 Server,Server 拿到之後再去後端確認
- 採用 Base64編碼
- 格式:name:password
- Header Authorization: Basic Base64(name:password)
@ BasicAuthorizeAttribute.cs
public class BasicAuthorizeAttribute : AuthorizeAttribute { public override async Task OnAuthorizationAsync(HttpActionContext actionContext, CancellationToken cancellationToken) { var authorization = actionContext.Request.Headers.Authorization; if (authorization != null && authorization.Scheme.ToLower() == "basic") { //base64 decode Tuple<string, string> userNameAndPasword = DecodeBase64(authorization.Parameter); string userName = userNameAndPasword.Item1; string password = userNameAndPasword.Item2; //check user at database IPrincipal principal = await this.AuthenticateAsync(userName, password, cancellationToken); if (principal != null) { Thread.CurrentPrincipal = principal; if (HttpContext.Current != null) { HttpContext.Current.User = principal; } actionContext.Request.GetRequestContext().Principal = principal; } } await base.OnAuthorizationAsync(actionContext, cancellationToken); } }
這裡就是取得哪些 action 需要授權,需要的就加上紅色驚嘆號
public class SwaggerAuthorizeOperationFilter : IOperationFilter { public void Apply(Operation operation, SchemaRegistry schemaRegistry, ApiDescription apiDescription) { var filterPipeline = apiDescription.ActionDescriptor.GetFilterPipeline(); // check if authorization is required var isAuthorized = filterPipeline .Select(filterInfo => filterInfo.Instance) .Any(filter => filter is IAuthorizationFilter); // check if anonymous access is allowed var allowAnonymous = apiDescription.ActionDescriptor.GetCustomAttributes<AllowAnonymousAttribute>().Any(); if (isAuthorized && !allowAnonymous) { if (operation.security == null) { operation.security = new List<IDictionary<string, IEnumerable<string>>>(); } var auth = new Dictionary<string, IEnumerable<string>> { {"basic", Enumerable.Empty<string>()} }; operation.security.Add(auth); } } }
需要授權的 API,就會多一個紅色驚嘆號的圖示,只要任何一個 API 有輸入過就可以
藍色驚嘆號代表已經有輸入過授權了,Logout 用來切換授權
Swagger UI 不會幫你驗證授權唷,還是必須要回到 BasicAuthorizeAttribute 裡面來驗證
專案位置
https://github.com/yaochangyu/sample.dotblog/tree/master/WebAPI/Swagger/Baisc%20Authorization
若有謬誤,煩請告知,新手發帖請多包涵
Microsoft MVP Award 2010~2017 C# 第四季
Microsoft MVP Award 2018~2022 .NET