IdentityServer4 и код с тестированием PKCE с почтальоном - PullRequest
0 голосов
/ 03 мая 2020

Я начинаю с IdentityServer4, и я справился с потоком владельцев ресурсов, но так как он больше не рекомендуется, PKCE, я решил изменить его. Я получаю следующее сообщение об ошибке, которое очевидно, потому что я больше не использую GrantTypes.ResourceOwnerPassword.

fail: IdentityServer4.Validation.TokenRequestValidator[0]
      Client not authorized for resource owner flow, check the AllowedGrantTypes setting{ client_id = trusted }, details: {
        "ClientId": "trusted",
        "ClientName": "Dayum Client",
        "GrantType": "password",
        "Raw": {
          "grant_type": "password",
          "username": "Admin",
          "password": "***REDACTED***",
          "scope": "openid profile offline_access api1",
          "client_id": "trusted"
        }
      }

Я не нахожу много информации, потому что она новая, но как мне ее проверить? с почтальоном? Раньше я делал следующие действия с потоком владельцев ресурсов:

POST http://localhost:58508/connect/token
grant_type = password
username=Admin
password=123456
scope=openid profile offline_access api1
client_id=trusted

Я знаю, что больше не могу этого делать с кодом с PKCE. Как запросить доступ и обновить sh токены, как проверить его с помощью Почтальона?

Код:

public static class Config
{
    public static IEnumerable<IdentityResource> GetResources() =>
        new List<IdentityResource>
        {
            new IdentityResources.OpenId(),
            new IdentityResources.Profile()
        };

    public static IEnumerable<ApiResource> GetApis() =>
        new List<ApiResource>
        {
            new ApiResource("api1", "My API")
        };

    public static IEnumerable<Client> GetClients() =>
        new List<Client>
        {
            new Client
            {
                ClientId = "trusted",
                ClientName = "Dayum Client",
                //ClientSecrets = { new Secret("xxxxxxxxxxxxxxxxxxxxxxx".Sha256()) },

                RequireConsent = false,
                RequireClientSecret = false,
                AllowedGrantTypes = GrantTypes.Code,
                RequirePkce = true,

                AllowAccessTokensViaBrowser = true,
                RedirectUris = { "http://localhost:58508" },
                PostLogoutRedirectUris = { "http://localhost:58508" },

                AllowedScopes =
                {
                    IdentityServerConstants.StandardScopes.OpenId,
                    IdentityServerConstants.StandardScopes.Profile,
                    IdentityServerConstants.StandardScopes.OfflineAccess,
                    "api1"
                },

                AccessTokenType = AccessTokenType.Jwt,  
                AccessTokenLifetime = 900,

                AllowOfflineAccess = true,
                RefreshTokenExpiration = TokenExpiration.Absolute,
                RefreshTokenUsage = TokenUsage.OneTimeOnly,
                AbsoluteRefreshTokenLifetime = 1800
            }
        };
}

public class Startup
{
    public IWebHostEnvironment Environment { get; }
    public IConfiguration Configuration { get; }

    public Startup(IWebHostEnvironment environment, IConfiguration configuration)
    {
        Environment = environment;
        Configuration = configuration;
    }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddControllersWithViews();

        services.AddDbContext<ApplicationDbContext>(options =>
            options.UseSqlServer(Configuration["ConnectionStrings:DayumConnection"],
                optionsBuilder => optionsBuilder.MigrationsAssembly(typeof(ApplicationDbContext).Assembly.FullName)));

        services.AddIdentity<ApplicationUser, IdentityRole>(options =>
        {
            options.Password.RequireDigit = false;
            options.Password.RequireLowercase = false;
            options.Password.RequireNonAlphanumeric = false;
            options.Password.RequireUppercase = false;
            options.Password.RequiredLength = 6;
        })
            .AddEntityFrameworkStores<ApplicationDbContext>()
            .AddDefaultTokenProviders();

        services.AddIdentityServer(options =>
        {
            options.Events.RaiseErrorEvents = true;
            options.Events.RaiseInformationEvents = true;
            options.Events.RaiseFailureEvents = true;
            options.Events.RaiseSuccessEvents = true;
        })
            .AddSigningCredential(new X509Certificate2(Configuration["Certificates:Default:Path"], Configuration["Certificates:Default:Password"]))
            .AddConfigurationStore(options =>
            {
                options.ConfigureDbContext = builder => builder.UseSqlServer(Configuration["ConnectionStrings:DayumConnection"],
                    optionsBuilder => optionsBuilder.MigrationsAssembly(typeof(ApplicationDbContext).Assembly.FullName));
            })
            .AddOperationalStore(options =>
            {
                options.ConfigureDbContext = builder => builder.UseSqlServer(Configuration["ConnectionStrings:DayumConnection"],
                    optionsBuilder => optionsBuilder.MigrationsAssembly(typeof(ApplicationDbContext).Assembly.FullName));

                options.EnableTokenCleanup = true;
            })
            .AddProfileService<ProfileService>()
            .AddAspNetIdentity<ApplicationUser>();
    }

    public void Configure(IApplicationBuilder app)
    {
        using (var serviceScope = app.ApplicationServices.GetService<IServiceScopeFactory>().CreateScope())
        {
            serviceScope.ServiceProvider.GetRequiredService<PersistedGrantDbContext>().Database.Migrate();

            var context = serviceScope.ServiceProvider.GetRequiredService<ConfigurationDbContext>();
            context.Database.Migrate();
            if (!context.Clients.Any())
            {
                foreach (var client in Config.GetClients())
                {
                    context.Clients.Add(client.ToEntity());
                }
                context.SaveChanges();
            }

            if (!context.IdentityResources.Any())
            {
                foreach (var resource in Config.GetResources())
                {
                    context.IdentityResources.Add(resource.ToEntity());
                }
                context.SaveChanges();
            }

            if (!context.ApiResources.Any())
            {
                foreach (var resource in Config.GetApis())
                {
                    context.ApiResources.Add(resource.ToEntity());
                }
                context.SaveChanges();
            }
        }

        if (Environment.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }

        app.UseRouting();

        app.UseIdentityServer();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllerRoute(
                name: "MyArea",
                pattern: "{area:exists}/{controller=Home}/{action=Index}/{id?}");

            endpoints.MapControllerRoute(
                name: "default",
                pattern: "{controller=Home}/{action=Index}/{id?}");
        });
    }
}

1 Ответ

1 голос
/ 04 мая 2020

Во-первых, поддержка PKCE для OAuth 2.0 доступна в последней версии приложения Postman (v7.23.0), пожалуйста, обновите ваш Postman до последней версии.

Затем в заголовке Authorization Почтальон, установите Type на OAuth2 и нажмите кнопку Get New Access Token, установите Grant Type на Authorization code(With PKCE) и установите конечные точки / информацию о клиенте, как показано ниже:

enter image description here

И Auth url / Access Token Url являются конечными точками сервера идентификации 4 и заменяют Callback url в качестве URL-адреса перенаправления вашего клиентского приложения. Я заметил, что в ваших кодах вы устанавливаете одну и ту же конечную точку / хост url (http://localhost: 58508 ) на сервере идентификации и клиенте, пожалуйста, измените его в соответствии с вашими реальными требованиями.

...