CookieAuthenticationOptions.AccessDeniedPath和Logi



我的原始配置只是cookie身份验证,并且未登录或未授权的重定向工作。然后我添加了jwt令牌授权,以便与应用程序的api端一起使用,这可以工作,但是重定向已经停止工作。我尝试将模式添加到authorize属性中,但是没有帮助。[Authorize(AuthenticationSchemes = CookieAuthenticationDefaults.AuthenticationScheme)]

我尝试处理事件。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();
            });
       
        }
    }

我找到了这个答案并改编了它。它基本上检查UseAuthentication的结果,如果状态与auth相关,如果不是api调用,则触发cookie方案的挑战和禁止处理程序。我正在检查承载令牌的存在,因为api调用可能根本没有它,而不是过期或未经授权。正如最初的答案所说,在身份验证确定后,必须将其添加到链中。

app.UseAuthentication();
app.Use(async (context, next) =>
{
await next();
if (context.Response.StatusCode == 401 || context.Response.StatusCode == 403)
{
//var bearerAuth = context.Request.Headers["Authorization"]
//.FirstOrDefault()?.StartsWith("Bearer ") ?? false;
var isAPI = context.Request.Path.Value.Contains("/api/", StringComparison.OrdinalIgnoreCase);
if (!isAPI)
{
if (context.Response.StatusCode == 401)
{
await context.ChallengeAsync(CookieAuthenticationDefaults.AuthenticationScheme);
}
else if (context.Response.StatusCode == 403)
{
await context.ForbidAsync(CookieAuthenticationDefaults.AuthenticationScheme);
}
}
}
});

相关内容

  • 没有找到相关文章

最新更新