在 AuthorizationHandler 中使用 `await`
Using `await` in AuthorizationHandler
我有一个 AuthorizationHandler,它依赖于为 .NET Core 3.1 的授权中间件提供异步方法的服务。我已经在 HandleRequirementAsync
方法中调用了其中一些异步方法。整体代码如下所示:
{
public class MyAuthorizationHandler : AuthorizationHandler<MyRequirement, Tuple<string, string>>
{
private readonly IAuthIntelRepository authIntelRepository;
public UserAssistanceAuthorizationHandler(IAuthIntelRepository authIntelRepository)
{
this.authIntelRepository = authIntelRepository;
}
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, MyRequirement requirement, Tuple<string, string> someRessource)
{
//some async calls to authIntelRepository
if (/*someCondition*/false)
{
context.Succeed(requirement);
}
return Task.CompletedTask;
}
}
public class MyRequirement : IAuthorizationRequirement { }
}
不过,一旦我使用 await
语句,我就会收到一个错误消息,指出签名未明确设置为异步。将 async
添加到继承方法的签名会导致以下错误。
a return keyword must not be followed by an object expression. Did you intend to return 'Task<T>'?
线程阐述了类似的问题,但该解决方案似乎在 .NET Core 3.1 中不起作用。
按以下方式使用 Result 是可行的,但据我所知,这将导致调用阻塞:
Task<Object> obj= this.authIntelRepository.getSomeAsync(...);
obj.Result.property //do Something to check the requirement
我不确定这里的正确解决方案是什么样的。
如果您的 async
方法的 return 类型是 Task
,那么,除了 await
关键字外,您将方法视为 void
returning:
protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context, MyRequirement requirement, Tuple<string, string> someRessource)
{
await authIntelRepository....
if (/*someCondition*/false)
{
context.Succeed(requirement);
}
return;
}
在HandleRequirementAsync中添加async并使用await调用HandleRequirementAsync内部的async方法破坏了授权,尝试调用外部db或httpClient(延迟),在浏览器中输入授权的路由地址。即使执行了 context.Succeed(requirement),路由也会被重定向到非授权页面。
我的工作解决方案 (blazor server .NET 5) 保持 HandleRequirementAsync 不变,执行我们需要调用的异步方法,使用在非异步方法中执行异步方法的模式。
我的示例工作代码来自
我的示例异步方法:
public async Task<IList<Permission>> GetGroupPermissions(int userId)
{
HttpResponseMessage response = await _httpClient.GetAsync(string.Format("Auth/GroupPermissions/{0}", userId));
try
{
var payload = await response.Content.ReadFromJsonAsync<List<Permission>>();
response.EnsureSuccessStatusCode();
return payload;
}
catch
{
return new List<Permission>();
}
}
HandleRequirementAsync:
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, PermissionRequirement requirement)
{
var t2 = (Task.Run(() => GetGroupPermissions(userId)));
t2.Wait();
var userGroupPermissions = t2.Result;
if (!userGroupPermissions.Contains(requirement.Permission))
{
//context.Fail(); //no need to fail, other requirement might success
return Task.CompletedTask;
}
context.Succeed(requirement);
return Task.CompletedTask;
}
我有一个 AuthorizationHandler,它依赖于为 .NET Core 3.1 的授权中间件提供异步方法的服务。我已经在 HandleRequirementAsync
方法中调用了其中一些异步方法。整体代码如下所示:
{
public class MyAuthorizationHandler : AuthorizationHandler<MyRequirement, Tuple<string, string>>
{
private readonly IAuthIntelRepository authIntelRepository;
public UserAssistanceAuthorizationHandler(IAuthIntelRepository authIntelRepository)
{
this.authIntelRepository = authIntelRepository;
}
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, MyRequirement requirement, Tuple<string, string> someRessource)
{
//some async calls to authIntelRepository
if (/*someCondition*/false)
{
context.Succeed(requirement);
}
return Task.CompletedTask;
}
}
public class MyRequirement : IAuthorizationRequirement { }
}
不过,一旦我使用 await
语句,我就会收到一个错误消息,指出签名未明确设置为异步。将 async
添加到继承方法的签名会导致以下错误。
a return keyword must not be followed by an object expression. Did you intend to return 'Task<T>'?
按以下方式使用 Result 是可行的,但据我所知,这将导致调用阻塞:
Task<Object> obj= this.authIntelRepository.getSomeAsync(...);
obj.Result.property //do Something to check the requirement
我不确定这里的正确解决方案是什么样的。
如果您的 async
方法的 return 类型是 Task
,那么,除了 await
关键字外,您将方法视为 void
returning:
protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context, MyRequirement requirement, Tuple<string, string> someRessource)
{
await authIntelRepository....
if (/*someCondition*/false)
{
context.Succeed(requirement);
}
return;
}
在HandleRequirementAsync中添加async并使用await调用HandleRequirementAsync内部的async方法破坏了授权,尝试调用外部db或httpClient(延迟),在浏览器中输入授权的路由地址。即使执行了 context.Succeed(requirement),路由也会被重定向到非授权页面。
我的工作解决方案 (blazor server .NET 5) 保持 HandleRequirementAsync 不变,执行我们需要调用的异步方法,使用在非异步方法中执行异步方法的模式。
我的示例工作代码来自
我的示例异步方法:
public async Task<IList<Permission>> GetGroupPermissions(int userId)
{
HttpResponseMessage response = await _httpClient.GetAsync(string.Format("Auth/GroupPermissions/{0}", userId));
try
{
var payload = await response.Content.ReadFromJsonAsync<List<Permission>>();
response.EnsureSuccessStatusCode();
return payload;
}
catch
{
return new List<Permission>();
}
}
HandleRequirementAsync:
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, PermissionRequirement requirement)
{
var t2 = (Task.Run(() => GetGroupPermissions(userId)));
t2.Wait();
var userGroupPermissions = t2.Result;
if (!userGroupPermissions.Contains(requirement.Permission))
{
//context.Fail(); //no need to fail, other requirement might success
return Task.CompletedTask;
}
context.Succeed(requirement);
return Task.CompletedTask;
}