我正在使用.net core 2.0和jwt bearer身份验证(https://github.com/aspnet/Security)制作一个小型新项目
这是我的 Startup.cs
/// <summary>
/// This method gets called by the runtime. Use this method to add services to the container.
/// </summary>
/// <param name="services"></param>
public void ConfigureServices(IServiceCollection services)
{
// Add entity framework to services collection.
var sqlConnection = Configuration.GetConnectionString("SqlServerConnectionString");
services.AddDbContext<RelationalDatabaseContext>(
options => options.UseSqlServer(sqlConnection, b => b.MigrationsAssembly(nameof(Main))));
// Injections configuration.
services.AddScoped<IUnitOfWork, UnitOfWork>();
services.AddScoped<DbContext, RelationalDatabaseContext>();
services.AddScoped<IEncryptionService, EncryptionService>();
services.AddScoped<IIdentityService, IdentityService>();
services.AddScoped<ITimeService, TimeService>();
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
// Requirement handler.
services.AddScoped<IAuthorizationHandler, SolidAccountRequirementHandler>();
services.AddScoped<IAuthorizationHandler, RoleRequirementHandler>();
// Load jwt configuration from setting files.
services.Configure<JwtConfiguration>(Configuration.GetSection(nameof(JwtConfiguration)));
services.Configure<ApplicationSetting>(Configuration.GetSection(nameof(ApplicationSetting)));
// Build a service provider.
var serviceProvider = services.BuildServiceProvider();
var jwtBearerSettings = serviceProvider.GetService<IOptions<JwtConfiguration>>().Value;
// Cors configuration.
var corsBuilder = new CorsPolicyBuilder();
corsBuilder.AllowAnyHeader();
corsBuilder.AllowAnyMethod();
corsBuilder.AllowAnyOrigin();
corsBuilder.AllowCredentials();
// Add cors configuration to service configuration.
services.AddCors(options => { options.AddPolicy("AllowAll", corsBuilder.Build()); });
services.AddOptions();
// This can be removed after https://github.com/aspnet/IISIntegration/issues/371
var authenticationBuilder = services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
});
authenticationBuilder.AddJwtBearer(o =>
{
// You also need to update /wwwroot/app/scripts/app.js
o.Authority = jwtBearerSettings.Authority;
o.Audience = jwtBearerSettings.Audience;
o.RequireHttpsMetadata = false;
o.SecurityTokenValidators.Clear();
o.SecurityTokenValidators.Add(new JwtBearerValidator());
o.Events = new JwtBearerEvents()
{
OnAuthenticationFailed = c =>
{
c.NoResult();
c.Response.StatusCode = 500;
c.Response.ContentType = "text/plain";
if ("dev".Equals(Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT")))
{
// Debug only, in production do not share exceptions with the remote host.
return c.Response.WriteAsync(c.Exception.ToString());
}
return c.Response.WriteAsync("An error occurred processing your authentication.");
}
};
});
#region Mvc builder
// Construct mvc options.
var mvcBuilder =
services.AddMvc(mvcOptions =>
{
//only allow authenticated users
var policy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme)
.AddRequirements(new SolidAccountRequirement())
.Build();
mvcOptions.Filters.Add(new AuthorizeFilter(policy));
});
// Add json configuration/
mvcBuilder.AddJsonOptions(options =>
{
options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
});
#endregion
}
/// <summary>
/// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
/// </summary>
/// <param name="app"></param>
/// <param name="env"></param>
/// <param name="loggerFactory"></param>
/// <param name="serviceProvider"></param>
public void Configure(IApplicationBuilder app,
IHostingEnvironment env,
ILoggerFactory loggerFactory, IServiceProvider serviceProvider)
{
// Enable logging.
loggerFactory.AddConsole(Configuration.GetSection("Logging"));
loggerFactory.AddDebug();
// Use JWT Bearer authentication in the system.
app.UseAuthentication();
// Enable cors.
app.UseCors("AllowAll");
// Enable MVC features.
app.UseMvc();
}
通过这些配置,我的Web应用程序中已启用jwt。但是,我目前面临着一件事:
我的问题是:如何让我的jwt身份验证自动忽略标记为 AllowAnonymous 的方法或控制器?
谢谢,
答案 0 :(得分:0)
我认为,这是因为你要同时添加两个身份验证,一个使用jwt,另一个使用此代码。
var mvcBuilder =
services.AddMvc(mvcOptions =>
{
//only allow authenticated users
var policy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme)
.AddRequirements(new SolidAccountRequirement())
.Build();
mvcOptions.Filters.Add(new AuthorizeFilter(policy));
});
只保留jwt,如果你想添加策略,可以像这个例子那样做
services.AddAuthorization(options =>
{
options.AddPolicy("CreateUser", policy => policy.AddRequirements(
new UserLevelRequirement("Admin")
));
})
您不需要配置两次授权。
答案 1 :(得分:0)
允许引发OnAuthenticationFailed事件。但是您的API将返回 406 Not Acceptable ,因为此事件会将 Response ContentType 设置为“text / plain”;。您可以将代码c.Response.ContentType = "text/plain";
更改为c.Response.ContentType = "application/json";
。
答案 2 :(得分:0)
而不是使用 OnAuthenticationFailed ,请尝试将其放入 OnChallenge :
o.Events = new JwtBearerEvents()
{
OnChallenge = c =>
{
c.HandleResponse();
c.Response.StatusCode = 500;
c.Response.ContentType = "text/plain";
return c.Response.WriteAsync("An error occurred processing your authentication.");
}
};
答案 3 :(得分:0)
我在这里https://github.com/aspnet/Security/issues/1488找到了解决方法
对AddAuthorization的调用必须在MvcCoreBuilder上,而不是服务集合上。
services
.AddMvcCore()
.AddAuthorization(...)
缺点是AddMvcCore()不会添加AddMvc()添加的所有服务。查看AddMvc()的源代码以了解要添加的其他服务。
编辑
以上仍然对我不起作用。
您可以改用[OverrideAuthentication]