英文:
Authorization in .NET Core 6 returns 400?
问题
我是.NET Core的新手,所以我决定在这里寻求帮助。
我在创建我的Web应用程序的身份验证功能时遇到了问题。
问题是,我得到了错误响应400
。如果我更改我的Program.cs中的某些配置,比如删除以下代码行:
options.Events = new JwtBearerEvents
{
OnMessageReceived = context =>
{
context.Token = context.Request.Cookies["jwt"];
return Task.CompletedTask;
}
};
它将返回错误响应401
。
以下是我的Program.cs中的代码:
var builder = WebApplication.CreateBuilder(args);
// 将服务添加到容器中。
builder.Services.AddControllersWithViews();
builder.Services.AddDbContext<ApplicationDBContext>(options =>
options.UseSqlServer(builder.Configuration.GetConnectionString("Dev_Environment")));
builder.Services.AddIdentity<LoginModel, IdentityRole>()
.AddEntityFrameworkStores<ApplicationDBContext>()
.AddDefaultTokenProviders();
builder.Services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(options =>
{
options.Events = new JwtBearerEvents
{
OnMessageReceived = context =>
{
context.Token = context.Request.Cookies["jwt"];
return Task.CompletedTask;
}
};
options.SaveToken = true;
options.RequireHttpsMetadata = false;
options.TokenValidationParameters = new TokenValidationParameters()
{
ValidateIssuer = true,
ValidateAudience = true,
ValidIssuer = builder.Configuration["Hashing:ValidIssuer"],
ValidAudience = builder.Configuration["Hashing:ValidAudience"],
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(builder.Configuration["Hashing:SecretKey"]))
};
});
builder.Services.AddAuthorization(options =>
{
var defaultAuthorizationPolicyBuilder = new AuthorizationPolicyBuilder(
JwtBearerDefaults.AuthenticationScheme);
defaultAuthorizationPolicyBuilder =
defaultAuthorizationPolicyBuilder.RequireAuthenticatedUser();
options.DefaultPolicy = defaultAuthorizationPolicyBuilder.Build();
});
var app = builder.Build();
// 配置HTTP请求管道。
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.MapControllerRoute(
name: "default",
pattern: "{controller=Authentication}/{action=Login}/{id?}");
app.Run();
我已经创建了一个带有属性[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
的DashboardController
。
这是我的AuthenticationController
,用于创建JWT令牌以进行授权。
[HttpPost]
public IActionResult Login(LoginModel userCredential, string returnURL)
{
systemLogic = new AuthenticationLogic();
if (userCredential != null)
{
userCredential.Email = hasher.Encrypt(userCredential.Email);
userCredential.Password = hasher.Encrypt(clearText: userCredential.Password);
}
userInput = new UserInput();
userInput[typeof(LoginModel).FullName] = userCredential;
systemResult = systemLogic.ExecuteProcess(configuration, userInput);
if (systemResult.ResultCode == SystemResult.SUCCESS)
{
LoginModel? userInfo = systemResult[typeof(LoginModel).FullName] as LoginModel;
Claim[] claims = new[] { new Claim(ClaimTypes.Email, hasher.Decrypt(userInfo.Email)) };
SymmetricSecurityKey secretKey = new(Encoding.UTF8.GetBytes(configuration["Hashing:SecretKey"]));
SigningCredentials signinCredentials = new(secretKey, SecurityAlgorithms.HmacSha256);
JwtSecurityToken tokenOptions = new(
issuer: configuration["Hashing:ValidIssuer"],
audience: configuration["Hashing:ValidAudience"],
claims: claims,
expires: DateTime.Now.AddHours(1),
signingCredentials: signinCredentials);
string tokenString = new JwtSecurityTokenHandler().WriteToken(tokenOptions);
Response.Cookies.Append("jwt", tokenString, new CookieOptions
{
HttpOnly = true,
SameSite = SameSiteMode.Strict,
Secure = true,
Expires = DateTime.UtcNow.AddDays(7)
});
if (!string.IsNullOrEmpty(returnURL))
{
return Redirect(returnURL);
}
return RedirectToAction("Dashboard", "Dashboard");
}
else
{
return View(userCredential);
}
}
我在做什么方面出错了,为什么会得到401和400?我已经检查了登录后的context.Request.Cookies["jwt"]
,并且存在令牌。但仍然会返回400的响应。
英文:
I am new in .NET Core so I decided to seek help here.
I am having trouble creating the Authentication Functionality of my Web Application.
The problem is, I am getting Error Response 400
. and if change some of the configuration in my Program.cs like removing this line of code,
options.Events = new JwtBearerEvents
{
OnMessageReceived = context =>
{
context.Token = context.Request.Cookies["jwt"];
return Task.CompletedTask;
}
};
It will return Error Response 401
.
Here is my code in my Program.cs
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllersWithViews();
builder.Services.AddDbContext<ApplicationDBContext>(options =>
options.UseSqlServer(builder.Configuration.GetConnectionString("Dev_Environment")));
builder.Services.AddIdentity<LoginModel, IdentityRole>()
.AddEntityFrameworkStores<ApplicationDBContext>()
.AddDefaultTokenProviders();
builder.Services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(options =>
{
options.Events = new JwtBearerEvents
{
OnMessageReceived = context =>
{
context.Token = context.Request.Cookies["jwt"];
return Task.CompletedTask;
}
};
options.SaveToken = true;
options.RequireHttpsMetadata = false;
options.TokenValidationParameters = new TokenValidationParameters()
{
ValidateIssuer = true,
ValidateAudience = true,
ValidIssuer = builder.Configuration["Hashing:ValidIssuer"],
ValidAudience = builder.Configuration["Hashing:ValidAudience"],
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(builder.Configuration["Hashing:SecretKey"]))
};
});
builder.Services.AddAuthorization(options =>
{
var defaultAuthorizationPolicyBuilder = new AuthorizationPolicyBuilder(
JwtBearerDefaults.AuthenticationScheme);
defaultAuthorizationPolicyBuilder =
defaultAuthorizationPolicyBuilder.RequireAuthenticatedUser();
options.DefaultPolicy = defaultAuthorizationPolicyBuilder.Build();
});
var app = builder.Build();
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Home/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.MapControllerRoute(
name: "default",
pattern: "{controller=Authentication}/{action=Login}/{id?}");
app.Run();
I have create a DashboardController with the Attribute [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
Here is my AuthenticationController
creating a JWT Token for Authorizaiton purposes.
[HttpPost]
public IActionResult Login(LoginModel userCredential, string returnURL)
{
systemLogic = new AuthenticationLogic();
if (userCredential != null)
{
userCredential.Email = hasher.Encrypt(userCredential.Email);
userCredential.Password = hasher.Encrypt(clearText: userCredential.Password);
}
userInput = new UserInput();
#pragma warning disable CS8604 // Possible null reference argument.
userInput[typeof(LoginModel).FullName] = userCredential;
#pragma warning restore CS8604 // Possible null reference argument.
systemResult = systemLogic.ExecuteProcess(configuration, userInput);
if (systemResult.ResultCode == SystemResult.SUCCESS)
{
LoginModel? userInfo = systemResult[typeof(LoginModel).FullName] as LoginModel;
Claim[] claims = new[] { new Claim(ClaimTypes.Email, hasher.Decrypt(userInfo.Email)) };
SymmetricSecurityKey secretKey = new(Encoding.UTF8.GetBytes(configuration["Hashing:SecretKey"]));
SigningCredentials signinCredentials = new(secretKey, SecurityAlgorithms.HmacSha256);
JwtSecurityToken tokenOptions = new(
issuer: configuration["Hashing:ValidIssuer"],
audience: configuration["Hashing:ValidAudience"],
claims: claims,
expires: DateTime.Now.AddHours(1),
signingCredentials: signinCredentials);
string tokenString = new JwtSecurityTokenHandler().WriteToken(tokenOptions);
// Response.Headers.Add("Authorization", "Bearer " + tokenString);
Response.Cookies.Append("jwt", tokenString, new CookieOptions
{
HttpOnly = true,
SameSite = SameSiteMode.Strict,
Secure = true,
Expires = DateTime.UtcNow.AddDays(7)
});
if (!string.IsNullOrEmpty(returnURL))
{
return Redirect(returnURL);
}
return RedirectToAction("Dashboard", "Dashboard");
}
else
{
return View(userCredential);
}
}
What am I doing wrong on this and why I am getting 401 and 400?
I already check the context.Request.Cookies["jwt"]
after logging in and there is a token. And still the response will be 400.
答案1
得分: 1
我检查了您的评论,我认为400错误是由[ValidateAntiForgeryToken]
属性引起的。如果您在控制器上添加了此属性,当您发送GET请求时,它也会期望一个AntiForgery令牌。根据您的要求,应该使用[AutoValidateAntiforgeryToken]
来保护所有的POST端点。
您可以查看这个文档以获取更多详细信息。
英文:
I checked your comments and i think the 400 error was caused by [ValidateAntiForgeryToken]
attribute .If you add the attr on the controller, when you send a get request, it would also expect an AntiForgeryToken .For your requirement,it should be [AutoValidateAntiforgeryToken]
to protect all post endpoints
You could check this document related for more details
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论