Laboratorul 04: Integrarea cu Auth0

Scopul Laboratorului

In laboratorul trecut am construit un proiect in React pe baza design-ului, trecand prin notiunile de baza ale bibliotecii de frontend ReactJS. In acest laborator vom face un pas in fata si vom integra aplicatia noastra cu Auth0, pentru a avea si partea de autentificare si management al utilizatorilor.

Ce veti invata la acest laborator?

Veti intelege diferenta dintre autentificare si autorizare. Veti invata sa folositi un 3rd party pentru gestionarea conturilor de utilizatori. Veti invata sa configurati Auth0. Veti invata sa integrati Auth0 cu frontendul.

Ce inseamna autentificare si autorizare?

Intr-un sistem securizat exista doua tipuri de actiuni care se pot realiza:

  • autentificare
  • autorizare

Autentificare

Autentificarea este operatia care raspunde la “Cine esti tu?”

Autentificarea se realizeaza prin trimiterea credentialelor de utilizator sistemului securizat. Daca sistemul accepta credentialele, sistemul va intoarce inapoi o dovada care sa ateste ca utilizatorul este, intr-adevar, cine zice ca este.

Aceasta dovada poate fi de mai multe tipuri:

  • Client Side Cookie
  • Server Side Cookie
  • Unul sau mai multi tokeni
  • Combinatie intre cele de mai sus

Auth0, in urma procesului de autentificare, returneaza 2 tokeni JWT. Un token JWT reprezinta o informatie codificata (nu criptata) in format Base64 care are o semnatura atasata. Folosind semnatura, un sistem poate verifica daca tokenul este valid sau a fost malformat de un atacator.

Mai multe informatii veti vedea la cursul dedicat securitatii web.

Autorizare

Autorizarea este operatia care raspunde la “Ce permisiuni ai tu?”.

Dovada intoarsa in urma procesului de autentificare poate fi folosita de clienti in comunicare cu alte sisteme (API-uri) pentru a efectua operatii. Daca API-urile recunosc acea dovada, precum si permisiunile care sunt atasate acelei dovezi, ele vor accepta interactiunea cu utilizatorul.

In cadrul Auth0, API-urile sunt inregistrate in platforma si sunt configurate sa accepte tokeni de access JWT. In baza acestor tokeni, API-urile vor putea comunica cu aplicatiile.

Standarde de securitate

In securitatea web exista o serie de standarde care descriu modul in care autentificarea si autorizarea trebuie sa aiba loc. Unul dintre acestea este OpenID Connect, care este o extensie a OAuth2 (care este standard doar de autorizare).

Auth0 foloseste OpenID Connect in flow-urile sale de autentificare si autorizare.

Aceste lucruri vor fi explicate in detaliu la cursul de securitate web. Pana atunci, va recomandam sa urmariti acest videoclip.

Ce este Auth0?

Auth0 este o platforma de gestionare a conturilor de utilizatori care ofera suport pentru autentificare si autorizare.

Avantajul in utilizarea unui 3rd party pentru gestionarea conturilor, autentificare si autorizare este ca puteti sa faceti foarte usor outsourcing la responsabilitatile ce tin de securitatea conturilor. Deoarece securitatea este foarte importanta, este foarte usor sa gresiti, mai ales la inceput de drum. Si greselile, de obicei, implica litigii pe sume foarte mari de bani. Este de preferat sa folositi un tert pentru a evita orice potentiale probleme.

Auth0 ofera suport pentru majoritatea tehnologiilor si are un sistem de configurare usor adaptabil.

Cum se configureaza Auth0?

Pasul 1: Crearea unui cont

Pentru a lucra cu Auth0, trebuie sa va creati un cont. Este gratuit. Puteti sa va creati un cont de la 0 sau sa folositi conturi deja existente de Google, Microsoft sau GitHub.

Pasul 2: Inregistrarea unei aplicatii

Aplicatiile reprezinta clienti care se vor conecta la sistemul Auth0 pentru operatii de autentificare si autorizare. Din cadrul aplicatiilor veti putea efectua operatii precum login, register, logout in Auth0. Mai mult, aplicatiile vor primi 2 tokeni de la Auth0 inapoi, pentru a valida faptul ca autentificarea s-a realizat cu succes.

Unul dintre acesti 2 tokeni reprezinta un ID Token, si are informatie embedded despre utilizator. Celalalt token reprezinta un Access Token si va fi folosit in comunicarea cu API-uri, in procesul de autorizare.

