.. Zdroj: elza/docs/admin-guide/source/05-security.rst, elza e87a93d6d1

.. _admin_security:

==========================
Autentizace a zabezpečení
==========================

Metody autentizace
==================

Elza podporuje tyto metody autentizace:

- **Interní účty** - uživatelé a hesla uložená v Elze (vždy k dispozici).
- **Active Directory (LDAP)** - jméno a heslo uživatele se ověří vůči
  doméně Active Directory.
- **Kerberos (SPNEGO)** - jednotné přihlášení (SSO) v doméně Windows,
  volitelně i ověření jména a hesla vůči KDC.
- **SSO hlavička** - reverzní proxy, která uživatele ověřila, předá jeho
  uživatelské jméno v HTTP hlavičce.
- **OAuth2 / JWT** - požadavky nesou token (bearer) vydaný poskytovatelem
  identit.
- **Osobní API klíče** - pro integrace volající rozhraní REST.

Metody lze kombinovat. Při přihlášení jménem a heslem (přihlašovací
formulář nebo HTTP Basic) se zkoušejí v tomto pořadí: Active Directory,
Kerberos, interní heslo. Platí první metoda, která heslo přijme.

Kromě OAuth2 všechny metody pouze ověřují identitu: **uživatel musí
v Elze již existovat** se stejným uživatelským jménem a musí být aktivní.
Uživatelé se nezakládají automaticky a skupiny ani role z adresářové
služby se nepoužívají; oprávnění se vždy přidělují v Elze.

Výchozí uživatel
================

Nová instalace obsahuje vestavěného uživatele ``admin`` s heslem
``admin`` a oprávněním administrátora. Existuje pouze v konfiguraci,
nikoli v databázi, a je dostupný, dokud v databázi neexistuje uživatel
stejného jména.

.. warning::

   Výchozího uživatele vypněte, jakmile existují účty administrátorů:

   .. code-block:: yaml

      elza:
        security:
          allowDefaultUser: false

   Výchozí uživatel se rozpoznává pouze podle jména. Dokud je zapnutý,
   metody SSO hlavička, Kerberos, Active Directory a OAuth2 přijmou
   identitu ``admin`` bez hesla a přidělí jí oprávnění administrátora.
   Při použití kterékoli z těchto metod výchozího uživatele vždy vypněte.
   Dokud je výchozí uživatel zapnutý, nezakládejte ani databázového
   uživatele se jménem ``admin``: jeho vlastní heslo a oprávnění by byly
   ignorovány.

.. list-table::
   :header-rows: 1
   :widths: 36 18 46

   * - Klíč
     - Výchozí hodnota
     - Význam
   * - ``elza.security.allowDefaultUser``
     - ``true``
     - Zapíná výchozího uživatele.
   * - ``elza.security.defaultUsername``
     - ``admin``
     - Jméno výchozího uživatele.
   * - ``elza.security.defaultPassword``
     - hash hesla ``admin``
     - Heslo výchozího uživatele jako zakódovaný hash (``{bcrypt}...``),
       nikoli jako prostý text.

Interní účty a hesla
====================

Uživatelé se zakládají v modulu *Administrace* > *Uživatelé*. Hesla se
ukládají jako hash bcrypt. Hesla ze starých verzí uložená pomocí SHA-256
se převedou na bcrypt při dalším přihlášení uživatele heslem.

``elza.security.salt`` slouží pouze k ověření těchto starých hashů
SHA-256. Neměňte jej: uživatelé, jejichž heslo ještě nebylo převedeno, by
se už nemohli přihlásit a administrátor by jim musel heslo nastavit
znovu.

Active Directory
================

.. code-block:: yaml

   elza:
     security:
       ldap:
         ad-domain: archiv.example
         ad-server: ldap://dc1.archiv.example/

``ad-domain``
   Doména Active Directory. Jejím nastavením se metoda zapne.
``ad-server``
   URL řadiče domény.

Uživatel se přihlašuje doménovým jménem a heslem. Poté, co doména heslo
přijme, Elza vyhledá uživatele podle zadaného jména; uživatele v Elze
zakládejte se stejnými jmény jako v doméně. Pokud doména heslo odmítne,
zkusí se interní heslo.

Při nastaveném Active Directory kontroluje kontrola stavu (viz
:doc:`08-monitorovani`) i spojení s řadičem domény.

Kerberos (SPNEGO)
=================

.. code-block:: yaml

   elza:
     security:
       kerberos:
         service-principal: HTTP/elza.archiv.example@ARCHIV.EXAMPLE
         keytab-location: /etc/elza/elza.keytab
         authenticate-with-password: true

``service-principal``
   Jméno služby (SPN) aplikace Elza. Jeho nastavením se metoda zapne.
``keytab-location``
   Cesta k souboru keytab s klíčem služby. Soubor smí číst pouze
   uživatel, pod kterým běží služba.
``authenticate-with-password``
   Ověřovat jména a hesla z přihlašovacího formuláře také vůči KDC
   (výchozí ``true``).
``kerberos-client-debug``, ``ticket-validator-debug``
   Ladicí výpisy klienta Kerberos a ověřování ticketů (výchozí
   ``false``).

Konfigurace Kerberos pro JVM (realm a KDC, :file:`krb5.conf`) se přebírá
z operačního systému nebo z nastavení Javy.

Při nastaveném Kerberos nabízí přihlašovací dialog jednotné přihlášení.
Prohlížeč se pak ověří doménovým ticketem uživatele; pro adresu Elzy musí
mít povolenou integrovanou autentizaci. Z principalu se odstraní realm a
uživatel se vyhledá podle zbytku jména (``jan.novak@ARCHIV.EXAMPLE`` se
změní na ``jan.novak``). Samotný realm se nekontroluje. Pokud jednotné
přihlášení selže, uživatel se může přihlásit formulářem.

SSO hlavička
============

Reverzní proxy nebo přístupová brána, která uživatele ověřuje, může
předávat uživatelské jméno v HTTP hlavičce:

.. code-block:: yaml

   elza:
     security:
       allowDefaultUser: false
       sso-header:
         user-header: X-SSO-User

Elza vyhledá uživatele podle hodnoty hlavičky. Pokud hlavička uvádí jiného
uživatele než aktuální session, session se nahradí.

.. warning::

   Elza hlavičce plně důvěřuje. Řešení je bezpečné, jen pokud:

   - je Elza dostupná výhradně přes proxy (naslouchá na ``127.0.0.1``
     nebo je port omezen firewallem),
   - proxy hlavičku u každého požadavku odstraní nebo přepíše, takže ji
     klient nemůže poslat sám,
   - je výchozí uživatel vypnutý.

Do ``elza.security.logoutUrl`` nastavte adresu odhlášení brány, aby
odhlášení z Elzy ukončilo i session na bráně.

OAuth2 / JWT
============

Elza může přijímat tokeny (``Authorization: Bearer ...``) vydané
poskytovatelem identit. Vystupuje pouze jako resource server;
přesměrování na přihlášení u poskytovatele neprovádí.

.. code-block:: yaml

   elza:
     security:
       o-auth2:
         key-url: https://idp.archiv.example/oauth/token_key
         permissions:
           - authority: ELZA_ADMIN
             permissions: [ADMIN]

``key-url``
   URL, které vrací veřejný klíč pro ověření podpisu tokenů, jako JSON
   s klíčem RSA ve formátu PEM v poli ``value``. Klíč se načte jednou při
   startu; pokud jej nelze načíst, aplikace nenastartuje. Tokeny musí být
   podepsány algoritmem RS256.
``permissions``
   Mapování hodnot z položky ``authorities`` tokenu na oprávnění Elzy.
   ``scope`` omezuje oprávnění na oblast archivních entit (podle kódu).

Položka ``sub`` tokenu je uživatelské jméno a ``name`` zobrazované jméno.
Na rozdíl od ostatních metod se neexistující uživatel založí, a to včetně
archivní entity osoby v oblasti ``JWT_USERS``. Přímo přidělená oprávnění
uživatele se nahradí oprávněními odvozenými z tokenu. Údaje o uživateli se
ukládají do cache na pět minut, změna oprávnění nebo deaktivace se tedy
projeví do pěti minut.

Osobní API klíče
================

Integrace volají rozhraní REST s osobním API klíčem místo hesla
uživatele. Klíč patří uživateli a pracuje s jeho oprávněními; pro každou
integraci založte samostatného uživatele.

Uživatelé zakládají a ruší své klíče v uživatelském nastavení (kategorie
*Elza*). Celý klíč se zobrazí pouze jednou, při vytvoření; Elza ukládá jen
jeho hash. Administrátoři mohou zobrazit a zrušit klíče ostatních
uživatelů. Klíče lze zakládat a rušit jen po interaktivním přihlášení,
nikoli s jiným API klíčem.

Klíč se posílá v hlavičce:

.. code-block:: bash

   curl -H "X-API-Key: elza_..." https://elza.archiv.example/api/v1/...

.. list-table::
   :header-rows: 1
   :widths: 44 12 44

   * - Klíč
     - Výchozí hodnota
     - Význam
   * - ``elza.security.api-keys.enabled``
     - ``true``
     - Přijímat API klíče. Při ``false`` se hlavička ignoruje.
   * - ``elza.security.api-keys.header-name``
     - ``X-API-Key``
     - Název hlavičky.
   * - ``elza.security.api-keys.default-validity-days``
     - 365
     - Platnost nového klíče, pokud ji uživatel nezvolí.
   * - ``elza.security.api-keys.max-validity-days``
     - 730
     - Maximální platnost klíče.

Odmítnutý klíč je zodpovězen HTTP 401 s tělem JSON uvádějícím důvod
(``MALFORMED_TOKEN``, ``UNKNOWN_KEY``, ``INVALID_SECRET``, ``EXPIRED``,
``REVOKED``, ``USER_INACTIVE``).

Bezpečnostní auditní log
========================

Při nastaveném ``elza.siemLogFile`` (viz :doc:`04-konfigurace`) zapisuje Elza
události autentizace do samostatného logu ve formátu JSON, jedna událost
na řádek, vhodného pro systém SIEM:

- ``login_success`` - uživatel, metoda (``PASSWORD``,
  ``ACTIVE_DIRECTORY``, ``KERBEROS``, ``SSO_HEADER``, ``JWT``,
  ``API_KEY``) a zdrojová adresa,
- ``login_failed`` - uživatelské jméno, zdrojová adresa a důvod,
- ``api_key_created`` a ``api_key_revoked`` - kdo založil nebo zrušil
  který klíč kterého uživatele.

Log se rotuje denně a uchovává se 90 dní. Za reverzní proxy je zdrojovou
adresou adresa proxy.

Další nastavení
===============

.. list-table::
   :header-rows: 1
   :widths: 40 12 48

   * - Klíč
     - Výchozí hodnota
     - Význam
   * - ``elza.security.acceptForwardedHeaders``
     - ``false``
     - Přijímat hlavičky ``X-Forwarded-*`` od reverzní proxy; nutné,
       pokud Elza běží pod cestou (viz :doc:`06-reverzni-proxy`).
   * - ``elza.security.logoutUrl``
     - (nenastaveno)
     - Adresa, kterou prohlížeč otevře po odhlášení, například stránka
       odhlášení SSO brány.
   * - ``elza.security.displayUserInfo``
     - ``true``
     - Zobrazovat v záhlaví aplikace nabídku uživatele.

Session vyprší po standardní době nečinnosti vloženého serveru (30 minut),
kterou lze změnit klíčem ``server.servlet.session.timeout``. Jeden uživatel
může mít současně nejvýše deset session; jedenácté přihlášení ukončí
nejstarší z nich.

Endpointy monitorování nevyžadují autentizaci a musí zůstat dostupné jen
lokálně (viz :doc:`08-monitorovani`).
