Home > Mobile >  In ASP.NET Core 6, is there a way to restrict certain action methods based on which URL is used?
In ASP.NET Core 6, is there a way to restrict certain action methods based on which URL is used?

Time:01-31

In a default ASP.NET Core web API app targetting .NET 6, by default it exposes two URL endpoints: one at http://localhost:50xx and an another at https://localhost:70xx.

What I want to do is use the first (http) for internal/trusted client requests, and the second (https) for internet/public requests. So naturally I want to treat requests differently depending on which one the request comes in on.

For both types of requests I want to use simple/default route matching, however, for HTTPS requests I want to enact a whitelist on selected action methods. The effect would be that most requests are simply not available over HTTPS.

I feel like there must be some simple way to do this, as the framework (and the default app template) seems to already get the ball rolling in this direction by providing both URLs... there's got to be some convenience methods that do just what I'm describing, but I have not come across them in the documentation.

Thanks

CodePudding user response:

Implement and apply a global custom ActionFilterAttribute that disallows HTTPS requests except for Controllers/Actions with a custom attribute applied.

1. Create a custom attribute which will be applied to contoller/methods that support HTTPS requests:

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class AllowHttpsAttribute : Attribute { }

2. Create a custom ActionFilterAttribute that short-circuits requests made over HTTPS when the controller or action does not have the AllowHttpsAttribute applied (short-circitung is accomplished by assigning a value to context.Result):

public class HttpOnlyActionFilter : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext context)
    {
        var isHttps = context.HttpContext.Request.Scheme == Uri.UriSchemeHttps;
        if (isHttps && HttpsNotSupported(context))
        {
            context.Result = new BadRequestResult();
        }
    }

    private bool HttpsNotSupported(ActionContext context)
    {
        return context.ActionDescriptor is ControllerActionDescriptor x &&
        !x.ControllerTypeInfo.GetCustomAttributes<AllowHttpsAttribute>().Any() &&
        !x.MethodInfo.GetCustomAttributes<AllowHttpsAttribute>().Any();
    }
}

3. Apply the HttpOnlyActionFilter globally (In Program.cs):

builder.Services.AddControllers(x => x.Filters.Add<HttpOnlyActionFilter>());

Usage:

Applied to Action:

public class Controller : ControllerBase
{
    // Allow requests over HTTPS 
    [HttpGet, AllowHttps]
    public ActionResult Action1() => ...;

    // Disallow requests over HTTPS 
    [HttpGet]
    public ActionResult Action2() => ...;
}

Applied to Controller:

[AllowHttps] // Allow requests over HTTPS 
public class Controller : ControllerBase
{
  ...
}
  •  Tags:  
  • Related