How can pass data from AuthorizationHandler to Controller in Asp.net core

后端 未结 1 1033
小蘑菇
小蘑菇 2021-01-05 19:26

I used a specific authorization policy for user log in, so created custom Authorization Handler. And I would like to display use a specific alert message if they failed the

1条回答
  •  礼貌的吻别
    2021-01-05 19:56

    Use TempData to show your message

    There are you need ITempDataDictionaryFactory and IHttpContextAccessor or for context you can get from mvcContext.HttpContext

    if (context.HasFailed && context.Resource is AuthorizationFilterContext mvcContext)
    {
        var tempData = _tempDataDictionaryFactory.GetTempData(mvcContext.HttpContext);
        tempData["message"] = "alert message";
    }
    

    then you can get it in Login method via TempData

    public IActionResult Login()
    {
        string message = null;
        var item = TempData.FirstOrDefault(x =>x.Key == key);
    
        if (item.Value != null)
        {
            message = (string)item.Value;
        }
    
         return View();
    }
    

    Why your code not working:

    HttpContext creating per request it means that you inserting mvcContext.HttpContext.Items["message"] = "alert message"; will be able only for current request, when you use Authorization in controller or his method it will insert you message to current request and redirect to your AccessDeniedPath or LoginPath and new HttpContext will be created for this request without your message. To share some info between requests you can use TempData or other methods.

    Update Try to get httpContext from accessor Here full code

    add to startup services.AddSingleton();

    public class CustomRequirementHandler : AuthorizationHandler
        {
            private readonly IHttpContextAccessor _httpContext;
            private readonly ITempDataDictionaryFactory _tempDataDictionaryFactory;
    
            public CustomRequirementHandler(IHttpContextAccessor httpContext, ITempDataDictionaryFactory tempDataDictionary)
            {
                _httpContext = httpContext;
                _tempDataDictionaryFactory = tempDataDictionary;
            }
    
            protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, CustomRequirement requirement)
            {
                ///////
                //Your logic
                ///////
    
                if (context.HasFailed)
                {
                    var tempData = _tempDataDictionaryFactory.GetTempData(_httpContext.HttpContext);
                    tempData["message"] = "alert message";
                }
    
                return Task.CompletedTask;
            }
        }
    

    UPDATE When context.Fail(); performed tempData dont injecting via tempdata provider but you can call tempdata provider for executing manual save

    Here example:

    public class CustomRequirementHandler : AuthorizationHandler
    {
        private readonly ITempDataProvider _tempDataProvider;
    
        public CustomRequirementHandler(ITempDataProvider tempDataProvider)
        {
            _tempDataProvider = tempDataProvider;
        }
    
        protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, CustomRequirement requirement)
        {
            ///////
            //Your logic
            ///////
            context.Fail();
    
    
            if (context.HasFailed && context.Resource is AuthorizationFilterContext mvcContext)
            {
                _tempDataProvider.SaveTempData(mvcContext.HttpContext, new Dictionary() {  { "message","alertmessage "+DateTime.Now } });
            }
    
            return Task.CompletedTask;
        }
    }
    

    0 讨论(0)
提交回复
热议问题