JWT Authentication .Net core [Authorize] 属性被控制器忽略
Posted
技术标签:
【中文标题】JWT Authentication .Net core [Authorize] 属性被控制器忽略【英文标题】:JWT Authentication .Net core [Authorize] Attribute Ignored by Controller 【发布时间】:2021-11-24 04:13:41 【问题描述】:我正在尝试在具有 Angular 8 前端和 .Net Core 后端的应用中实现基于 JWT 的身份验证。我加了
app.UseAuthentication();
app.UseAuthorization();
和
services.AddAuthentication(opt =>
在启动类中。我使用[Authorize]
属性修饰了控制器方法。但是当我尝试在没有任何标记的情况下点击控制器方法时,它允许进入控制器方法。
启动
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)
var jwtSettings = Configuration.GetSection("JwtSettings");
services.AddAuthentication(opt =>
opt.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
opt.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
).AddJwtBearer(options =>
options.TokenValidationParameters = new TokenValidationParameters
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = jwtSettings.GetSection("validIssuer").Value,
ValidAudience = jwtSettings.GetSection("validAudience").Value,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtSettings.GetSection("securityKey").Value))
;
);
services.AddSignalR();
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
// In production, the Angular files will be served from this directory
services.AddSpaStaticFiles(configuration =>
configuration.RootPath = "ClientApp/dist";
);
// requires using Microsoft.Extensions.Options
services.Configure<DatabaseSettings>(
Configuration.GetSection(nameof(DatabaseSettings)));
services.AddSingleton<IDatabaseSettings>(sp =>
sp.GetRequiredService<IOptions<DatabaseSettings>>().Value);
services.AddSingleton<FileService>();
services.AddSingleton<InternalReportService>();
services.AddTransient<MailService>();
services.AddMvc(option => option.EnableEndpointRouting = false);
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
app.UseRouting();
app.UseMvc();
if (env.IsDevelopment())
app.UseDeveloperExceptionPage();
else
app.UseExceptionHandler("/Error");
app.UseHsts();
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
endpoints.MapHub<CoreHub>("/corehub");
endpoints.MapControllerRoute("default", "controller=Home/action=Index");
);
app.UseSpa(spa =>
spa.Options.SourcePath = "ClientApp";
if (env.IsDevelopment())
spa.UseProxyToSpaDevelopmentServer("http://localhost:4200");
);
控制器
[Authorize]
public async Task UploadFile(IFormFile file)
// Do Stuff
【问题讨论】:
尝试使用这个 services.AddMvcCore() 而不是 services.AddMvc() 您没有共享创建 JWT 或持久化令牌的代码。https://code-maze.com/authentication-aspnetcore-jwt-1/
【参考方案1】:
嗯,你已经配置了你的 API 的认证部分,现在你需要用同样的方式配置授权......
你可以这样配置:
services.AddAuthorization(options =>
options.AddPolicy("Default", new AuthorizationPolicyBuilder()
.AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme)
.RequireAuthenticatedUser()
.Build());
options.AddPolicy("Admin", new AuthorizationPolicyBuilder()
.RequireRole("Admin")
.AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme)
.RequireAuthenticatedUser()
.Build());
);
然后你就可以使用属性了
[Authorize("User")]
[Authorize("Admin")]
在您的控制器或特定端点上。
如果您希望将此默认策略放在所有端点/控制器上并仅控制 if 的“AllowAnonymous”部分,您可以这样做:
services.AddMvc()
.AddMvcOptions(options =>
// Mark all endpoints with the default policy
options.Filters.Add(new AuthorizeFilter("Default"));
)
【讨论】:
应该是正确答案。 为什么必须定义角色?我的应用程序只需要有效的 Token 即可运行,不需要角色。 你不需要需要一个角色,只需定义一个默认的 -no named- 策略,正如@GibbOne 已经使用opts.DefaultPolicy = new AuthorizationPolicyBuilder(opts.DefaultPolicy).RequireAuthenticatedUser()
展示的那样,事实上,如果你愿意,你可以同时使用两者,同样适用于全局过滤器
事实上,默认策略是静态的,我想只要调用services.AddAuthorization()
就可以了,否则你必须配置它【参考方案2】:
根据您的身份验证方案,您应该以这种方式指定属性:
[Authorize(AuthenticationSchemes = "Bearer")]
这应该可以按您的预期工作
【讨论】:
谢谢...但这不起作用。 @techno 你能提供你的控制器的完整代码吗? 问题已解决。我打错了方法。 @techno 你的意思是有些答案是正确的吗?或者你的意思是整个问题与问题无关? 添加承载实际上解决了这个问题。但真正的问题是别的。【参考方案3】:我一般加DefaultSchema
。
services.AddAuthentication(opt =>
opt.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
opt.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
opt.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
//...
和授权。
services.AddAuthorization(opts =>
opts.DefaultPolicy = new AuthorizationPolicyBuilder(opts.DefaultPolicy)
.RequireAuthenticatedUser()
//...
【讨论】:
以上是关于JWT Authentication .Net core [Authorize] 属性被控制器忽略的主要内容,如果未能解决你的问题,请参考以下文章
在c#asp.net core web api中创建jwt令牌[重复]
将 JWT Bearer Authentication Web API 与 Asp.Net Core 2.0 结合使用的问题
JWT Bearer Authentication 不从标头中读取 Token