C# 使用.NET Core 3.1和端点路由获取401的有效访问令牌
我在获得认证/授权工作时遇到一些问题。我正在使用identity server身份验证(使用jwt承载令牌)。我正在使用C# 使用.NET Core 3.1和端点路由获取401的有效访问令牌,c#,asp.net-core,authentication,jwt,identityserver4,C#,Asp.net Core,Authentication,Jwt,Identityserver4,我在获得认证/授权工作时遇到一些问题。我正在使用identity server身份验证(使用jwt承载令牌)。我正在使用OnMessageReceived事件从正文而不是标题中获取令牌(这使得我的问题不同于此处询问的其他问题)。我还使用端点路由,而不是UseMvc()。每当我试图击中我的端点时,我都会得到一个401未经授权的响应。在调试输出中,我得到以下结果: Microsoft.AspNetCore.Authorization.DefaultAuthorizationService: Info
OnMessageReceived
事件从正文而不是标题中获取令牌(这使得我的问题不同于此处询问的其他问题)。我还使用端点路由,而不是UseMvc()
。每当我试图击中我的端点时,我都会得到一个401未经授权的响应。在调试输出中,我得到以下结果:
Microsoft.AspNetCore.Authorization.DefaultAuthorizationService: Information: Authorization failed.
Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler: Information: Successfully validated the token.
Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler: Information: AuthenticationScheme: BearerIdentityServerAuthenticationJwt was challenged.
IdentityServer4.AccessTokenValidation.IdentityServerAuthenticationHandler: Information: AuthenticationScheme: Bearer was challenged.
以下是我的startup.cs配置方法:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseHttpsRedirection();
app.UseStaticFiles();
if (!env.IsDevelopment())
{
app.UseSpaStaticFiles();
}
app.UseCookiePolicy();
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseStatusCodePagesWithReExecute("/Error/{0}");
app.UseAuthentication();
app.UseRouting();
app.UseAuthorization();
// Define the endpoints
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller}/{action=Index}/{id?}");
});
app.UseSwagger();
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "TheApp V1");
c.DefaultModelsExpandDepth(-1);
});
app.UseSpa(spa =>
{
// To learn more about options for serving an Angular SPA from ASP.NET Core,
// see https://go.microsoft.com/fwlink/?linkid=864501
spa.Options.SourcePath = "ManagementUI/ClientApp";
Log.Debug($"Setting SPA source path to: {spa.Options.SourcePath}");
if (env.IsDevelopment())
{
spa.UseAngularCliServer(npmScript: "start");
}
});
}
以下是我的startup.cs ConfigureServices方法:
public void ConfigureServices(IServiceCollection services)
{
services.AddMvcCore(options => options.EnableEndpointRouting = true)
.AddAuthorization()
.AddNewtonsoftJson()
.AddApiExplorer();
services.AddSpaStaticFiles(configuration =>
{
configuration.RootPath = "ManagementUI/ClientApp/dist";
Log.Debug($"Setting SPA root path to: {configuration.RootPath}");
});
services.AddDbContext<TheAppDatabaseContext>(options =>
options.UseSqlServer(
Configuration.GetConnectionString("TheAppDatabase")));
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddIdentityServerAuthentication(options =>
{
options.Authority = Configuration.GetValue<string>("IdentityServerInfo:IdentityServerAddress");
options.RequireHttpsMetadata = false;
options.SaveToken = true;
options.JwtBearerEvents.OnMessageReceived += async context =>
{
// Generate the database for the auth helper.
var optionsBuilder = new DbContextOptionsBuilder<TheAppDatabaseContext>();
optionsBuilder.UseSqlServer(Configuration.GetConnectionString("TheAppDatabase"));
await using var databaseContext = new TheAppDatabaseContext(optionsBuilder.Options);
// Create the auth helper.
var authenticationHelper =
new AuthenticationHelper(databaseContext, Configuration,
new IdentityServerInfoModel());
// Get the token from the request body.
var token = await authenticationHelper.ExtractTokenFromRequestBody(context.HttpContext);
// Assign the token to the context.
context.Token = token;
};
options.JwtBearerEvents.OnChallenge += async context =>
{
Log.Debug($"There was an issue with authentication: {context.Error} {context.ErrorDescription}");
};
});
var identServerInfo = Configuration.GetSection("IdentityServerInfo");
services.Configure<IdentityServerInfoModel>(identServerInfo);
services.AddSwaggerGen(sGen =>
{
sGen.SwaggerDoc("v1", new OpenApiInfo
{
Version = "v1",
Title = "TheApp"
});
sGen.IncludeXmlComments(GetXmlCommentsPath());
});
}
public void配置服务(IServiceCollection服务)
{
services.AddMvcCore(options=>options.EnableEndpointRouting=true)
.AddAuthorization()
.AddNewtonsoftJson()
.AddApiExplorer();
services.AddSpaStaticFiles(配置=>
{
configuration.RootPath=“ManagementUI/ClientApp/dist”;
Debug($“将SPA根路径设置为:{configuration.RootPath}”);
});
services.AddDbContext(选项=>
options.UseSqlServer(
GetConnectionString(“应用数据库”);
services.AddAuthentication(选项=>
{
options.DefaultAuthenticateScheme=JwtBearerDefaults.AuthenticationScheme;
options.DefaultScheme=JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme=JwtBearerDefaults.AuthenticationScheme;
})
.AddIdentityServerAuthentication(选项=>
{
options.Authority=Configuration.GetValue(“IdentityServerInfo:IdentityServerAddress”);
options.RequireHttpsMetadata=false;
options.SaveToken=true;
options.JwtBearerEvents.OnMessageReceived+=异步上下文=>
{
//为auth助手生成数据库。
var optionsBuilder=new DbContextOptionsBuilder();
optionsBuilder.UseSqlServer(Configuration.GetConnectionString(“应用数据库”);
等待使用var-databaseContext=newtheappdatabasecontext(optionsBuilder.Options);
//创建auth助手。
var authenticationHelper=
新的AuthenticationHelper(数据库上下文、配置、,
新标识服务器信息模型());
//从请求主体获取令牌。
var token=await authenticationHelper.ExtractTokenFromRequestBody(context.HttpContext);
//将令牌分配给上下文。
context.Token=Token;
};
options.JwtBearerEvents.OnChallenge+=异步上下文=>
{
Log.Debug($“身份验证出现问题:{context.Error}{context.ErrorDescription}”);
};
});
var identServerInfo=Configuration.GetSection(“IdentityServerInfo”);
services.Configure(identServerInfo);
services.AddSwaggerGen(sGen=>
{
sGen.SwaggerDoc(“v1”,新OpenApiInfo
{
Version=“v1”,
Title=“TheApp”
});
sGen.includexmlcompresents(getxmlcompresentspath());
});
}
我的控制器上有[Authorize(AuthenticationSchemes=“Bearer”)]
属性
我还尝试过使用app.UseAuthentication()下面的代码>app.UseRouting()
没有成功,因此我不确定订单是否与app.UseAuthentication()
和app.UseRouting()
有关,为什么您希望在控制器上放置[Authorize(AuthenticationSchemes=“Bearer”)
会起作用,当输出显式声明AuthenticationScheme:beareridentitityserverauthenticationjwt
?因为我能够在添加OnMessageReceived事件处理程序之前让它使用它(因此我可以从主体中提取令牌)。我试过了,但在我的项目中没有BearerIdentityServerAuthenticationJwt
。此外,Intellisense并没有意识到这是我遗漏的一项重要内容。