Identityserver4 API-аутентификация не работает должным образом - PullRequest
0 голосов
/ 26 мая 2018

Я застрял с этой проблемой почти месяц, поэтому любая помощь приветствуется.Давайте перейдем к самой проблеме: у меня есть сервер идентификации и API управления пользователями (на основе CRUD) в одном проекте.Сам сервер идентификации работает как страница входа / регистрации для других веб-сайтов (в настоящее время у меня есть только один веб-сайт MVC ASP.NET Framework).API используется для извлечения и обновления профиля пользователя из проекта MVC и мобильного приложения.Сервер идентификации и проект MVC поддерживаются док-контейнерами.

Аутентификация API выполняется через маркер канала идентификации сервера.Таким образом, аутентификация API отлично работает на локальном хосте, однако, когда я развертываю сервер идентификации на экземплярах контейнеров Azure, API перестает работать как из MVC, так и из Postman.Я получаю сообщение об ошибке:

Произошло необработанное исключение при обработке запроса.WinHttpException: истекло время ожидания операции

System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () HttpRequestException: при отправке запроса произошла ошибка.

System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw ()IOException: IDX10804: невозможно получить документ из: 'http://taxrefund -identity.westeurope.azurecontainer.io / .well-known / openid-configuration '.

Microsoft.IdentityModel.Protocols.HttpDocumentRetriever + d__8.MoveNext () InvalidOperationException: IDX10803: Не удалось получить конфигурацию из: 'http://taxrefund -identity.westeurope.azurecontainer.io / .well-known / openid-configuration '.

Microsoft.IdentityModel.Protocols.ConfigurationManager + d__24.MoveNext ()

Самое странное, что я могу без проблем получить доступ к конечной точке обнаружения через браузер.

Метод My ConfigureServices:

   public void ConfigureServices(IServiceCollection services)
    {
        services.AddEntityFrameworkSqlServer()
                .AddDbContext<ApplicationDbContext>(options =>
                    options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"),
                        sqlServerOptionsAction: sqlOptions =>{
                            sqlOptions.EnableRetryOnFailure(maxRetryCount: 10, maxRetryDelay: TimeSpan.FromSeconds(30), errorNumbersToAdd: null);
                        }), ServiceLifetime.Scoped
                 );
        services.AddIdentity<ApplicationUser, IdentityRole>()
            .AddEntityFrameworkStores<ApplicationDbContext>()
            .AddDefaultTokenProviders();
        services.AddTransient<IEmailSender, EmailSender>();
        services.AddScoped<DatabaseInitializer>();
        services.AddCors();
        // Adds IdentityServer
        var cert = new X509Certificate2(Path.Combine(Environment.ContentRootPath, "idsrv3test.pfx"), "idsrv3test");
        services.AddIdentityServer()
            .AddSigningCredential(cert)
            .AddInMemoryIdentityResources(Config.GetIdentityResources())
            .AddInMemoryApiResources(Config.GetApiResources())
            .AddInMemoryClients(Config.GetClients())
            .AddAspNetIdentity<ApplicationUser>()
            .Services.AddTransient<IProfileService, ProfileService>();

        JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
        services.AddAuthentication()
            .AddGoogle("Google", options =>
            {
                options.ClientId = "**";
                options.ClientSecret = "**";
            })
            .AddMicrosoftAccount("Microsoft", options =>
            {
                options.ClientId = "**";
                options.ClientSecret = "**";
            });
        services.AddAuthentication("Bearer")
            .AddIdentityServerAuthentication(o =>
            {
                o.Authority = "http://taxrefund-identity.westeurope.azurecontainer.io/";
                o.ApiName = "Profile.API";
                o.ApiSecret = "**";
                o.RequireHttpsMetadata = false;
            });
        services.AddMvc();
        services.AddAntiforgery();
    }

Метод настройки:

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, RoleManager<IdentityRole> roleManager, ApplicationDbContext context, UserManager<ApplicationUser> userManager)
    {
        loggerFactory.AddDebug();
        loggerFactory.AddConsole(LogLevel.Trace);
        loggerFactory.AddFile("logs.txt");

        app.UseDeveloperExceptionPage();
        app.UseDatabaseErrorPage();
        app.UseBrowserLink();
        app.UseCors(policy =>
        {
            policy.AllowCredentials();
            policy.AllowAnyOrigin();
            policy.AllowAnyHeader();
            policy.AllowAnyMethod();
            policy.WithExposedHeaders("WWW-Authenticate");
        });

        app.UseStaticFiles();
        app.UseIdentityServer();
        app.UseAuthentication();
        app.UseMvc(routes =>
        {
            routes.MapRoute(
                name: "default",
                template: "{controller=Home}/{action=Index}/{id?}");
        });
        context.Database.Migrate();
        DatabaseInitializer.SeedData(roleManager);
    }

Конфигурация ресурса API:

new ApiResource("Profile.API", "Profile management API")
{
    UserClaims = { ClaimTypes.Role },
    ApiSecrets =
    {
        new Secret("**".Sha256())
    }
}

Я защищаю свой API следующим образом:

[Authorize(AuthenticationSchemes = "Bearer")]
[Route("api/Users")]
[Produces("application/json")]
public class ApplicationUsersAPIController : ControllerBase

Чтобы получить к нему доступ, я запрашиваю токен из конечной точки / connect / token (либо с учетными данными клиента, либо с помощью пароля / имени пользователя владельца ресурса), а затем используюэто в заголовке авторизации с последующими запросами.

Я застрял с этой проблемой почти месяц - сейчас это расстраивает.Я прочитал все сообщения, связанные с этой проблемой, и ни одно из решений не помогло.Я попытался снизить ранние версии system.net.http, другие сертификаты и другие решения, которые помогли другим.

Кроме того, конечная точка без атрибута [Authorize] работает просто отлично.

Единственное, что я не пробовал, это установить SSL-сертификат и сделать мои URL-адреса https - я прочитал, что это не должно влиять на функциональность сервера идентификации.У меня сейчас нет реальной необходимости в этом, поэтому дайте мне знать, если это необходимо.

Если от меня потребуется дополнительная информация, дайте мне знать.

Очень ценится.

1 Ответ

0 голосов
/ 28 мая 2018

Окончательное решение состояло в том, чтобы изменить URL-адрес полномочий в AddIdentityServerAuthentication с:

services.AddAuthentication("Bearer")
            .AddIdentityServerAuthentication(o =>
            {
                o.Authority = "http://taxrefund-identity.westeurope.azurecontainer.io/";
                o.ApiName = "Profile.API";
                o.ApiSecret = "**";
                o.RequireHttpsMetadata = false;
            });

На:

   services.AddAuthentication("Bearer")
                .AddIdentityServerAuthentication(o =>
                {
                    o.Authority = "http://localhost/"; //crucial part
                    o.ApiName = "Profile.API";
                    o.ApiSecret = "**";
                    o.RequireHttpsMetadata = false;
                });

Это действительно имеет смысл, поскольку в данном случае идентичностьСервер и API-интерфейс выполняются в одном и том же экземпляре / процессе контейнера, поэтому он не может получить доступ к самому себе через URL-адрес DNS, вместо этого он может получить доступ к самому себе через localhost URL-адрес.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...