Skip to content

Commit

Permalink
Enable reuse of BackOfficeSecurityRequirementsOperationFilter for cus…
Browse files Browse the repository at this point in the history
…tom APIs (#15699)
  • Loading branch information
kjac committed Feb 13, 2024
1 parent 690bfe3 commit 4f04669
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 50 deletions.
@@ -1,56 +1,8 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.SwaggerGen;
using Umbraco.Cms.Api.Management.DependencyInjection;
using Umbraco.Extensions;

namespace Umbraco.Cms.Api.Management.OpenApi;

internal class BackOfficeSecurityRequirementsOperationFilter : IOperationFilter
internal class BackOfficeSecurityRequirementsOperationFilter : BackOfficeSecurityRequirementsOperationFilterBase
{
public void Apply(OpenApiOperation operation, OperationFilterContext context)
{
if (context.MethodInfo.HasMapToApiAttribute(ManagementApiConfiguration.ApiName) == false)
{
return;
}

if (!context.MethodInfo.GetCustomAttributes(true).Any(x => x is AllowAnonymousAttribute) &&
!(context.MethodInfo.DeclaringType?.GetCustomAttributes(true).Any(x => x is AllowAnonymousAttribute) ?? false))
{
operation.Responses.Add(StatusCodes.Status401Unauthorized.ToString(), new OpenApiResponse
{
Description = "The resource is protected and requires an authentication token"
});

operation.Security = new List<OpenApiSecurityRequirement>
{
new OpenApiSecurityRequirement
{
{
new OpenApiSecurityScheme
{
Reference = new OpenApiReference
{
Type = ReferenceType.SecurityScheme,
Id = ManagementApiConfiguration.ApiSecurityName
}
}, new string[] { }
}
}
};
}


// If method/controller has an explicit AuthorizeAttribute or the controller ctor injects IAuthorizationService, then we know Forbid result is possible.
if (context.MethodInfo.GetCustomAttributes(false).Any(x => x is AuthorizeAttribute
|| context.MethodInfo.DeclaringType?.GetConstructors().Any(x => x.GetParameters().Any(x => x.ParameterType == typeof(IAuthorizationService))) is true))
{
operation.Responses.Add(StatusCodes.Status403Forbidden.ToString(), new OpenApiResponse
{
Description = "The authenticated user do not have access to this resource"
});
}
}
protected override string ApiName => ManagementApiConfiguration.ApiName;
}
@@ -0,0 +1,58 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.SwaggerGen;
using Umbraco.Cms.Api.Management.DependencyInjection;
using Umbraco.Extensions;

namespace Umbraco.Cms.Api.Management.OpenApi;

public abstract class BackOfficeSecurityRequirementsOperationFilterBase : IOperationFilter
{
protected abstract string ApiName { get; }

public void Apply(OpenApiOperation operation, OperationFilterContext context)
{
if (context.MethodInfo.HasMapToApiAttribute(ApiName) == false)
{
return;
}

if (!context.MethodInfo.GetCustomAttributes(true).Any(x => x is AllowAnonymousAttribute) &&
!(context.MethodInfo.DeclaringType?.GetCustomAttributes(true).Any(x => x is AllowAnonymousAttribute) ?? false))
{
operation.Responses.Add(StatusCodes.Status401Unauthorized.ToString(), new OpenApiResponse
{
Description = "The resource is protected and requires an authentication token"
});

operation.Security = new List<OpenApiSecurityRequirement>
{
new OpenApiSecurityRequirement
{
{
new OpenApiSecurityScheme
{
Reference = new OpenApiReference
{
Type = ReferenceType.SecurityScheme,
Id = ManagementApiConfiguration.ApiSecurityName
}
}, new string[] { }
}
}
};
}


// If method/controller has an explicit AuthorizeAttribute or the controller ctor injects IAuthorizationService, then we know Forbid result is possible.
if (context.MethodInfo.GetCustomAttributes(false).Any(x => x is AuthorizeAttribute
|| context.MethodInfo.DeclaringType?.GetConstructors().Any(x => x.GetParameters().Any(x => x.ParameterType == typeof(IAuthorizationService))) is true))
{
operation.Responses.Add(StatusCodes.Status403Forbidden.ToString(), new OpenApiResponse
{
Description = "The authenticated user do not have access to this resource"
});
}
}
}

0 comments on commit 4f04669

Please sign in to comment.