.net core API and UI authorization with cookie and session

Last Reply 8 days ago By dharmendr

Posted 8 days ago

Hello all,

I am working on some final touches with this project before it goes into production.

I currently have everything with API and UI talking correctly and passing data back and forth.

Here is one thing I am confused about tho.

When I login on the UI it goes to the API and checks credentials and sends back a model with the main data to the UI. I store this in a session so I can use it later on. I try to add it to my httpcontext.user.identity and claims but they are always null, even after I signing and add them to it.

My login on the UI is this:

        [HttpPost]
        public async Task<IActionResult> Login(LoginVM loginVM)
        {
            if (ModelState.IsValid)
            {
                AuthUserVM authUserVM = null;
                using (var client = _httpClient.CreateClient("UserAPI"))
                {
                    try
                    {
                        using var httpResponse = await client.PostAsync($"/api/Users/Login/",
                                    new StringContent(JsonSerializer.Serialize(loginVM), Encoding.UTF8, "application/json"));
                        if (httpResponse.IsSuccessStatusCode)
                        {                          
                            using var responseStream = await httpResponse.Content.ReadAsStreamAsync();
                            string token = await JsonSerializer.DeserializeAsync<string>(responseStream);
                            var role = UserHelper.GetClaim(token, ClaimTypes.Role);
                            var username = UserHelper.GetClaim(token, "sub");
                            var email = UserHelper.GetClaim(token, "email");
                            var guid = UserHelper.GetClaim(token, "sid");
                            var createdTime = UserHelper.GetClaim(token, "auth_time");
                            var subscribed = UserHelper.GetClaim(token, "Subscribed");
                            var subscribedDate = UserHelper.GetClaim(token, "SubscribedDate");
                            authUserVM = new AuthUserVM
                            {
                                UserGUID = guid,
                                Username = username,
                                Email = email,
                                Role = role,
                                Token = token,
                                IsSubscribed = Convert.ToBoolean(subscribed),
                                Subscribed = subscribedDate
                            };
                            //ViewBag.Account = authUserVM as AuthUserVM;
                            ////TempData["Account"] = authUserVM;
                            //ViewData["Account"] = authUserVM as AuthUserVM;
                            //ViewBag.Accountjson = JsonSerializer.Serialize(authUserVM);
                            //TempData["test"] = "test string";
                            //TempData["AccountJson"] = JsonSerializer.Serialize(authUserVM);

                            HttpContext.Session.SetString("sGUID", guid);
                            HttpContext.Session.SetString("sAccount", JsonSerializer.Serialize(authUserVM));
                            HttpContext.Session.SetString("sRole", role);
                            //HttpContext.Session.SetObjectAsJson()
                            //var xz = HttpContext.Session.GetObjectFromJson<UserVM>("x");

                            List<Claim> lstClaims = new List<Claim>();
                            lstClaims.Add(new Claim(ClaimTypes.Role, role));
                            lstClaims.Add(new Claim("sub", username));
                            lstClaims.Add(new Claim("sid", guid));
                            lstClaims.Add(new Claim("token", token));
                            #region Single Claims
                            //var roleClaim = new Claim(ClaimTypes.Role, role);
                            //var usernameClaim = new Claim("sub", username);
                            //var guidClaim = new Claim("sid", guid);
                            //var tokenClaim = new Claim("token", token); 
                            #endregion

                            var claimsIdentity = new ClaimsIdentity(lstClaims, CookieAuthenticationDefaults.AuthenticationScheme);
                            var authProperties = new AuthenticationProperties
                            {
                                //AllowRefresh = <bool>,
                                // Refreshing the authentication session should be allowed.

                                //ExpiresUtc = DateTimeOffset.UtcNow.AddMinutes(10),

                                // The time at which the authentication ticket expires. A 
                                // value set here overrides the ExpireTimeSpan option of 
                                // CookieAuthenticationOptions set with AddCookie.

                                IsPersistent = false,
                                // Whether the authentication session is persisted across 
                                // multiple requests. When used with cookies, controls
                                // whether the cookie's lifetime is absolute (matching the
                                // lifetime of the authentication ticket) or session-based.

                                //IssuedUtc = <DateTimeOffset>,
                                // The time at which the authentication ticket was issued.

                                //RedirectUri = <string>
                                // The full path or absolute URI to be used as an http 
                                // redirect response value.
                            };

                            await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme,
                                    new ClaimsPrincipal(claimsIdentity), authProperties);

                            //HttpContext.User = new GenericPrincipal(new ClaimsPrincipal(username.ToString()), role.ToArray());
                            GenericIdentity genericIdentity = new GenericIdentity(authUserVM.Username, ClaimTypes.NameIdentifier);
                            string[] roles = { role };
                            GenericPrincipal genericPrincipal = new GenericPrincipal(claimsIdentity, roles);
                            IPrincipal identity = (IPrincipal)genericPrincipal;
                            HttpContext.User = (ClaimsPrincipal)identity;

                            TempData["Success"] = "Login Successful.";
                            ViewData["Success"] = "Login Successful.2";
                            _logger.LogInformation(DateTime.Now + " - " + loginVM.Username + " Login Success ");

                            return RedirectToAction("Dashboard");
                        }
                        else
                        {
                            TempData["Error"] = "Invalid Username or Password.\n Please try again.";
                        }
                    }
                    catch (Exception ex) 
                    { 
                        
                    }
                }
            }

            return View(loginVM);            
        }

When I go and check httpcontext in debug I find all 3 sessions. but the User part is always null.

When I go to the admin controller I want to

[Authorize(Roles="Administrator")]

 but this I'm not sure about since my 'User' in my httpcontext is null.

The only way I got Authorize to work was with:

[Authorize(AuthenticationSchemes=CookieAuthenticationDefaults.AuthenticationScheme)]

but this does not check the 'Role' it only makes sure the user is logged in.

I am currently not using my JWT token until my next API I create. This current microservice is 'User' and it's just checking Roles of users for dashboards.

I would gladly clear any other questions up if you have any. 

How would I be able to use Authorize on my Role with my setup? I have a API and UI 2 separate .net core projects. I'm using httpclient to talk between the 2.

You are viewing reply posted by: dharmendr 8 days ago.