我有一个问题,如果我手动转到登录页面之后的页面,我的策略句柄之一会出现异常,因为它找不到索赔。
为什么会发生这种情况,而不是将用户重定向到登录页面,因为他没有经过身份验证?我什至设置了身份验证方案,因为我的所有页面都有
[Authorize("scheme"), Policy = "policy"]
Run Code Online (Sandbox Code Playgroud)
这是我的整个启动代码
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.AddAuthentication()
.AddCookie("ProductionAuth", options =>
{
options.ExpireTimeSpan = TimeSpan.FromDays(1);
options.LoginPath = new PathString("/Production/Index");
options.LogoutPath = new PathString("/Production/Logout");
options.AccessDeniedPath = new PathString("/Production/AccessDenied/");
options.SlidingExpiration = true;
})
.AddCookie("AdministrationAuth", options =>
{
options.ExpireTimeSpan = TimeSpan.FromDays(1);
options.LoginPath = new PathString("/Administration/Index");
options.LogoutPath = new PathString("/Administration/Logout");
options.AccessDeniedPath = new PathString("/Administration/AccessDenied/");
options.SlidingExpiration = true;
});
services.AddAuthorization(options =>
{
options.AddPolicy("HasArranqueActivo", policy =>
policy.RequireAuthenticatedUser()
.AddAuthenticationSchemes("ProductionAuth")
.Requirements.Add(new HasArranqueActivoRequirement()
));
options.AddPolicy("HasArranqueInactivo", policy =>
policy.RequireAuthenticatedUser()
.AddAuthenticationSchemes("ProductionAuth")
.Requirements.Add(new HasArranqueInactivoRequirement()
));
options.AddPolicy("IsParagemNotOnGoing", policy =>
policy.RequireAuthenticatedUser()
.AddAuthenticationSchemes("ProductionAuth")
.Requirements.Add(new IsParagemNotOnGoingRequirement()
));
options.AddPolicy("IsParagemOnGoing", policy =>
policy.RequireAuthenticatedUser()
.AddAuthenticationSchemes("ProductionAuth")
.Requirements.Add(new IsParagemOnGoingRequirement()
));
});
services.AddMemoryCache();
services.AddMvc()
.AddRazorPagesOptions(options =>
{
options.AllowAreas = true;
options.Conventions.AuthorizeAreaFolder("Administration", "/Account");
options.Conventions.AuthorizeAreaFolder("Production", "/Account");
})
.AddNToastNotifyToastr(new ToastrOptions()
{
ProgressBar = true,
TimeOut = 3000,
PositionClass = ToastPositions.TopFullWidth,
PreventDuplicates = true,
TapToDismiss = true
})
.SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseNToastNotify();
app.UseAuthentication();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}
}
Run Code Online (Sandbox Code Playgroud)
这是我的handler,每个handler基本都是一样的。要求很简单,身体里什么也没有。
public class IsParagemNotOnGoingHandler : AuthorizationHandler<IsParagemNotOnGoingRequirement>
{
private readonly DatabaseContext _context;
public IsParagemNotOnGoingHandler(DatabaseContext context)
{
_context = context;
}
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, IsParagemNotOnGoingRequirement requirement)
{
// Get the context
var redirectContext = context.Resource as AuthorizationFilterContext;
var registoId = Convert.ToInt32(context.User.FindFirst(c => c.Type == ClaimTypes.PrimarySid).Value);
bool IsRegistoOnGoing = _context.ParagensRegistos.Any(pr => pr.RegistoId == registoId && pr.HoraFim == null);
if (!IsRegistoOnGoing)
{
context.Succeed(requirement);
}
else
{
redirectContext.Result = new RedirectToPageResult("/Paragem");
context.Succeed(requirement);
}
return Task.CompletedTask;
}
}
Run Code Online (Sandbox Code Playgroud)
这是例外
处理请求时发生未处理的异常。NullReferenceException:未将对象引用设置为对象的实例。IsParagemNotOnGoingHandler.cs 第 27 行中的 NoPaper.Policies.IsParagemNotOnGoingHandler.HandleRequirementAsync(AuthorizationHandlerContext 上下文、IsParagemNotOnGoingRequirement 要求)
堆栈查询 Cookie 标头 NullReferenceException:未将对象引用设置为对象的实例。IsParagemNotOnGoingHandler.cs 中的 NoPaper.Policies.IsParagemNotOnGoingHandler.HandleRequirementAsync(AuthorizationHandlerContext 上下文,IsParagemNotOnGoingRequirement 要求) + var registoId = Convert.ToInt32(context.User.FindFirst(c => c.Type == ClaimTypes.PrimarySid).Value); Microsoft.AspNetCore.Authorization.AuthorizationHandler.HandleAsync(AuthorizationHandlerContext上下文) Microsoft.AspNetCore.Authorization.DefaultAuthorizationService.AuthorizeAsync(ClaimsPrincipal用户,对象资源,IEnumerable要求) Microsoft.AspNetCore.Authorization.Policy.PolicyEvaluator.AuthorizeAsync(AuthorizationPolicy策略,AuthenticateResult认证结果, HttpContext 上下文,对象资源) Microsoft.AspNetCore.Mvc.Authorization.AuthorizeFilter.OnAuthorizationAsync(AuthorizationFilterContext context) Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeFilterPipelineAsync() Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeAsync() Microsoft.AspNetCore .Routing.EndpointMiddleware.Invoke(HttpContext httpContext) Microsoft.AspNetCore.Routing.EndpointRoutingMiddleware.Invoke(HttpContext httpContext) Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware.Invoke(HttpContext 上下文) Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext 上下文) NToastNotify .NtoastNotifyAjaxToastsMiddleware.InvokeAsync(HttpContext context, RequestDelegate next) Microsoft.AspNetCore.Builder.UseMiddlewareExtensions+<>c__DisplayClass5_1+<b__1>d.MoveNext() Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware.Invoke(HttpContext context) Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware。调用(HttpContext 上下文)
文档中有一个重要的注释解决了这个问题:
即使身份验证失败,也会调用授权处理程序。
在您的情况下,身份验证已失败,但您的IsParagemNotOnGoingHandler仍被HandleRequirementAsync调用。要解决该问题,您只需使处理程序实现对丢失的声明更具弹性即可。下面是一个完整性示例:
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, IsParagemNotOnGoingRequirement requirement)
{
if (!context.User.HasClaim(c => c.Type == ClaimTypes.PrimarySid))
return Task.CompletedTask;
...
}
Run Code Online (Sandbox Code Playgroud)
Convert.ToInt32对于声明的值不可转换为int.
| 归档时间: |
|
| 查看次数: |
7060 次 |
| 最近记录: |