Как показать конечную точку токена WebApi OAuth в Swagger

Я создал новый проект Web Api, добавил Asp.Net Identity и настроил OAuth так:

OAuthOptions = new OAuthAuthorizationServerOptions
{
    TokenEndpointPath = new PathString("/Token"),
    Provider = new ApplicationOAuthProvider(PublicClientId),
    AuthorizeEndpointPath = new PathString("/api/Account/ExternalLogin"),
    AccessTokenExpireTimeSpan = TimeSpan.FromDays(14),
    AllowInsecureHttp = true
};

Все работает отлично, я могу вызвать конечную точку /Token и вернуть токен-носитель.

Проблема заключается в том, что это невозможно обнаружить в Swagger. Я предполагаю, что он не на контроллере и поэтому не имеет XML-документации, сгенерированной для него.

Кто-нибудь знает способ отображения этой конечной точки входа в моих документах Swagger?

Спасибо.

Кроме того, я должен был сказать, что документация Swagger работает со всеми моими контроллерами, просто я пропустил этот один очевидный метод - как войти в систему.

Ответ 1

ApiExplorer не будет автоматически генерировать любую информацию для вашей конечной точки, поэтому вам нужно будет добавить собственный DocumentFilter, чтобы вручную описать конечную точку маркера.

Вот пример этого в https://github.com/domaindrivendev/Swashbuckle/issues/332:

class AuthTokenOperation : IDocumentFilter
{
    public void Apply(SwaggerDocument swaggerDoc, SchemaRegistry schemaRegistry, IApiExplorer apiExplorer)
    {
        swaggerDoc.paths.Add("/auth/token", new PathItem
        {
            post = new Operation
            {
                tags = new List<string> { "Auth" },
                consumes = new List<string>
                {
                    "application/x-www-form-urlencoded"
                },
                parameters = new List<Parameter> {
                    new Parameter
                    {
                        type = "string",
                        name = "grant_type",
                        required = true,
                        @in = "formData"
                    },
                    new Parameter
                    {
                        type = "string",
                        name = "username",
                        required = false,
                        @in = "formData"
                    },
                    new Parameter
                    {
                        type = "string",
                        name = "password",
                        required = false,
                        @in = "formData"
                    }
                }
            }
        });
    }
}

httpConfig.EnableSwagger(c =>
{
    c.DocumentFilter<AuthTokenOperation>();
});

Ответ 2

Если кто-то интересуется, как добавить тело ответа к этой операции, здесь обновлен код Ruaidhri:

class AuthTokenOperation : IDocumentFilter
{
    public void Apply(SwaggerDocument swaggerDoc, SchemaRegistry schemaRegistry, IApiExplorer apiExplorer)
    {
        swaggerDoc.paths.Add("/token", new PathItem
        {
            post = new Operation
            {
                tags = new List<string> { "Auth" },
                consumes = new List<string>
                    {
                        "application/x-www-form-urlencoded"
                    },
                parameters = new List<Parameter> {
                    new Parameter
                    {
                        type = "string",
                        name = "grant_type",
                        required = true,
                        @in = "formData"
                    },
                    new Parameter
                    {
                        type = "string",
                        name = "username",
                        required = false,
                        @in = "formData"
                    },
                    new Parameter
                    {
                        type = "string",
                        name = "password",
                        required = false,
                        @in = "formData"
                    }
                },
                responses = new Dictionary<string, Response>()
                {
                    {
                        "200",
                        new Response {schema = schemaRegistry.GetOrRegister(typeof(OAuthTokenResponse))}
                    }
                }
            }
        });
    }
}

class OAuthTokenResponse
{
    [JsonProperty("access_token")]
    public string AccessToken { get; set; }

    [JsonProperty("token_type")]
    public string TokenType { get; set; }

    [JsonProperty("expires_in")]
    public long ExpiresIn { get; set; }

    [JsonProperty("userName")]
    public string Username { get; set; }

    [JsonProperty(".issued")]
    public DateTime Issued { get; set; }

    [JsonProperty(".expires")]
    public DateTime Expires { get; set; }
}