简体   繁体   中英

OpenIdDict 3.0 Accepting Id Token instead of Access Token in Controllers

I'm using OpenIdDict 3.0 to host my identity server. I'm able to get access token and id token, but somehow my controllers are returning 401 when I use access token in authorization header but successfully authenticated when I'm using id token.

I have used OpenIdDict 2.0 in my previous project and that worked fine.

The following is my Start.cs

public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            #region Database
            var connectionString = Environment.GetEnvironmentVariable("CONNECTION_STRING");
#if DEBUG
            connectionString = Configuration.GetConnectionString("DefaultConnection");
#endif
            services.AddDbContext<ApplicationDbContext>(options => 
            { 
                options.UseMySql(connectionString);

                // Register the entity sets needed by OpenIddict.
                // Note: use the generic overload if you need
                // to replace the default OpenIddict entities.
                options.UseOpenIddict();
            });
            #endregion

            #region Authentication
            services
                .AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
                .AddJwtBearer(options =>
                {
                    options.Authority = Configuration["Jwt:Authority"];
                    options.Audience = Configuration["Jwt:Audience"];
                    options.RequireHttpsMetadata = bool.TryParse(Configuration["Jwt:Https"], out bool isHttps) && isHttps;
                });

            // Configure Identity to use the same JWT claims as OpenIddict instead
            // of the legacy WS-Federation claims it uses by default (ClaimTypes),
            // which saves you from doing the mapping in your authorization controller.
            services.Configure<IdentityOptions>(options =>
            {
                options.ClaimsIdentity.UserNameClaimType = ClaimTypes.Name;
                options.ClaimsIdentity.UserIdClaimType = JwtRegisteredClaimNames.Sub;
                options.ClaimsIdentity.RoleClaimType = ClaimTypes.Role;
            });

            services.AddOpenIddict()
                    // Register the OpenIddict core components.
                    .AddCore(options =>
                    {
                        // Configure OpenIddict to use the Entity Framework Core stores and models.
                        // Note: call ReplaceDefaultEntities() to replace the default entities.
                        options.UseEntityFrameworkCore()
                               .UseDbContext<ApplicationDbContext>();
                    })
                    // Register the OpenIddict server components.
                    .AddServer(options =>
                    {
                        // Enable the token endpoint.
                        // Enable the client credentials flow.
                        options
                            .SetTokenEndpointUris("/Account/Token")
                            .AllowPasswordFlow()
                            .SetAccessTokenLifetime(TimeSpan.FromHours(1))
                            .AllowRefreshTokenFlow()
                            .SetRefreshTokenLifetime(TimeSpan.FromDays(7));

                        // Register the signing and encryption credentials.
                        options
                            .AddDevelopmentEncryptionCertificate()
                            .AddDevelopmentSigningCertificate();

                        options.RegisterClaims();

                        // Register the ASP.NET Core host and configure the ASP.NET Core options.
                        options
                            .UseAspNetCore()
                            .EnableTokenEndpointPassthrough();
                    })
                    // Register the OpenIddict validation components.
                    .AddValidation(options =>
                    {
                        // Import the configuration from the local OpenIddict server instance.
                        options.UseLocalServer();

                        // Register the ASP.NET Core host.
                        options.UseAspNetCore();
                    });
            #endregion

            services.AddControllers();
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();

                app.UseMyPcBuilderOpenIdDict().Wait();
            }

            app.UseRouting();

            app.UseAuthentication();

            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
        }
    }

Your configuration is invalid: you're registering both the JWT handler and the OpenIddict validation handler.

Unlike the JWT handler, the OpenIddict validation handler can import the encryption keys used to protect the access tokens issued by the server (thanks to UseLocalServer() ). Since the JWT handler doesn't have an equivalent method, it can't decrypt your access tokens.

The OpenIddict validation handler also comes with built-in typ token type validation to ensure identity tokens are never accepted by API endpoints. This is not something the JWT handler does.

Replace JwtBearerDefaults.AuthenticationScheme by OpenIddictValidationAspNetCoreDefaults.AuthenticationScheme and things will work correctly.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM