Search code examples
c#asp.net-coreblazor-server-side

blazor server authentication dont work with httpcontext cookie


i want authorize user with api controller and save claims to cookie

and after that authorize my blazor server with it

this is my code for api Controller

public async Task<IActionResult> Login([FromBody] userPassModel userPass)
        {
            try
            {

                DIMAuthUser user = await authService.GetUser(userPass.UserName);
                if (user == null) return Unauthorized();
                bool resCheck = await authService.CheckUserCredentialAsync(userPass.UserName, userPass.Password);
                if (resCheck == false) return Unauthorized();
                ClaimsPrincipal principal = new ClaimsPrincipal(new ClaimsIdentity(user.AllSettedClaims, CookieAuthenticationDefaults.AuthenticationScheme));
                await HttpContext.SignInAsync(principal);
                return Ok();
            }
            catch (Exception ex)
            {
                Log.Error(ex.Message,this);
                return StatusCode(500);
            }
        }

user successfully loggin and cookie sent back to user ... but when i want redirect login page to main page my blazor server said not authorize

this is login page code

async Task OnClickLogin()
        {
            if (string.IsNullOrWhiteSpace(username)) return;
            if (string.IsNullOrWhiteSpace(password)) return;
            
            HttpResponseMessage mess = await HttpClient.PostAsJsonAsync( "/api/Athentication/login", new userPassModel
            {
                UserName=username,
                Password=password
            });
            if (mess.IsSuccessStatusCode)
            {
                if (mess.StatusCode == System.Net.HttpStatusCode.OK)
                {
                    NavigationManager.NavigateTo("/");
                    return;
                }
                else if (mess.StatusCode == System.Net.HttpStatusCode.Unauthorized)
                {
                    await SweetAlert2Service.ShowWarning("user or pass incorrect");
                    return;
                }
            }
            await SweetAlert2Service.ShowWarning("somthing went wrong");
        }

and this is main poge code

@page "/"
@attribute [Authorize]
<AuthorizeView>
    <Authorized>
        Authed
    </Authorized>
    <NotAuthorized>
        Noted
    </NotAuthorized>
</AuthorizeView>
<h1>INDEX</h1>

and this is program.cs

builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme).AddCookie();
app.UseStaticFiles();
app.UseRouting();

app.UseAuthentication();
app.UseAuthorization();

app.MapControllers();

app.MapBlazorHub();
app.MapFallbackToPage("/_Host");

app.Run();

after successful login with controller and redirected to main page show me "Noted"

i want user identity in cookie that can log activity in middleware with httpcontext ...


Solution

  • Blazor Don't Completely access To httpContext So if You Want user Cookie Authentication that use httpcontex don't Make Login page with blazor ( make login page with Razor Or MVC Page )

    in previously i sent authentication request from blazor page to controller and after that i navigate user to index, that is wrong ...

    before every blazor page, authentication process must be done and after that navigate user to blazor page ...

    so i must authentication process out of blazor pages and after that navigate to blazor pages

    so :

    i make a razor page in my Blazor project :

    enter image description here

    and all athentication logic added to it

    public async Task<IActionResult> OnPost()
            {
                string username = Request.Form["username"].FirstOrDefault();
                string password = Request.Form["password"].FirstOrDefault();
                if(string.IsNullOrWhiteSpace(username) || string.IsNullOrWhiteSpace(password)) return Page();
                DIMAuthUser user = await authService.GetUser(username);
                if (user == null)
                {
                    AuthResult = "Wrong User";
                    return Page();
                }
                bool resCred = await authService.CheckUserCredentialAsync(username, password);
                if (resCred == false)
                {
                    AuthResult = "Wrong USer Or Password";
                    return Page();
                }
                else
                {
                    await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme,
                        user.ClaimsPrincipal);
                    authService.AuthedUser = user;
                    Log.Logger
                        .ForContext("Username",user.UserName)
                        .Information($"{user.UserName} Logged In ...",this);
                    return Redirect("/");
                }
            }