Маркер Swagger Azure AD OAuth2 не используется - PullRequest
0 голосов
/ 08 июня 2018

Я пытаюсь использовать AzureAD, чтобы получить токен в swagger и протестировать с ним мои контроллеры.

Здесь я регистрируюсь с помощью swagger-ui:

enter image description here

И только после этого без использования моего личного идентификатора AzureAD, я уже вошел в систему.

Но когда я пытаюсь использовать свои контроллеры, у меня появляется ошибка: Unauthorized

Все мои контроллеры наследуются от baseController.Все они имеют аннотацию [Authorize].

Я действительно не знаю, в чем проблема.Я использую Swashbuckle.AspNetCore v2.5.0

Некоторый конфигурационный код.

Statup.cs

public virtual void ConfigureServices(IServiceCollection services)
{

    services
            .AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
            .AddJwtBearer(options =>
            {
                options.Audience = "{client_id}";
                options.Authority = "https://login.microsoftonline.com/{tenant_id}";
            });
    services.AddSwaggerGen(options =>
    {
        options.SwaggerDoc("v2", new Info
        {
            Title = "API",
            Version = "v2",
            Description = "Api Help",
            Contact = new Contact()
            {
                Name = "John Doe",
                Email = "john.doe@somewhere.com"
            }
        });
        var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
        var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
        options.IncludeXmlComments(xmlPath);

        options.AddSecurityDefinition("OAuth2", new OAuth2Scheme()
        {
            Flow = "implicit",
            Type = "oauth2",
            TokenUrl = "https://login.microsoftonline.com/{tenant_id}/oauth2/token",
            Description = "OAuth2 Implicit Grant",
            AuthorizationUrl = "https://login.microsoftonline.com/{tenant_id}/oauth2/authorize",
            Scopes = new Dictionary<string, string>()
            {
                { "user_impersonation", "Access api" }
            }
        });

        options.OperationFilter<FileOperation>();
        options.DescribeAllEnumsAsStrings();
    });
}

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    app.UseMiddleware<ExceptionHandlerMiddleware>();

    // Enable middleware to serve generated Swagger as a JSON endpoint.
    app.UseSwagger();

    // Enable middleware to serve swagger-ui (HTML, JS, CSS etc.), specifying the Swagger JSON endpoint.
    app.UseSwaggerUI(c =>
    {
        c.SwaggerEndpoint("../swagger/v2/swagger.json", "API V2");
        c.RoutePrefix = "Help";
        c.OAuthClientId("{client_id_swagger_app}"); //Swagger
        //c.OAuthClientId("client_id_api_app"); //api
        c.DisplayRequestDuration();
        c.OAuthClientSecret("{secret_client_key_swagger}"); //swagger secret
        c.OAuthAppName("Swagger");
        c.OAuthRealm("http://localhost:1234/swagger/ui/o2c-html");
        c.OAuthScopeSeparator(" ");
        c.OAuthUseBasicAuthenticationWithAccessCodeGrant();
        c.OAuthAdditionalQueryStringParams(new Dictionary<string, string>
        {
            { "resource", "{app_ID_URI}"} //api
        });
    });

    app.UseAuthentication();
    app.UseMvc();
}

1 Ответ

0 голосов
/ 11 июня 2018

Вы настроили Swagger UI для получения токена доступа с ресурсом:

c.OAuthAdditionalQueryStringParams(new Dictionary<string, string>
    {
        { "resource", "{app_ID_URI}"} //api
    });

Но вы настроили свою действительную аудиторию как:

options.Audience = "{client_id}";

Swagger UI, используя идентификатор приложенияС URI все в порядке, и вместо этого вы можете настроить свой API на прием идентификатора клиента и URI в качестве аудитории (Azure AD позволяет использовать и то и другое, так почему бы не настроить свой API как таковой?):

options.TokenValidationParameters = new TokenValidationParameters
{
    ValidAudiences = new List<string>{ "client-id", "app-id-uri"}
};

выше должно идти в вашем обратном вызове конфигурации AddJwtBearer, и вы можете удалить строку options.Audience =.

Чтобы указать области, необходимые для действия, вам нужно добавить фильтр операций внутри services.AddSwaggerGen(options =>{}):

options.OperationFilter<AuthenticationOperationFilter>();

И определите фильтр, для которого требуется область действия OAuth для каждого действия:

public class AuthenticationOperationFilter : IOperationFilter
{
    public void Apply(Operation operation, OperationFilterContext context)
    {
        operation.Security = new List<IDictionary<string, IEnumerable<string>>>
        {
            new Dictionary<string, IEnumerable<string>>
            {
                //Note "OAuth2" casing here must match the definition you use in Swagger UI config
                ["OAuth2"] = new List<string>{ "user_impersonation" }
            }
        };
    }
}

То, что вы определили в конфигурации пользовательского интерфейса Swagger, определяет области, которые пользователь может выбрать при использовании пользовательского интерфейса.Помните, что поскольку вы используете конечные точки Azure AD v1, выбранные вами области не будут иметь значения.Маркер всегда будет содержать согласованные области действия, ни больше, ни меньше.

...