Becoming a software developer – episode XV

Becoming a software developer – episode XV

Welcome to the fifteenth episode of my course “Becoming a software developer” in which we will implement password encryption, authorization and authentication using JWT.

All of the materials including videos and sample projects can be downloaded from here.
The source code repository is being hosted on GitHub.


 

Scope

  • Encryption
  • Authentication
  • Authorization

Abstract

Encryption

Whenever we want to store user accounts along with their passwords in our database, the best option is to apply a hashing function. It means that given e.g. “secret” password such function will create a so-called hash which can not be reversed (or decrypted) based on some random and secure sequence of characters named salt. Basically, whenever we want to ensure that the password is valid, we need to create its hash based on the salt generated for the first time when hashing the password e.g. during account registration and then compare the hashes, simple as that. This way, even if the data storage would be compromised the password can not be decrypted easily, as the hash is not a reversible function (at least theoretically).

Authentication

In order to find out the identity of the user in our system, he needs to be able to authenticate in some way. For the typical web application which is stateless, we can choose between different methods of authentication and pass along this information either with cookies, headers or within the URL itself. In our case, we want to use JWT (JSON Web Tokens) which is one of the most popular industry standards and basically boils down to generating a secure token that can be passed within the HTTP Header “Authorizaion: Bearer {token}”. Once the token is validated by the server, we can assign an identity to the user and allow him to perform operations that he wouldn’t be able to do otherwise.

Authorization

Once the user was authenticated we can grant him access to the different operations or resources for example based on his role (user, moderator, admin etc.) or claims (list of permissions). While authentication is all about finding out if the user is who he claims to be, the authorization’s task is to validate whether the user has the required permissions to successfully perform a request.

Next

In the next expisode we will talk a little bit more about caching, implement the “login” endpoint in our API, move further with business logic and also resolve the user identity based on JWT claims and map it automatically to the commands that require user id.

3 Comments Becoming a software developer – episode XV

  1. Bartosz

    Z tego co rozumiem salt to jest klucz który służy do zaszyfrowania hasła? Jeśli tak to nie rozumiem tego co zrobiłeś w klasach UserService oraz Encrypter. W UserService przy rejestracji użytkownika zapisujesz do bazy danych zaszyfrowane hasło + salt, gdzie salt, patrząc na wywołanie metody GetSalt sugerowałoby, że jest generowane na podstawie hasła, lecz patrząc w ciało tej metody widzę, że parametr value jest użyty jedynie do komunikatu, gdy jest on pusty, a salt jest jednak generowane losowo.
    Tutaj pojawia się nieścisłość której nie mogę zrozumieć, z ciała metody GetSalt wynika, że salt jest generowane losowo, a nie na podstawie hasła jak wynika z wywołania tej metody (chyba, że coś przeoczyłem/czegoś nie rozumiem), a więc żeby przy logowaniu sprawdzić, czy hasło jest poprawne należało by odczytać salt z bazy i wygenerować na jego podstawie hash wpisanego hasła i go porównać z tym zapisanym w bazie. W klasie UserService jednak wygląda to inaczej, generujesz nowy salt, i na jego podstawie generujesz hash do porównania z hashem z bazy, czy to nie spowoduje sytuacji, że dwa takie same hasła będą miały inny hash?

    Tak w skrócie:
    Czy metoda GetSalt generuje salt losowo czy na podstawie hasła?
    Dlaczego przy logowaniu generujesz nowy salt, zamiast pobrać go z bazy?

    Reply

Leave A Comment

Your email address will not be published. Required fields are marked *