How to check/redirect in every method of any controller in ASP NET Core 3.1?

I’m looking for a way to do this in every Method of every Controller, even for those that doesn’t return an IActionResult (I’ll talking about this forward):

  1. Get User.Claim to get the user info logged into the site.
  2. Check if the user is blocked in the database (I’ve my own repositories working already)
  3. Redirect a user to a Page that shows “you are blocked” like the workflow of Exceptions does.

Considerations and tries that I already made:

  • Can’t get this from a Claim in order to work it with ViewStart because I need the block works in the same moment the database were updated. The Claim should the user sign out and sign in.
  • Can’t do this trough a controller that returns a boolean with Json in
    every page because the user could stop the redirect
  • I’ve several methods that returns partialviews, objects, lists, anything but IActionResult. I don’t care if that doesn’t work for two reasons:
    • It should be triggered by the main view that calls those through ajax.
    • The user is blocked anyway so I don’t care if it see the page broken.
  • My security workflow is like this:
    [HttpPost]
    [Authorize(Policy = "Users")]
    [Authorize(AuthenticationSchemes = "MyAppScheme")]
    
    public IActionResult GetRep() {
         //Do things
    }

Right now I’m trying do a middleware but I’m new in NET Core at so deep level, so can’t compile neither. Also working trying to call my userRepository from the ViewStart

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

The best way is using a middleware. Here you have an example:

internal class UserMiddleware
{
    private readonly RequestDelegate next;
    private readonly IUserRepository userRepository;

    public UserMiddleware(RequestDelegate next, IUserRepository userRepository)
    {
        this.next = next ?? throw new ArgumentNullException(nameof(next));
        this.userRepository = userRepository ?? throw new ArgumentNullException(nameof(userRepository));
    }

    public async Task Invoke(HttpContext httpContext)
    {
        Claim clientId = httpContext.User.FindFirst(ClaimTypes.NameIdentifier);
        bool isBlocked = await this.userRepository.CheckUser(clientId);

        if (isBlocked)
        {
            await httpContext.Response.WriteAsync("You are blocked.");
            return;
        }

        await this.next(httpContext);
    }
}

Then in your startup method you should call it before mapping your controllers:

public static void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    // Other stuff...

    app.UseMiddleware<UserMiddleware>();
    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();
    });
}


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x