Custom AuthorizationAttribute not working to allow access once user is authorized

60 views Asked by At

This is the attribute

[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, Inherited = true, AllowMultiple = true)]
public class MyAuthorize : Attribute, IAuthorizationFilter
{
    public void OnAuthorization(AuthorizationFilterContext context)
    {
        if (!IsAuthorized(context))
        {
            context.Result = new RedirectResult("/Account/Login", true);
        }
    }
    private bool IsAuthorized(AuthorizationFilterContext context)
    {
        return Current.IsAuthenticated;
    }
}

The following are a few snippets showing how the attribute is applied on Action methods in different controllers

//MergerController
[MyAuthorize]
        [HttpGet]
        public IActionResult ChooseSemester()
        {
            return View();
        }

//SessionController
[MyAuthorize]
        public async Task<IActionResult> EditGroups(bool firstSemester)
        {
            var response = await wrapper.Session.GetGroups();
            var groups = await response.Content.ReadFromJsonAsync<List<Lecture>>();

            return View("Groups", groups);
        }

//HomeController
[MyAuthorize]
        public IActionResult Profile()
        {
            return View(Current.User);
        }

        [MyAuthorize]
        [HttpPost]
        [ActionName("Profile")]
        public async Task<IActionResult> UpdateProfile(string id, string action, string newValue)
        {
            var user = Current.User;

            switch (id)
            {
                case "username": user.UserName = newValue; break;
                case "email": user.Email = newValue; break;
                case "mergeKey": user.MergeKey = newValue; break;
            }

            var result = await wrapper.User.Update(user);
            if (result.IsSuccessStatusCode)
                TempData["Message"] = "Your account detail(s) have successfully been updated";
            else
                TempData["Message"] = "Failed to update account detail(s)";

            return action == "mergeKey" ? RedirectToAction("Index") : RedirectToAction("Profile");
        }

I am able to successfully login with the following code

[AllowAnonymous]
        public IActionResult Login(string returnUrl)
        {
            return RedirectToAction("SignIn", new { returnUrl = returnUrl });
        }

        [AllowAnonymous]
        public IActionResult SignIn(string returnUrl)
        {
            return View(new LoginViewModel
            { ReturnUrl = returnUrl }
                        );
        }

        [HttpPost]
        [ValidateAntiForgeryToken]
        [AllowAnonymous]
        public async Task<IActionResult> Login(LoginViewModel loginModel)
        {
            if (ModelState.IsValid)
            {
                //login to the API
                var response = await _wrapper.Authorization.Login(loginModel);
                if (response.IsSuccessStatusCode)
                {
                    var user = await response.Content.ReadFromJsonAsync<BongoUser>();
                    Response.Cookies.Append("Notified", user.Notified.ToString().ToLower(),
                        new CookieOptions { Expires = DateTime.Now.AddDays(90) });
                    Current.User = user;

                    if (Current.User.SecurityQuestion != default)
                        return RedirectToAction("Index", "Home");
                    else
                        return RedirectToAction("SecurityQuestion", new { sendingAction = "LogIn" });
                }
                else
                {
                    ModelState.AddModelError("", "Something went wrong. Please try again and if the problem persists contact us.");
                    goto OnError;
                }

            }
            ModelState.AddModelError("", "Invalid email or password");
        OnError:
            return View("SignIn", loginModel);
        }

My goal here is to use an API, I am using the _wrapper object to do that using the repository pattern. I have since then disconnected the application from the database completely and it only connects to the API for any activities that require database connection and hence I removed the default [Authorize] attribute of ASP .Net Core because I cannot use User.IsAuthenticated and User.Identity.Name if I am not using userManager on the application itself to sign in.

Initially, I could not connect to the API and was having some issues. I have now kind of embedded the API into the appliction so I can work with it in that way to test the application. For reference, if you have time you can check the project on my github at https://github.com/MpofuO/Bongo4Students and the API at https://github.com/MpofuO/BongoAPI

0

There are 0 answers