[Swagger] 使用 Basic Auth 測試受保護的 Web API

通常 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 拿到之後再去後端確認

  1. 採用 Base64編碼
  2. 格式:name:password
  3. 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<stringstring> 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);
    }
}

完整代碼如下:
https://github.com/yaochangyu/sample.dotblog/blob/master/WebAPI/Swagger/Baisc%20Authorization/Server/BasicAuthorizeAttribute.cs

這裡就是取得哪些 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<stringIEnumerable<string>>>();
            }
 
            var auth = new Dictionary<stringIEnumerable<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

Image result for microsoft+mvp+logo