Base solution for your next web application
Open Closed

Redirect authenticated user without permission to a page instead of login #7382


User avatar
0
MBTLGPLC19 created

Following the tip in https://support.aspnetzero.com/QA/Questions/4049#answer-447ec9e8-b664-4f5a-b75f-313a2a2236f3, I'm trying to do the same thing in an asp.net core 2.2 solution (redirect to a page if the user hasn't the permission, but is already logged). I have tried to implement my AbpMvcAuthorizeFilter class, but without sucess (I cannot resolve the AuthorizationContext sucessfully, even after adding all asp.net mvc dependences). I tried to create the middleware for changing the behavior, but I cannot see the status code forbidden or unauthorized after executing the call to be able to redirect as I want. Another thing: there's someway to avoid to hit the middleware's method everytime ? Like, if we already validated that the user has permission, we can leave the middleware.


5 Answer(s)
  • User Avatar
    0
    maliming created
    Support Team

    Can you share your complete code?

  • User Avatar
    0
    MBTLGPLC19 created

    My project is ASP.NET CORE 2.2 MVC & jQuery with Asp.NET Zero 7.0 and ABP 4.7

    My Middleware:

    using System; using System.Collections.Generic; using System.Linq; using System.Runtime.CompilerServices; using System.Threading.Tasks; using Abp.AspNetCore.Mvc.Authorization; using Abp.Authorization; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc.Filters;

    public class MyMvcAuthorizeMiddleware { private readonly RequestDelegate _next; private readonly IAuthorizationHelper _authorizationHelper;

     public MyMvcAuthorizeMiddleware(RequestDelegate next, IAuthorizationHelper authorizationHelper)
     {
         _next = next;
         _authorizationHelper = authorizationHelper;
     }
    
     public async Task Invoke(HttpContext context)
     {
         try
         {
             bool isAuthenticated = context.User?.Identity?.IsAuthenticated ?? false;
    
             await _next.Invoke(context);
            //  I never see status code 401 or 402 so that I can take any action
            // So, what I can do here?
         }
         catch (Exception e)
         {
             Console.WriteLine(e);
         }
     }
    

    }

    public static class MyMvcAuthorizeMiddlewareExtensions { public static IApplicationBuilder UseMyMvcAuthorize(this IApplicationBuilder builder) { return builder.UseMiddleware<MyMvcAuthorizeMiddleware>(); } }


    And my MyMvcAuthorizeFilter (that I tried to create following https://github.com/aspnetboilerplate/aspnetboilerplate/issues/1256#issuecomment-237463318):

    using Abp.Web.Mvc.Authorization; using System; using System.Collections.Generic; using System.Reflection; using System.Text; using Abp.Authorization; using Abp.Events.Bus; using Abp.Web.Models;

    public class MyMvcAuthorizeFilter : AbpMvcAuthorizeFilter { public MyMvcAuthorizeFilter(IAuthorizationHelper authorizationHelper, IErrorInfoBuilder errorInfoBuilder, IEventBus eventBus) : base(authorizationHelper, errorInfoBuilder, eventBus) { }

    protected override void HandleUnauthorizedRequest(System.Web.Mvc.AuthorizationContext filterContext, MethodInfo methodInfo,
        AbpAuthorizationException ex)
    {
        //base.HandleUnauthorizedRequest(filterContext, methodInfo, ex);
    
        //filterContext.HttpContext.Response.StatusCode
        // Even after adding Microsoft.AspNet.Mvc 5.2.7 to the project, I cannot access filterContext.HttpContext.Response
    }
    

    }

  • User Avatar
    0
    MBTLGPLC19 created

    Hi,

    While looking around some more (in the forum and ABP source code), I see that I should add my custom authorization filter (https://support.aspnetzero.com/QA/Questions/3126). I made some tests and it seems to work. I will continue to look at it. My question now is how do I remove or replace AbpAuthorizationFilter so that we have only MyAbpAuthorizationFilter registered?

  • User Avatar
    0
    maliming created
    Support Team

    hi

    Try adding the following code to ConfigureServices method.

    services.PostConfigure<MvcOptions>(options =>
    {
       for (var index = options.Filters.Count - 1; index >= 0; --index)
       {
          if (options.Filters[index] is ServiceFilterAttribute &&
             ((ServiceFilterAttribute)options.Filters[index]).ServiceType != typeof(AbpAuthorizationFilter))
          {
             continue;
          }
          options.Filters.RemoveAt(index);
    
          options.Filters.Insert(index, new ServiceFilterAttribute(typeof(MyAbpAuthorizationFilter))
          {
             Order = 0
          });
    
          break;
       }
    });
    
    
  • User Avatar
    0
    MBTLGPLC19 created

    That's exactly what I wanted! I didn't knew that we could use the PostConfigure like that. Thank you very much