Подтвердить что ты не робот

Пропустить аутентификацию с помощью ASP Core MVC, Web API и IdentityServer4?

Я работал над переносом монолитного приложения ASP Core MVC для использования дизайна архитектуры службы. На внешнем веб-сайте MVC используется HttpClient для загрузки необходимых данных из ASP Core Web API. Небольшая часть внешнего приложения MVC также требует аутентификации, которая используется с помощью IdentityServer4 (интегрирована с внутренним API). Все это отлично работает, пока я не добавлю атрибут Authorize на контроллер или метод в веб-API. Я знаю, что мне нужно как-то передать авторизацию пользователя с внешнего интерфейса на задний план, чтобы это работало, но я не уверен, как это сделать. Я попытался получить access_token: User.FindFirst("access_token"), но он возвращает null. Затем я попробовал этот метод, и я могу получить токен:

var client = new HttpClient("url.com");
var token = HttpContext.Authentication.GetTokenAsync("access_token")?.Result;
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);

Этот метод получает токен, но до сих пор не выполняет аутентификацию с помощью API-интерфейсов. Я новичок в этой концепции OpenId/IdentityServer, и любая помощь будет оценена!

Вот соответствующий код из класса запуска MVC Client:

    private void ConfigureAuthentication(IApplicationBuilder app)
    {
        app.UseCookieAuthentication(new CookieAuthenticationOptions
        {
            AuthenticationScheme = "Cookies",
            AutomaticAuthenticate = true,
            ExpireTimeSpan = TimeSpan.FromMinutes(60)
        });
        JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
        app.UseOpenIdConnectAuthentication(new OpenIdConnectOptions
        {
            AuthenticationScheme = "oidc",
            SignInScheme = "Cookies",

            Authority = "https://localhost:44348/",
            RequireHttpsMetadata = false,

            ClientId = "clientid",
            ClientSecret = "secret",

            ResponseType = "code id_token",
            Scope = { "openid", "profile" },
            GetClaimsFromUserInfoEndpoint = true,
            AutomaticChallenge = true, // Required to 302 redirect to login
            SaveTokens = true,

            TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters
            {
                NameClaimType = "Name",
                RoleClaimType = "Role",
                SaveSigninToken = true
            },


        });
    }

и класс StartUp API:

        // Add authentication
        services.AddIdentity<ExtranetUser, IdentityRole>(options =>
        {
            // Password settings
            options.Password.RequireDigit = true;
            options.Password.RequiredLength = 8;
            options.Password.RequireNonAlphanumeric = true;
            options.Password.RequireUppercase = true;
            options.Password.RequireLowercase = true;

            // Lockout settings
            options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(30);
            options.Lockout.MaxFailedAccessAttempts = 10;

            // User settings
            options.User.RequireUniqueEmail = true;
        })
            .AddDefaultTokenProviders();
        services.AddScoped<IUserStore<ExtranetUser>, ExtranetUserStore>();
        services.AddScoped<IRoleStore<IdentityRole>, ExtranetRoleStore>();
        services.AddSingleton<IAuthorizationHandler, AllRolesRequirement.Handler>();
        services.AddSingleton<IAuthorizationHandler, OneRoleRequirement.Handler>();
        services.AddSingleton<IAuthorizationHandler, EditQuestionAuthorizationHandler>();
        services.AddSingleton<IAuthorizationHandler, EditExamAuthorizationHandler>();
        services.AddAuthorization(options =>
        {
            /* ... etc .... */
        });
        var serviceProvider = services.BuildServiceProvider();
        var serviceSettings = serviceProvider.GetService<IOptions<ServiceSettings>>().Value;
        services.AddIdentityServer() // Configures OAuth/IdentityServer framework
            .AddInMemoryIdentityResources(IdentityServerConfig.GetIdentityResources())
            .AddInMemoryClients(IdentityServerConfig.GetClients(serviceSettings))
            .AddAspNetIdentity<ExtranetUser>()
            .AddTemporarySigningCredential(); // ToDo: Add permanent SigningCredential for IdentityServer
4b9b3361

Ответ 1

Добавлен пакет nuget здесь и следующий код для исправления:

app.UseIdentityServerAuthentication(new IdentityServerAuthenticationOptions
{
   Authority = "https://localhost:44348/",
   ApiName = "api"
});

Это позволяет API размещать IdentityServer4 и использовать его как аутентификацию. Затем в MvcClient маркер-носитель может быть передан API.

Ответ 2

Да, вам нужно добавить пакет IdentityServer4.AccessTokenValidation в проект API. И проверьте комментарии ниже

app.UseIdentityServerAuthentication(new IdentityServerAuthenticationOptions
{
   Authority = "https://localhost:44348/", //Identity server host uri
   ApiName = "api", // Valid Api resource name 
   AllowedScopes = scopes // scopes:List<string> 
});

Вам следует удалить код ниже из класса StartUp API и заменить с помощью указанного выше:

 services.AddIdentityServer() // Configures OAuth/IdentityServer framework
            .AddInMemoryIdentityResources(IdentityServerConfig.GetIdentityResources())
            .AddInMemoryClients(IdentityServerConfig.GetClients(serviceSettings))
            .AddAspNetIdentity<ExtranetUser>()
            .AddTemporarySigningCredential();

вышеуказанный код требуется на вашем сервере идентификации, а не в API или любом другом клиенте