Pasul 3: Configurarea unei aplicatii in cadrul Auth0

In functie de tehnologia pe care o folositi, Auth0 va ofera un ghid.

Va recomandam sa urmariti ghidul, deoarece este foarte bine explicat.

Pasul 4: Inregistrarea unui API in cadrul Auth0

Chiar daca nu lucram inca la backend, este necesar sa inregistram API-ul pe care il vom dezvolta in cadrul Auth0, pentru a putea realiza setarile pentru roluri si permisiuni. Setarile acestui API vor fi folosite de noi, atunci cand vom dezvolta backendul, pentru a putea autoriza cererile care vin de la client (frontend) cu Access Token-ul primit de la Auth0.

Inregistrarea unui API este si ea foarte simpla.

Nu conteaza ce url puneti in cadrul Identifier, pentru ca el nu va fi nicidoata apelat. Este utilizat doar pentru identificare si pentru crearea de token.

Pasul 5: Configurare permisiuni

Pentru a putea folosi permisiunile in cadrul API-urilor pe care le vom crea, este necesar sa activam doua optiuni care permit injectarea permisiunilor in Access Token.

Dupa ce ati facut acest lucru, trebuie sa adaugam o serie de permisiuni. Pentru cazul nostru, ne intereseaza sa filtram utilizatorii dupa capabilitati de admin. Asadar, avem nevoie doar de o permisiune, si anume, cea de administrator.

Adaugarea unei permisiuni este si ea, foarte simpla:

Permisiunile vor fi vizibile in Access Token si vor fi citite de catre backend. Pe baza lor, backendul va sti sa restrictioneze sau nu accesul la anumite resurse.

Pasul 6: Configurare roluri pentru utilizatori

Dupa ce avem permisiunile de accesare a API-ului create, putem sa le asignam unor roluri de utilizatori. Nu este obligatoriu sa facem asta, insa rolurile ajuta pentru agregarea mai multor permisiuni sub aceeasi umbrela.

In primul rand, trebuie sa cream un rol:

Dupa ce avem rolul creat, trebuie sa ii asignam permisiunile. Dati click pe rol, si apoi asignati-i permisiunea creata anterior:

Rolurile sunt folosite de Auth0 ca sa agrege mai multe permisiuni impreuna. In plus, rolurile pot fi incluse in ID Token si frontendul poate vedea rolul, pentru a randa pagini diferite, in functie de rol. Noi avem nevoie de aceasta functionalitate.

Pasul 7: Injectarea rolului in ID Token

Asa cum am spus anterior, frontendul trebuie sa stie cine este admin si cine nu, pentru a putea afisa diferit informatiile. De asemenea, nu este indicat ca frontendul sa acceseze Access Token-ul, deoarece acela este destinat pentru backend.

Pentru a putea adauga informatii in ID Token, Auth0 ofera Actions. Actions reprezinta niste middlewares care sunt injectate in procesele de autentificare si autorizare si sunt complet customizabile.

Pentru a injecta rolul in ID Token, este necesar sa adaugam un middleware in procesul de login:

Atentie la proprietatea pe care o setati in cadrul ID Token-ului. Trebuie obligatoriu sa fie in format de url, si sa inceapa cu http sau https. Altfel va fi ignorata de catre Auth0. Acest lucru face parte din standardul OpenID Connect de includere a properitatilor custom in token-uri.

Pasul 8: Asignare rol la utilizator (viitor)

Felicitari! Daca ati ajuns aici, inseamna ca aveti sistemul pregatit pentru operatiile de autentificare si autorizare. Ultimul pas este acela de a asigna roluri utilizatorilor. In cadrul proiectului nostru, a librariei online, avem nevoie de un administrator.

Asadar, va trebui creat un cont in platforma, folosind functionalitatea oferita de Auth0, integrata in frontendul nostru si apoi, din dashboardul Auth0, va trebui sa ii asignam acestui cont, rolul creat anterior.

Odata cu asignarea rolului, s-a asignat automat si permisiunea creata anterior.

Doar utilizatorii care vor avea rolul de admin asignat (si deci permisiunea de admin asignata) vor putea efectua operatii pe backend disponibile doar adminilor.

Integrare Auth0 cu React

Asa cum am prezentat anterior, auth0 are un tutorial foarte bun si usor de parcurs pentru integrarea cu frontendul nostru. In continuare, aveti cateva puncte care, mai mult sau mai putin, sunt prezentate si in tutorial:

