Как настроить Swashbuckle.AspNetCore и Oauth2 - PullRequest
0 голосов
/ 04 июля 2019

Я пытаюсь выяснить, где я ошибся.

services.AddSwaggerGen(options =>
{
    options.SwaggerDoc("v1", new Info { Title = "MySite API", Version = "v1" });
    options.OperationFilter<AuthorizeCheckOperationFilter>();
    options.OperationFilter<AddSwaggerHeadersOperationFilter>();
    options.AddSecurityDefinition("oauth2", new OAuth2Scheme
    {
        Type = "oauth2",
        Flow = "implicit",
        AuthorizationUrl = "authorization url",
        TokenUrl = "token url",
        Scopes = new Dictionary<string, string>()
        {
            { "scope", "Scope" }
        }
    });
});


//Configure Method
app.UseSwagger();

app.UseSwaggerUI(options =>
{
    options.SwaggerEndpoint("/swagger/v1/swagger.json", "MySite API V1");
    options.OAuthClientId("MyClientId");
    options.OAuthAppName("Swagger Api Calls");
    //c.RoutePrefix = string.Empty;
});

//AuthorizeCheckOperationFilter
internal class AuthorizeCheckOperationFilter : IOperationFilter
{
    public void Apply(Operation operation, OperationFilterContext context)
    {
        if (context.ApiDescription.TryGetMethodInfo(out var methodInfo))
        {
            var attributes = methodInfo.DeclaringType.GetTypeInfo().GetCustomAttributes(true);
            if (attributes.OfType<AuthorizeAttribute>().Any())
            {
                operation.Responses.Add("401", new Response { Description = "Unauthorized" });
                operation.Responses.Add("403", new Response { Description = "Forbidden" });

                operation.Security = new List<IDictionary<string, IEnumerable<string>>>();
                operation.Security.Add(new Dictionary<string, IEnumerable<string>>
                {
                    { "oauth2", new [] { "api1" } }
                });
            }
        }
    }
}

//Extra field
internal class AddSwaggerHeadersOperationFilter : IOperationFilter
{
    public void Apply(Operation operation, OperationFilterContext context)
    {
        if (operation.Parameters == null)
            operation.Parameters = new List<IParameter>();

        operation.Parameters.Add(new NonBodyParameter
        {
            Name = "SomeField",
            In = "header",
            Type = "string",
            Required = true,
            Default = "some value"
        });
    }
}

Теперь, когда я открываю свагерскую страницу, я получаю кнопку Авторизоваться, на которую я нажимаю, и когда я там заполняю деталиЯ перенаправлен на мой веб-сайт Identity, который регистрирует меня и перенаправляет обратно на swagger.Затем Swagger говорит санкционировано, как будто все в порядке.

Затем я пытаюсь использовать API, который требует передачи токена Bearer, но не передает его.Я не вижу его в шапке, и по моим логам с сайта идентичности ничего не пропущено.

Есть идеи, почему или как это исправить?Я использую пакет Swashbuckle.AspNetCore 4.1.

1 Ответ

1 голос
/ 05 июля 2019

Вы можете добавить DocumentFilter:

public class SecurityRequirementsDocumentFilter : IDocumentFilter
{
    public void Apply(SwaggerDocument document, DocumentFilterContext context)
    {
        document.Security = new List<IDictionary<string, IEnumerable<string>>>()
        {
            new Dictionary<string, IEnumerable<string>>()
            {
                { "oauth2", new string[]{ "openid", "profile", "email" } },
            }
        };
    }
}

, а затем зарегистрировать фильтр в функции AddSwaggerGen:

options.DocumentFilter<SecurityRequirementsDocumentFilter>();

Ссылка: https://github.com/domaindrivendev/Swashbuckle.AspNetCore/issues/603#issuecomment-368487641

Я тестирую с вашим примером кода, и он работает как ожидалось:

enter image description here

...