我最初的配置只是 cookie 身份验证,未登录或未授权的重定向有效。然后我添加了 jwt token auth 以与我们应用程序的 api 端一起使用,并且可以正常工作,但是重定向已停止工作。我尝试将架构添加到授权属性,但它没有帮助。
[Authorize(AuthenticationSchemes = CookieAuthenticationDefaults.AuthenticationScheme)]
我尝试处理 Events.OnRedirectToAccessDenied 事件,当我添加 jwt 支持(AddJwtBearer 并将架构添加到默认策略)时它不会触发。
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)
{
services.AddCors(policy =>
{
policy.AddPolicy("OpenCorsPolicy", opt =>
opt.AllowAnyOrigin()
.AllowAnyHeader()
.AllowAnyMethod());
});
services.AddTransient<IUserManager, UserManager>();
var tokenValidationParams = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration.GetValue<string>("JWTSecret"))),
ValidateIssuer = false,
ValidateAudience = false,
ValidateLifetime = true,
RequireSignedTokens = true,
ClockSkew = TimeSpan.FromMinutes(1)
};
// adding the token settings so that hey are DI-able
services.AddSingleton<TokenValidationParameters>(tokenValidationParams);
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.MinimumSameSitePolicy = SameSiteMode.Strict;
});
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(CookieAuthenticationDefaults.AuthenticationScheme, x =>
{
x.LoginPath = new PathString("/Account/Login");
x.ExpireTimeSpan = TimeSpan.FromMinutes(Configuration.GetValue<int>("CookieExpiry"));
x.AccessDeniedPath = new PathString("/Account/Login");
x.SlidingExpiration = true;
//x.Events.OnRedirectToAccessDenied = ReplaceRedirector(HttpStatusCode.Forbidden, x.Events.OnRedirectToAccessDenied);
//x.Events.OnRedirectToLogin = ReplaceRedirector(HttpStatusCode.Unauthorized, x.Events.OnRedirectToLogin);
})
.AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, x =>
{
x.RequireHttpsMetadata = false;
x.SaveToken = true;
x.TokenValidationParameters = tokenValidationParams;
})
;
static Func<RedirectContext<CookieAuthenticationOptions>, Task> ReplaceRedirector(HttpStatusCode statusCode, Func<RedirectContext<CookieAuthenticationOptions>, Task> existingRedirector) =>
context => {
context.Response.Redirect(context.RedirectUri + "&Extra=Foo");
System.Diagnostics.Debug.WriteLine(statusCode);
return Task.CompletedTask;
//return existingRedirector(context);
};
services.AddAuthorization(options =>
{
// setting up that the default authorize can be either cookie or token
var defaultAuthorizationPolicyBuilder =
new AuthorizationPolicyBuilder(
CookieAuthenticationDefaults.AuthenticationScheme, JwtBearerDefaults.AuthenticationScheme);
defaultAuthorizationPolicyBuilder = defaultAuthorizationPolicyBuilder.RequireAuthenticatedUser();
options.DefaultPolicy = defaultAuthorizationPolicyBuilder.Build();
});
services.AddMvc(); //.AddJsonOptions(jsonOptions => jsonOptions.JsonSerializerOptions.PropertyNamingPolicy = null);
services.AddRazorPages(options =>
{
// you can set the authentication at the folder level
options.Conventions.AuthorizeFolder("/");
// you can set authenication for a single page
options.Conventions.AllowAnonymousToPage("/Error");
// you can set in the razor page [AllowAnonymous] like on index
/*
options.Conventions.AuthorizePage("/Contact");
options.Conventions.AuthorizeFolder("/Private");
options.Conventions.AllowAnonymousToPage("/Private/PublicPage");
options.Conventions.AllowAnonymousToFolder("/Private/PublicPages");
*/
});
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
}
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
endpoints.MapControllers();
});
}
}