我有一个奇怪的问题,无法调试。
我正在尝试使用OperationAuthorizationRequirement
和AuthorizationHandler
。
当我在控制器中放置断点时,我总是得到403结果,因此我试图将断点放置在CountryControllerAuthorizationHandler
内,并且它从未被触发。但是在控制器中,我总是得到AuthorizeAsync false
的结果,但是我不明白为什么我无法获得被击中或触发的断点。我在犯一些愚蠢的错误吗?无论如何,如我所见,资源是NOT null
,用户和声明也是NOT null
:
这是我的代码:
CountryControllerAuthorizationHandler:
public class CountryControllerAuthorizationHandler : AuthorizationHandler<OperationAuthorizationRequirement, Country>
{
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context,
OperationAuthorizationRequirement requirement,
Country resource)
{
if (requirement.Name == Operations.ReadDetail.Name &&
context.User.Claims.FirstOrDefault(a => a.Type == "userType")?.Value == "customer"
)
{
context.Succeed(requirement);
}
if (requirement.Name == Operations.Create.Name &&
context.User.Claims.FirstOrDefault(a => a.Type == "userType")?.Value == "1"
)
{
context.Succeed(requirement);
}
if (requirement.Name == Operations.Update.Name &&
context.User.Claims.FirstOrDefault(a => a.Type == "userType")?.Value == "1"
)
{
context.Succeed(requirement);
}
if (requirement.Name == Operations.Delete.Name &&
context.User.Claims.FirstOrDefault(a => a.Type == "userType")?.Value == "1"
)
{
context.Succeed(requirement);
}
return Task.CompletedTask;
}
}
Operations类:
public static class Operations
{
public static OperationAuthorizationRequirement Create =
new OperationAuthorizationRequirement { Name = nameof(Create) };
public static OperationAuthorizationRequirement Read =
new OperationAuthorizationRequirement { Name = nameof(Read) };
public static OperationAuthorizationRequirement ReadDetail =
new OperationAuthorizationRequirement { Name = nameof(ReadDetail) };
public static OperationAuthorizationRequirement Update =
new OperationAuthorizationRequirement { Name = nameof(Update) };
public static OperationAuthorizationRequirement Delete =
new OperationAuthorizationRequirement { Name = nameof(Delete) };
}
Startup.cs:
services.AddSingleton<IAuthorizationHandler, CountryControllerAuthorizationHandler>();
services.AddMvcCore()
.AddAuthorization()
.AddJsonFormatters();
services.AddAuthentication("Bearer")
.AddIdentityServerAuthentication(options =>
{
options.Authority = "http://localhost:5000";
options.RequireHttpsMetadata = false;
options.ApiName = "api1";
});
最后是控制器:
public CountriesController(ICountryService service, IAuthorizationService authorizationService)
{
_authorizationService = authorizationService;
this.countryService = service;
}
public async Task<object> GetDetail()
{
var obj = countryService.Get_DETAILS();
var authorizationResult = await _authorizationService.AuthorizeAsync(User, obj, Operations.ReadDetail);
if (authorizationResult.Succeeded)
{
return Ok(obj);
}
else if (User.Identity.IsAuthenticated)
{
return new ForbidResult();
}
else
{
return new ChallengeResult();
}
}
答案 0 :(得分:0)
确保countryService.Get_DETAILS()
为不为空,并且仅返回一个国家/地区。
对于CountryControllerAuthorizationHandler
,它接受Country
,因此,仅传递了一个县对象的对象将被传递到HandleRequirementAsync
中。
HandleRequirementAsync
由HandleAsync
中的AuthorizationHandler
调用。
尝试使用以下代码进行测试,以调试未调用HandleRequirementAsync
的原因。
public class CountryControllerAuthorizationHandler : AuthorizationHandler<OperationAuthorizationRequirement, Country>
{
public override async Task HandleAsync(AuthorizationHandlerContext context)
{
if (context.Resource is Country)
{
foreach (var req in context.Requirements.OfType<OperationAuthorizationRequirement>())
{
await HandleRequirementAsync(context, req, (Country)context.Resource);
}
}
}
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context,
OperationAuthorizationRequirement requirement,
Country resource)
{
if (requirement.Name == Operations.ReadDetail.Name &&
context.User.Claims.FirstOrDefault(a => a.Type == "userType")?.Value == "customer"
)
{
context.Succeed(requirement);
}
if (requirement.Name == Operations.Create.Name &&
context.User.Claims.FirstOrDefault(a => a.Type == "userType")?.Value == "1"
)
{
context.Succeed(requirement);
}
if (requirement.Name == Operations.Update.Name &&
context.User.Claims.FirstOrDefault(a => a.Type == "userType")?.Value == "1"
)
{
context.Succeed(requirement);
}
if (requirement.Name == Operations.Delete.Name &&
context.User.Claims.FirstOrDefault(a => a.Type == "userType")?.Value == "1"
)
{
context.Succeed(requirement);
}
return Task.CompletedTask;
}
}