controller security with the same service.

This commit is contained in:
David Lebee 2021-02-04 21:09:29 -05:00
parent 3e6c76ab18
commit d68f87028d
8 changed files with 137 additions and 5 deletions

View File

@ -11,7 +11,7 @@ namespace PoweredSoft.CQRS.AspNetCore.Mvc
public class CommandController<TCommand> : Controller
where TCommand : class
{
[HttpPost]
[HttpPost, CommandControllerAuthorization]
public async Task<IActionResult> Handle([FromServices] ICommandHandler<TCommand> handler,
[FromBody] TCommand command)
{
@ -27,7 +27,7 @@ namespace PoweredSoft.CQRS.AspNetCore.Mvc
public class CommandController<TCommand, TTCommandResult> : Controller
where TCommand : class
{
[HttpPost]
[HttpPost, CommandControllerAuthorization]
public async Task<ActionResult<TTCommandResult>> Handle([FromServices] ICommandHandler<TCommand, TTCommandResult> handler,
[FromBody] TCommand command)
{

View File

@ -0,0 +1,44 @@
using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.DependencyInjection;
using System.Linq;
using Microsoft.AspNetCore.Mvc;
using System.Reflection;
using PoweredSoft.CQRS.Abstractions.Security;
namespace PoweredSoft.CQRS.AspNetCore.Mvc
{
public class CommandControllerAsyncAuthorizationFilter : IAsyncAuthorizationFilter
{
private readonly ICommandAuthorizationService _authorizationService;
public CommandControllerAsyncAuthorizationFilter(IServiceProvider serviceProvider)
{
_authorizationService = serviceProvider.GetService<ICommandAuthorizationService>();
}
public async Task OnAuthorizationAsync(AuthorizationFilterContext context)
{
if (_authorizationService == null)
return;
var action = context.ActionDescriptor as Microsoft.AspNetCore.Mvc.Controllers.ControllerActionDescriptor;
if (action == null)
throw new Exception("Only Supports controller action descriptor");
var attribute = action.MethodInfo.GetCustomAttribute<CommandControllerAuthorizationAttribute>();
Type commandType;
if (attribute?.CommandType != null)
commandType = attribute.CommandType;
else
commandType = action.ControllerTypeInfo.GenericTypeArguments.First();
var ar = await _authorizationService.IsAllowedAsync(commandType);
if (ar == AuthorizationResult.Forbidden)
context.Result = new StatusCodeResult(403);
else if(ar == AuthorizationResult.Unauthorized)
context.Result = new StatusCodeResult(401);
}
}
}

View File

@ -0,0 +1,21 @@
using System;
using Microsoft.AspNetCore.Mvc;
namespace PoweredSoft.CQRS.AspNetCore.Mvc
{
[AttributeUsage(AttributeTargets.Method)]
public class CommandControllerAuthorizationAttribute : TypeFilterAttribute
{
public CommandControllerAuthorizationAttribute() : base(typeof(CommandControllerAsyncAuthorizationFilter))
{
}
public CommandControllerAuthorizationAttribute(Type commandType) : base(typeof(CommandControllerAsyncAuthorizationFilter))
{
CommandType = commandType;
}
public Type CommandType { get; } = null;
}
}

View File

@ -11,7 +11,7 @@ namespace PoweredSoft.CQRS.AspNetCore.Mvc
public class QueryController<TQuery, TQueryResult> : Controller
where TQuery : class
{
[HttpPost]
[HttpPost, QueryControllerAuthorization]
public async Task<ActionResult<TQueryResult>> Handle([FromServices] IQueryHandler<TQuery, TQueryResult> handler,
[FromBody] TQuery query)
{

View File

@ -0,0 +1,44 @@
using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.DependencyInjection;
using System.Linq;
using Microsoft.AspNetCore.Mvc;
using System.Reflection;
using PoweredSoft.CQRS.Abstractions.Security;
namespace PoweredSoft.CQRS.AspNetCore.Mvc
{
public class QueryControllerAsyncAuthorizationFilter : IAsyncAuthorizationFilter
{
private readonly IQueryAuthorizationService _authorizationService;
public QueryControllerAsyncAuthorizationFilter(IServiceProvider serviceProvider)
{
_authorizationService = serviceProvider.GetService<IQueryAuthorizationService>();
}
public async Task OnAuthorizationAsync(AuthorizationFilterContext context)
{
if (_authorizationService == null)
return;
var action = context.ActionDescriptor as Microsoft.AspNetCore.Mvc.Controllers.ControllerActionDescriptor;
if (action == null)
throw new Exception("Only Supports controller action descriptor");
var attribute = action.MethodInfo.GetCustomAttribute<QueryControllerAuthorizationAttribute>();
Type queryType;
if (attribute?.QueryType != null)
queryType = attribute.QueryType;
else
queryType = action.ControllerTypeInfo.GenericTypeArguments.First();
var ar = await _authorizationService.IsAllowedAsync(queryType);
if (ar == AuthorizationResult.Forbidden)
context.Result = new StatusCodeResult(403);
else if (ar == AuthorizationResult.Unauthorized)
context.Result = new StatusCodeResult(401);
}
}
}

View File

@ -0,0 +1,21 @@
using System;
using Microsoft.AspNetCore.Mvc;
namespace PoweredSoft.CQRS.AspNetCore.Mvc
{
[AttributeUsage(AttributeTargets.Method)]
public class QueryControllerAuthorizationAttribute : TypeFilterAttribute
{
public QueryControllerAuthorizationAttribute() : base(typeof(QueryControllerAsyncAuthorizationFilter))
{
}
public QueryControllerAuthorizationAttribute(Type queryType) : base(typeof(QueryControllerAsyncAuthorizationFilter))
{
QueryType = queryType;
}
public Type QueryType { get; } = null;
}
}

View File

@ -1,4 +1,5 @@
using Microsoft.AspNetCore.Mvc;
using PoweredSoft.CQRS.AspNetCore.Mvc;
using PoweredSoft.CQRS.DynamicQuery.Abstractions;
using PoweredSoft.DynamicQuery.Core;
using System;
@ -13,7 +14,7 @@ namespace PoweredSoft.CQRS.DynamicQuery.AspNetCore.Mvc
where TSource : class
where TDestination : class
{
[HttpPost]
[HttpPost, QueryControllerAuthorization]
public async Task<IQueryExecutionResult<TDestination>> HandleAsync(
[FromBody] DynamicQuery<TSource, TDestination> query,
[FromServices]PoweredSoft.CQRS.Abstractions.IQueryHandler<IDynamicQuery<TSource, TDestination>, IQueryExecutionResult<TDestination>> queryHandler
@ -30,7 +31,7 @@ namespace PoweredSoft.CQRS.DynamicQuery.AspNetCore.Mvc
where TDestination : class
where TParams : class
{
[HttpPost]
[HttpPost, QueryControllerAuthorization]
public async Task<IQueryExecutionResult<TDestination>> HandleAsync(
[FromBody] DynamicQuery<TSource, TDestination, TParams> query,
[FromServices] PoweredSoft.CQRS.Abstractions.IQueryHandler<IDynamicQuery<TSource, TDestination, TParams>, IQueryExecutionResult<TDestination>> queryHandler

View File

@ -11,6 +11,7 @@
<ItemGroup>
<ProjectReference Include="..\PoweredSoft.CQRS.Abstractions\PoweredSoft.CQRS.Abstractions.csproj" />
<ProjectReference Include="..\PoweredSoft.CQRS.AspNetCore.Abstractions\PoweredSoft.CQRS.AspNetCore.Abstractions.csproj" />
<ProjectReference Include="..\PoweredSoft.CQRS.AspNetCore\PoweredSoft.CQRS.AspNetCore.csproj" />
<ProjectReference Include="..\PoweredSoft.CQRS.DynamicQuery.Abstractions\PoweredSoft.CQRS.DynamicQuery.Abstractions.csproj" />
<ProjectReference Include="..\PoweredSoft.CQRS.DynamicQuery\PoweredSoft.CQRS.DynamicQuery.csproj" />
</ItemGroup>