Pasul 1: Instalarea pachetului Auth0

Instalarea pachetului respectiv pentru React in proiectul nostru de React

npm install @auth0/auth0-react

Pasul 2: Configurare

Completarea unui fisier de configurare in care vom tine datele statice

const authSettings = {
  rolesKey: "******************",
  domain: '********************',
  clientId: "**********************",
  audience: "********************"
};

export { authSettings };

Valorile cu stelute trebuie completate cu valorile voastre proprii!!!

RolesKey reprezinta numele proprietatatii custom pe care voi ati setat-o in Actions la pasul 7

Domain si ClientId sunt informatii care tin de contul vostru de Auth0 si aplicatia inregistrata la pasul 1.

Audienta reprezinta API-ul catre care frontendul va putea face call-uri autorizate de catre Auth0. Nu uitati ca la inceput am configurat si un API in Auth0.

Pasul 3: Configurarea providerului

Configurarea componentei de tip provider, practic un wrapper peste aplicatia noastra

import React from "react";
import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
import App from "./App";
import reportWebVitals from "./reportWebVitals";
import { Auth0Provider } from "@auth0/auth0-react";
import { authSettings } from "./AuthSettings";

ReactDOM.render(
  <React.StrictMode>
    <Auth0Provider
      domain={authSettings.domain}
      clientId={authSettings.clientId}
      redirectUri={window.location.origin}
    >
      <App />
    </Auth0Provider>
  </React.StrictMode>,
  document.getElementById("root")
);

Pasul 4: Login

Redirectarea catre login daca utilizatorul nu este autentificat in componenta noastra de Routing

import React, { useEffect } from "react";
import { BrowserRouter, Route, Routes } from "react-router-dom";
import Analytics from "../pages/Admin/Analytics";
import Book from "../pages/Admin/Book";
import UserBooks from "../pages/User/Books";
import Books from "../pages/Admin/Books";
import Account from "../pages/User/Account";
import { useAuth0 } from "@auth0/auth0-react";

const Router = () => {
  const { isAuthenticated, loginWithRedirect } = useAuth0();

  useEffect(() => {
    if (!isAuthenticated) {
      loginWithRedirect();
    }
  }, [isAuthenticated, loginWithRedirect]);
  return (
    isAuthenticated && (
      <BrowserRouter>
        <Routes>
          <Route exact path="/" element={<UserBooks />} />
          <Route exact path="/profile" element={<Account />} />
          <Route exact path="books" element={<Books />} />
          <Route exact path="books/:id" element={<Book />} />
          <Route exact path="analytics" element={<Analytics />} />
        </Routes>
      </BrowserRouter>
    )
  );
};

export default Router;

Pasul 5: Logout

Adaugarea actiunii de Logout pe butoane

 onClick={() => {
              logout({ returnTo: window.location.origin });
            }}

Pasul 6: Protejarea rutelor in functie de rol

Protejarea rutelor in functie de tipul de utilizator (admin/utilizator normal). De exemplu, ca si utilizator autentificat nu am niciun rol asignat (admin) inseamna ca nu voi avea dreptul sa vad paginile dedicate admin-ului, deci il voi redirectiona catre pagina lui principala in care vede cartile pe care le poate imprumuta.

useEffect(() => {
    if (user && user[authSettings.rolesKey].length === 0) {
      navigate("/");
    }
  }, [user]);

Testarea integrarii

Dupa ce ati integrat frontendul cu Auth0, testarea este foarte simpla:

  1. deschideti Network Tab in Browser Dev Tools
  2. faceti un login
  3. investigati call-ul prin care se intoarce tokenul, in sectiunea Preview

O sa vedeti 2 tokeni, Access Token si Id Token.

  • Access token va fi trimis catre backend, pentru autorizare
  • ID token este folosit de frontend, pentru extragerea datelor de profil

Investigarea tokenilor

Pe JWT.io puteti investiga continutul tokenilor.

ID Tokenul ar trebui sa contina informatii de profil si rolul injectat la pasul 7 (daca este token pentru admin):

Access Tokenul ar trebui sa contina informatii legate de audienta pentru care poate fi folosit si permisiuni injectate la pasul 5, prin optiunea de RBAC:

pw/laboratoare/04.txt · Last modified: 2022/04/08 12:15 by alexandru.hogea
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0