Zain Malik
Zain Malik

Reputation: 141

How to use custom middleware in ASP.NET Core only when request is authorized?

I have developed a custom middleware in ASP.NET Core but it gets triggered with every request. My intent is to use it only when a request is authorized.

Upvotes: 5

Views: 7695

Answers (2)

AmirReza-Farahlagha
AmirReza-Farahlagha

Reputation: 1212

Update:

I create more sample for you and edit my answer. as you see, before the Next() method, I checked every token request. If didn't have Authorization tag in header of context request, be next(), If did check the token.

Now, may you have a question that what is the await _next(context); It is very complex and long, I want to suggest you that visit this link to know what is this issue.

For Create a Middlware you have to control and develop.

  1. Create Generally class as Middleware that work General action like you action Authorization.
  2. Create a static Extension class for relation between Middleware and startup.
  3. And finally Register in startup configuration.

Now this is good sample for you:

General Middlware:

public class RequestTokenMiddleware
    {
        private readonly RequestDelegate _next;
        private readonly SignInManager<User> _signInManager;

        public RequestTokenMiddleware(RequestDelegate next, SignInManager<User> signInManager)
        {
            _next = next;
            _signInManager = signInManager;
        }

        public async Task Invoke(HttpContext context)
        {
            try
            {
                var hasAuthorization = context.Request.Headers.ContainsKey("Authorization");
            if (!hasAuthorization)
            {
                await _next(context); 
            }
            else
            {
                var shouldBeNext = false;
                foreach (var item in context.Request.Headers)
                {
                    if (item.Key == "Authorization")
                    {
                        using (var contextBudget = BudgetUnitOfWork.Get())
                        {

                            var tokenCode = item.Value.ToString().Remove(0, 7);
                            var token = await contextBudget.Db.Token.FirstOrDefaultAsync(x => x.TokenCode == tokenCode).ConfigureAwait(false);
                            if (token == null || !token.IsValid)
                            {
                                signOut(context);
                            }
                            else
                            {
                                shouldBeNext = true;
                            }
                        }
                    }
                }
                if (shouldBeNext)
                {
                    await _next(context);
                }

            }
            }
            catch (Exception exc)
            {
                signOut(context);
            }
        }

        private async void signOut(HttpContext context)
        {
            try
            {
                await context.Response.WriteAsync(JsonConvert.SerializeObject(ResultModel.Failure(null, ResultModel.StatusType.InvalidToken)));
            }
            catch (Exception)
            {
                throw new Exception();
            }
        }
    }

This is Static Extension class for Relation:

public static class ReuqestTokenMiddlewareExctention
    {
        public static IApplicationBuilder UseTokenValidator(this IApplicationBuilder applicationBuilder)
        {
            return applicationBuilder.UseMiddleware<RequestTokenMiddleware>();
        }
    }

Now Register your Middleware in startup:

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, IOptions<SetiaSettings> options)
{

     app.UseTokenValidator();
}

Upvotes: 9

Greg
Greg

Reputation: 11480

I believe you have a misunderstanding of middleware. Fundamentally middleware is software that will be assembled into the application pipeline to manage each request and response.

That means that middleware is executed every time.

An important concept though, would be how middleware handles each component. In essence top down execution, all allowed code will execute unless conditionally stated otherwise.

  • Chooses whether to pass the request to the next component in the pipeline.
  • Can perform work before and after the next component in the pipeline is invokved.

So your early statement is the behavior you should experience, but now you have to ensure the request being instantiated is allowed to execute or not. Your approach for security would basically be in your middleware, allowing that authorization to occur.

An example would be the authorize attribute, but I am not sure what authorization / authentication mechanism you are using.

To explicitly answer your question, you could do something along these lines:

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc();

    services.AddAuthorization(options =>
    {
        options.AddPolicy("RequireAdministratorRole", policy => policy.RequireRole("Administrator"));
    });
}

Upvotes: 1

Related Questions