我对.net core有点陌生,并且我在如何解决这个问题上苦苦挣扎,所以请原谅我当前的方法是错误的还是固有地皱眉。
但是,我将我的应用程序设置为在使用任何API端点时使用Jwt和[Authorization]。由于这不是一个单页应用程序,因此我还需要授权访问该应用程序内的特定视图。例如,我只希望用户已经登录就可以访问应用程序的仪表板。
我的登录方法(来自伪描述)检查凭据,并生成一个JWT令牌,如果一切都检查完,则返回到客户端进行存储。在将令牌返回给客户端之前,我还要调用以下命令:
await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, User);
大部分工作。它创建一个cookie并将信息存储在cookie中,但是当它到达我要验证用户是否经过身份验证的控制器时,验证将运行两次。第一次运行时,isAuthenticated为false。第二次运行,这是事实。我很难找出为什么它运行两次(也许我在这里错过了什么?),并且开始怀疑我是否正确地解决了这个问题。
public IActionResult Dashboard()
{
bool isAuthenticated = User.Identity.IsAuthenticated;
return isAuthenticated ? View() : (IActionResult)Forbid();
}
我的Jwt授权工作得很好,但是我对cookie的授权根本不起作用。例如,以下方法中的“授权”工作正常。
[Authorize]
public OkObjectResult Test()
{
return Ok(HttpStatusCode.OK);
}
这是我的Startup.cs ConfigureServices
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthorization(auth =>
{
auth.AddPolicy("Bearer", new AuthorizationPolicyBuilder()
.AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme)
.RequireAuthenticatedUser().Build());
});
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddCookie(CookieAuthenticationDefaults.AuthenticationScheme, options =>
{
options.LoginPath = "/Home/Index";
options.AccessDeniedPath = "/Home/Index";
options.Cookie.Name = CookieAuthenticationDefaults.AuthenticationScheme;
options.ExpireTimeSpan = new TimeSpan(365, 0, 0, 0);
options.Cookie.SecurePolicy = CookieSecurePolicy.SameAsRequest;
options.Cookie.SameSite = SameSiteMode.None;
})
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateAudience = false,
//ValidAudience = "the audience you want to validate",
ValidateIssuer = false,
//ValidIssuer = "the issuer you want to validate",
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("XXX")),
ValidateLifetime = true, //validate the expiration and not before values in the token
ClockSkew = TimeSpan.FromMinutes(5) //5 minute tolerance for the expiration date
};
});
services.Configure<CookiePolicyOptions>(options =>
{
// This lambda determines whether user consent for non-essential cookies is needed for a given request.
options.CheckConsentNeeded = context => true;
options.Secure = CookieSecurePolicy.SameAsRequest;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
services.AddMvc(options =>
{
options.Filters.Add(new RequireHttpsAttribute());
})
.SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
// Configure the DB Access.
services.AddDbContext<DbAccess>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
// Ensure that we are adding the repos to our scope.
services.AddScoped<IResetRepository, ResetRepository>();
services.AddScoped<IAuthRepository, AuthRepository>();
// Inject our email settings.
services.Configure<EmailSettings>(Configuration.GetSection("EmailSettings"));
// Let's set up the email sender as transient.
services.AddTransient<IEmailSender, EmailSender>();
}
这是我在Startup.cs中的Configure方法
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
var cookiePolicyOptions = new CookiePolicyOptions
{
Secure = CookieSecurePolicy.SameAsRequest,
MinimumSameSitePolicy = SameSiteMode.None
};
app.UseCookiePolicy(cookiePolicyOptions);
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseCookiePolicy();
app.UseAuthentication();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}
我希望我不会在这里错过任何显而易见的事情。非常感谢您的协助。