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.