[Swagger] 使用 OAuth2 - Resource Owner Password / Implicit flow 測試受保護的 Web API

OAuth2 是目前大廠都有支援的一種授權機制, Swagger 也有支援,我將使用  Resource Owner Password / Implicit flow + Identity Framework 來進行演練。

開發環境

  • VS 2017 Enterprise 15.9.5
  • Swashbuckle 5.6.0

實作步驟

這裡需要一個 OAuth Server,所以這次的範本用這個並且給予授權,這個範本會幫我們建立 OAuth Server

安裝

Install-Package Swashbuckle

@SwaggerConfig.cs

套用 Filter

c.OperationFilter<OAuth2OperationFilter>();

指定 Grant Flow

c.OAuth2("oauth2")
    .Description("OAuth2 password Grant")
    .Flow("password")
    .TokenUrl("http://localhost:58310/token")
    ;

有關 Swagger OAuth 請參考

https://swagger.io/docs/specification/authentication/oauth2/

 

Filter 指定授權方式

public class OAuth2OperationFilter : 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>>
            {
                {"oauth2"Enumerable.Empty<string>()}
            };
 
            operation.security.Add(auth);
 
        }
    }
}

 

@ApplicationOAuthProvider.cs

這個範例我不用 Client 驗證,所以讓它通過驗證

public override Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
{
     context.Validated(this._publicClientId);
     return Task.FromResult<object>(null);
}

 

完成之後需要授權的 API 就會有紅色驚嘆號,但帳號密碼哪裡來?

建立帳號

這個專案範本用到了 Identity Framework,為了能順利測試 Swagger ,得先建立帳號,成功之後再去訪問需要授權的方法

通過授權之後紅色就變藍色了

同場加映 implicit flow

@SwaggerConfig.cs

Swagger UI 打 ClientId 進去

GlobalConfiguration.Configuration
    .EnableSwagger(=>
        {
            c.OperationFilter<OAuth2OperationFilter>();
            c.SingleApiVersion("v1""Server");
            //https://swagger.io/docs/specification/authentication/oauth2/
            c.OAuth2("oauth2")
                .Description("OAuth2 password Grant")
                .Flow("implicit")
                .TokenUrl("http://localhost:58310/token")
                .AuthorizationUrl("http://localhost:58310/authorize")
                ;
        })
    .EnableSwaggerUi(=>
        {
            c.EnableOAuth2Support(
                clientId: "self",
                clientSecret: null,
                realm: "test-realm",
                appName: "Swagger UI"
            );
      
        });

@ApplicationOAuthProvider.cs

加上授權的 EndPoint

public override Task AuthorizeEndpoint(OAuthAuthorizeEndpointContext context)
{
    if (context.AuthorizeRequest.IsImplicitGrantType)
    {
        //implicit 授權方式
        var identity = new ClaimsIdentity("Bearer");
        context.OwinContext.Authentication.SignIn(identity);
        context.RequestCompleted();
    }
 
    return Task.FromResult<object>(null);
}

 

用 Implicit 就不用按帳號密碼了

你應該針對你的需求嚴格把關Client Id,不要照抄唷

 

利用 Fidder 可以觀察到,Swagger UI 用 /swagger/ui/o2c-html 來接收 Token

範例位置
https://github.com/yaochangyu/sample.dotblog/tree/master/WebAPI/Swagger/OAuth2

 

若有謬誤,煩請告知,新手發帖請多包涵


Microsoft MVP Award 2010~2017 C# 第四季
Microsoft MVP Award 2018~2022 .NET

Image result for microsoft+mvp+logo