.NET CORE web API: hashowanie hasła i generacja tokenów

0

Witam,

Od niedawna rozpoznaję temat zarządzania użytkownikami w .NET Core web api. Muszę przyznać, że ta platforma ma bardzo fajny system autoryzacji autentykacji użytkowników. Implementacja podstawowych funkcjonalności jak rejestracja, logowanie i generowanie tokena JWT nie stanowi problemu, gdyż jest dużo informacji na ten temat. Obecnie borykam się z czymś innym, muszę rozpoznać dwa procesy, na temat których nie potrafię znaleźć informacji. Może któryś z forumowiczów zna odpowiedź na te pytania.

  1. Dodaje nowego użytkownika do bazy danych. W żądaniu podaje hasło jako plain tekst. Później wywołuję metodę CreateAsync i w bazie znajduje się hash hasła:
 var result = await _userManager.CreateAsync(user, registerUser.Password);

Pytanie: jak generowany jest hash, jaki algorytm jest do tego użyty?

  1. Przy logowaniu generuję tokena dla klienta:
 var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("KLUCZ_SEKRETNY_O_ODPOWIEDNIEJ_DLUGOSCI");
 var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
 var token = new JwtSecurityToken(
             issuer ......
             ......
             signingCredentials: creds
           );
 return token; // Żeby sprawdzić co się znajduje w tokenie

Oto co między innymi znajduje się w środku

.....
"signingCredentials":{
      "algorithm": "HS256",
      "cryptoProviderFactory": null,
      "key":{
            "keySize": 200,
             "key": "SEpSRV9XSUxYX0JFX0FfU0VDUkKUX0tFWm==",
             "keyId": null,
             "cryptoProviderFactory":{
                   "customCryptoProvider": null
            }
      },
      "kid": null
},
"encryptingCredentials": null,
"signingKey": null,
.....

Oczywiście po wywołaniu poniższej funkcji otrzymuję normalnego tokena składającego się z trzech części

return new JwtSecurityTokenHandler().WriteToken(token);

Pytanie: jak może klient sprawdzić (a taki jest wymóg) autentyczność tokena? Jak rozumiem, musi on znać algorytm i klucz według których nagłówek i payload zostały zapisane w sygnaturze. Algorytm jest znany, ale co jest w tym przypadku kluczem: KLUCZ_SEKRETNY_O_ODPOWIEDNIEJ_DLUGOSCI", czy "key": "SEpSRV9XSUxYX0JFX0FfU0VDUkKUX0tFWm==", a może jeszcze coś innego?

Update:
Ten token jest na serwerze sprawdzany za każdym razem, gdy tylko ktoś wysyła żądanie opatrzone [Authorize]. A teraz chciałbym po prostu znać ten klucz i taką samą weryfikację zrobić u klienta.

Pozdrawiam,

0

Dzięki, nie widziałem Twojej odpowiedzi, ale też to dziś znalazłem w świetnym artykule. To ta kwestia jest już rozwiązana, można generować hashe u klienta. Jednak pojawia się kolejna kwestia, czy .NET Core udostępnia funkcję do rejestracji i logowania, która przyjmuje usera i hash hasła? Czytałem dokumentację na githubie, ale nie znalazłem żadnego tropu.

Co do kwestii numer dwa to sama się rozwiązała. Źle zdiagnozowaliśmy problem, nie był nim sam klucz, tylko jego długość. .NET Core rzuca wyjątkiem gdy klucz ma mniej niż 128 bitów, a klient w JAVA'ie akceptuje co najmniej 256 bitowe klucze. Używaliśmy klucza o długości 200 bitów i stąd to nieporozumienie. W temacie JWT dużo informacji można znaleźć tu i tu

Pozdrawiam,

0

Witam,

W kwestii tokenów (potrzebnych do pracy offline) dochodzi jeszcze jedna kwestia, a mianowicie sesje (potrzebne do pracy on line), które są generowane po udanym logowaniu, a które są powiązane z tokenami.

W internecie można znaleźć nie wiele sensownych informacji (link1 link2). Skonfigurowałem Startup:

services.AddDistributedMemoryCache();
services.AddSession();

.....

app.UseSession();

ale to jeszcze niczego nie załatwia.

W zasadzie po dwóch dniach rozeznawania tematu nadal nie wiem nic:

  • jak generować sesje z konkretnymi danymi, po udanym logowaniu?
  • skąd serwer wie, że przychodzi dobra sesja?
  • jak używać funkcji np getstring i set string? mam coś takiego (na bazie linku 2) w kontrolerze, ale name dla get jest null:
 [HttpGet("set/{data}")]
        public IActionResult setsession(string data)
        {
            HttpContext.Session.SetString("keyname", data);
            return Ok("session data set");
        }

        [HttpGet("get")]
        public IActionResult getsessiondata()
        {
            var name = _httpContextAccessor.HttpContext.Session.GetString(SessionKeyName);
            return Ok(name);
        }
  • czy mam wstrzykiwać zależność w konstruktorze kontrolera IHttpContextAccesor?

Czy ktoś stosował takie rozwiązanie i może odpowiedzieć na powyższe pytania?

Pozdrawiam,

1 użytkowników online, w tym zalogowanych: 0, gości: 1