严重的是,我在这里做错了什么?如果另一个策略与另一个策略相反,怎么可能不起作用?名称上只有3个字母会更改并反转布尔检查。...
政策HasArranqueActivo
是可行的。我用调试器进行测试并触发它。
以下是宣布的政策
services.AddAuthorization(options =>
{
options.AddPolicy("HasArranqueActivo", policy =>
policy.Requirements.Add(new HasArranqueActivoRequirement()
));
options.AddPolicy("HasArranqueInactivo", policy =>
policy.Requirements.Add(new HasArranqueInactivoRequirement()
));
});
如您所见,两个处理程序基本相同
public class HasArranqueActivoHandler : AuthorizationHandler<HasArranqueActivoRequirement>
{
private readonly NoPaperContext _context;
public HasArranqueActivoHandler(NoPaperContext context)
{
_context = context;
}
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, HasArranqueActivoRequirement requirement)
{
// Do something with _context
// Check if the requirement is fulfilled.
var registoId = Convert.ToInt32(context.User.FindFirst(c => c.Type == ClaimTypes.PrimarySid).Value);
var registo = _context.Registos.Find(registoId);
if (registo.IsArranqueActivo)
{
context.Succeed(requirement);
}
return Task.CompletedTask;
}
}
public class HasArranqueInactivoHandler : AuthorizationHandler<HasArranqueInactivoRequirement>
{
private readonly NoPaperContext _context;
public HasArranqueInactivoHandler(NoPaperContext context)
{
_context = context;
}
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, HasArranqueInactivoRequirement requirement)
{
// Do something with _context
// Check if the requirement is fulfilled.
var registoId = Convert.ToInt32(context.User.FindFirst(c => c.Type == ClaimTypes.PrimarySid).Value);
var registo = _context.Registos.Find(registoId);
if (!registo.IsArranqueActivo)
{
context.Succeed(requirement);
}
return Task.CompletedTask;
}
}
在我的页面上,它被扭曲了,并且没有触发策略处理程序,并且我一直在拒绝访问。为什么?
[Authorize(AuthenticationSchemes = "ProductionAuth", Policy = "HasArranqueInactivo")]
编辑
这是整个创业公司
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.Requirements.Add(new HasArranqueActivoRequirement()
));
options.AddPolicy("HasArranqueInactivo", policy =>
policy.Requirements.Add(new HasArranqueInactivoRequirement()
));
});
services.AddSingleton<IFileProvider>(
new PhysicalFileProvider(
Path.Combine(Directory.GetCurrentDirectory(), "wwwroot/files")));
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);
services.AddTransient<IAuthorizationHandler, HasArranqueActivoHandler>();
services.AddRouting(options =>
{
options.LowercaseUrls = true;
options.LowercaseQueryStrings = true;
});
services.AddDbContext<NoPaperContext>(options =>
{
//if(Environment.IsProduction())
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"), sqlServerOptionsAction: sqlOptions =>
{
sqlOptions.EnableRetryOnFailure(
maxRetryCount: 2,
maxRetryDelay: TimeSpan.FromSeconds(1),
errorNumbersToAdd: null);
});
//else if(Environment.IsDevelopment())
//options.UseInMemoryDatabase(databaseName: "AbastecimentoDB");
});
services.AddHttpContextAccessor();
services.AddTransient<IComponenteService, ComponenteService>();
services.AddTransient<IReferenciaService, ReferenciaService>();
services.AddTransient<IRegistoService, RegistoService>();
services.AddTransient<IParagemService, ParagemService>();
}
// 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();
}
else
{
app.UseExceptionHandler("/Error");
}
app.UseNToastNotify();
app.UseAuthentication();
app.UseStaticFiles();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}
}
答案 0 :(得分:2)
对于HasArranqueActivoHandler
,您已经在ConfigureServices
中添加了服务注册:
services.AddTransient<IAuthorizationHandler, HasArranqueActivoHandler>();
您尚未为HasArranqueInactivoHandler
添加服务注册。添加以下内容:
services.AddTransient<IAuthorizationHandler, HasArranqueInactivoHandler>();
IAuthorizationHandler
的实现是从DI容器中解决的,因此缺少此注册意味着authz系统无法处理您为HasArranqueInactivoRequirement
策略设置的HasArranqueInactivo
要求。