Autentizácia a autorizácia
Autentizace (Přihlášení) v systému ABRA Gen Web API je proces ověřování identity uživatele nebo aplikace, která se snaží přistupovat k API. Autentizace se provádí pomocí přihlašovacích údajů uživatele, tj. jeho přihlašovacího jména a hesla či tokenu. Na uživateli musí být také zatržen parametr Přihlášení nevizuálního uživatele API. Autorizace následuje po autentizaci a určuje, co může uživatel nebo systém udělat. Autorizace určuje, jaké akce, zdroje nebo služby jsou dostupné pro autentizovaného uživatele či aplikaci.
Níže se proces autentizace a autorizace v systému ABRA Gen probereme podrobně.

Přihlášení probíhá klíčem Authorization v HTTP hlavičce požadavku metodou Basic Authentication. Argumenty musí být v UTF-8 a musí být zakódovány do base64 (včetně oddělovacích znaků).
Authorization: Basic login:[password|token][;lock_connection]
Argument | Popis argumentu |
---|---|
login |
Přihlašovací jméno. Jedná se standardně o povinný parametr. Parametr je nepovinný pouze tehdy, pokud je zatržen parametr Umožnit rychlé přihlášení přes token. Přihlašovací jméno nesmí obsahovat znak dvojtečky ":". Pokud znak dvojtečky bude obsahovat, vrátí přihlášení do Web API chybu:
Přihlašovací jméno se vždy uvádí s dvojtečkou na konci. Tj. i tehdy, pokud není vyplněno heslo nebo token. |
password | Heslo uživatele, který se přihlašuje. Jedná se o nepovinný parametr. |
token |
Token uživatele, který se přihlašuje. Jedná se o nepovinný parametr. Pokud je zatržen parametr Umožnit rychlé přihlášení přes token není nutné vyplňovat login (Uživatelské jméno). V takovém případě je nutné před token uvést znak dvojtečky. Pokud se login nevyplní, použije se jako výchozí login řetězec ~token~. Přihlášení na uživatele s tímto loginem (resp. Přihlašovacím jménem) pak probíhá přes vyplněný Token. Přihlášení na tohoto uživatele se realizuje jako první. V aplikaci Postman se Token může na záložce Authorization vyplnit do pole Password. |
lock_connection |
Heslo zámku parametru Spojení je uzamčeno v nástroji DBAdmin.exe. Je třeba jej uvést za středník. Jedná se o nepovinný parametr. Heslo, token ani heslo zámku spojení nesmí obsahovat středník ";". Pokud znak středníku bude obsahovat uživatelské heslo nebo token, vrátí přihlášení do Web API chybu:
Pokud znak středníku bude obsahovat heslo zámku, vrátí přihlášení do Web API chybu:
Po nastavení Hesla zámku je nutno Web API restartovat. |
Uživatel je Supervisor, heslo (či token) je 1234. Supervisor:1234 zakódován do base64 je řetězec U3VwZXJ2aXNvcjoxMjM0. V HTTP hlavičce požadavku tedy bude uvedeno:
Authorization: Basic U3VwZXJ2aXNvcjoxMjM0
Uživatel je Supervisor, heslo ani token nejsou vyplněny. Supervisor: zakódován do base64 je řetězec U3VwZXJ2aXNvcjo=. V HTTP hlavičce požadavku tedy bude uvedeno:
Authorization: Basic U3VwZXJ2aXNvcjo=
Uživatel je Supervisor, heslo (či token) je 1234, heslo zámku je 567. Supervisor:1234;567 zakódován do base64 je řetězec U3VwZXJ2aXNvcjoxMjM0OzU2Nw. V HTTP hlavičce požadavku tedy bude uvedeno:
Authorization: Basic U3VwZXJ2aXNvcjoxMjM0OzU2Nw
Uživatel je Supervisor, heslo ani token nejsou vyplněny, heslo zámku je 567. Supervisor:;567 zakódován do base64 je řetězec U3VwZXJ2aXNvcjo7NTY3. V HTTP hlavičce požadavku tedy bude uvedeno:
Authorization: Basic U3VwZXJ2aXNvcjo7NTY3
Uživatel je Supervisor, token je 1234, parametr Umožnit rychlé přihlášení přes token je zatržen. :1234 zakódován do base64 je řetězec OjEyMzQ. V HTTP hlavičce požadavku tedy bude uvedeno:
Authorization: Basic OjEyMzQ
Pro zakódování a dekódování řetězců lze využít různé on-line nástroje typu Base64 decoder/encoder. Aplikace pro odesílání REST API požadavků jako např. Postman dokáží uživatelské jméno a heslo zakódovat i vygenerovat HTTP hlavičku.

Doménové přihlášení je z pohledu API realizováno stejně jako standardní přihlášení, ale je třeba zohlednit obdobná pravidla jako pro přihlášení uživatele přes doménový server.
Podmínky, aby doménové přihlášení fungovalo:
- Aplikační server musí být na serveru (PC), který je v doméně a musí běžet pod doménovým účtem.
- API server může být nainstalován na doménovém serveru, ale i na nedoménovém. Spuštěn může být pod doménovým i nedoménovým, účtem.
- Klient (např. Postman) může být spuštěn kdekoliv, tzn. není vyžadováno PC připojené do domény ani doménový účet.
Autentizace proběhne v těchto případech:
- Dotaz bude obsahovat doménové jméno shodné s přihlašovacím jménem v ABRA Gen a doménové heslo.
-
Dotaz bude obsahovat doménové jméno shodné s přihlašovacím jménem v ABRA Gen a tokenem v ABRA Gen.
Pokud dotaz bude obsahovat doménové jméno, bude zatržen parametr Umožnit rychlé přihlášení přes token, bude vyplněn Token, Heslo nebude prázdné a jako Přihlašovací jméno bude uveden řetězec ~token~, pak přihlášení také proběhne a navíc se tento způsob přihlášení realizuje jako první.
Autentizace neproběhne v těchto případech:
-
Dotaz bude obsahovat doménové jméno shodné s přihlašovacím jménem v ABRA Gen, ale nebude obsahovat heslo či token.
Pokud bude klient přihlášen pod doménovým jménem shodným s přihlašovacím jménem v ABRA Gen a současně pod stejným doménovým účtem je spuštěn API server, dojde k přihlášení, i pokud dotaz nebude obsahovat heslo.
- Dotaz bude obsahovat doménové jméno shodné s přihlašovacím jménem v ABRA Gen a heslo v ABRA Gen.

JWT (JSON Web Token) umožňuje bezpečné a efektivní přihlášení uživatelů do Web API systému ABRA Gen. Proces zahrnuje vytvoření přístupového a případně i obnovovacího tokenu, které slouží k autorizaci požadavků na API. Přihlášení pomocí JWT tokenu je třeba nakonfigurovat v agendě Definice JWT a explicitně zatrhnou na uživateli parametr JWT Přihlášení.


Přihlášení se provádí přes endpoint:
POST http://localhost:81/currentuser/logintoken
Parametre:
- Basic Authentication: Uživatel se přihlásí pomocí jména a hesla (pomocí HTTP Basic Auth).
-
jwtsettingcode (volitelné): Pokud existuje více definic JWT, je nutné specifikovat kód definice:
POST http://localhost:81/demodata/currentuser/logintoken?jwtsettingcode=<kod_definice>
Výsledok:
- Přístupový token (access_token): Používá se pro autorizaci běžných API požadavků.
- Obnovovací token (refresh_token, pokud je povolen): Používá se k získání nových tokenů.

Pro autorizaci požadavků na API se přístupový token přidává do hlavičky Authorization
:
Authorization: Bearer <access_token>
Token je nutné použít před vypršením jeho platnosti (definováno v agendě Definice JWT).

Pokud je povoleno obnovení přihlášení, lze použít endpoint:
POST http://localhost:81/demodata/currentuser/refreshtoken
Podmínky:
- Obnovovací token musí být platný.
- Přístupový token musí být v poslední desetině své životnosti.
Výsledok:
- Nový přístupový a obnovovací token.

Pro účely příkladu je nakonfigurováno použití přihlašovacího i obnovovacího tokenu.
Vygenerování tokenů, použití přihlašovacího a obnovovacího tokenu:
import base64
import json
import sys
import requests
from http_constants.headers import HttpHeaders
session = requests.Session()
headers = {}
headers[HttpHeaders.CONTENT_TYPE] = HttpHeaders.CONTENT_TYPE_VALUES.json
headers[HttpHeaders.AUTHORIZATION] = "Basic " + (
base64.urlsafe_b64encode(("tester" + ":" + "testerp").encode("utf-8"))
).decode("utf-8")
# generate new token
response = session.post(
url="http://localhost:81/demodata/currentuser/logintoken?jwtsettingcode=<kod_definice>",
headers=headers,
)
if response.status_code != 200:
print(f"\n\nerror issuing new token: {response.status_code} {response.text}")
sys.exit(0)
print(f"\n\nnew login and refresh tokens:\n{json.dumps(response.json(), indent=2)}")
access_token = response.json()["access_token"]
refresh_token = response.json()["refresh_token"]
# use login token in authorization as a bearer
headers_token = {}
headers_token[HttpHeaders.CONTENT_TYPE] = HttpHeaders.CONTENT_TYPE_VALUES.json
headers_token[HttpHeaders.AUTHORIZATION] = "Bearer " + access_token
response = session.get(
url="http://localhost:81/demodata/countries?where=code eq 'cz'",
headers=headers_token,
)
print("\n\nuse of login token:")
if response.status_code != 200:
print(f"error: {response.status_code} {response.text}")
sys.exit(0)
print(f"status code: {response.status_code}")
print("response body:")
print(response.text)
# use refresh token to generate new token(if use of refresh tokens is configured)
headers_refresh = {}
headers_refresh[HttpHeaders.CONTENT_TYPE] = HttpHeaders.CONTENT_TYPE_VALUES.json
headers_refresh[HttpHeaders.AUTHORIZATION] = "Bearer " + refresh_token
response = session.post(
url="http://localhost:81/demodata/currentuser/refreshtoken",
headers=headers_refresh,
)
print("\n\nuse of refresh token:")
if response.status_code != 200:
print(f"error: {response.status_code} {response.text}")
sys.exit(0)
print(f"new login and refresh tokens: {json.dumps(response.json(), indent=2)}")
Výstup:
new login and refresh tokens:
{
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJEZW1vdmVyemUiLCJzdWIiOiJ0ZXN0ZXIiLCJhdWQiOiJ0ZXN0IiwiZXhwIjoxNzA4OTU4MzEwLCJwcnAiOiJhdCJ9.dqegGmsotsTvizWflhEgyCetPqy8KmW8rPWXd47XqwQ",
"expires_in": 320,
"refresh_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJEZW1vdmVyemUiLCJzdWIiOiJ0ZXN0ZXIiLCJhdWQiOiJ0ZXN0IiwiaWF0IjoxNzA4OTM5MTEwLCJleHAiOjE3MDg5NTgzMTAsInBycCI6InJ0In0.w9VJ9PIInZlxRpoMIezXcoRHkTLvkOkAJKreiFbKahI",
"refresh_token_expires_in": 10080
}
use of login token:
status code: 200
response body:
[{"alternatecode":"","code":"CZ","currency_id":"0000CZK000","hidden":false,"id":"00000CZ000","name":"Česká republika","numcode":"203","objversion":6}]
use of refresh token:
new login and refresh tokens: {
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJEZW1vdmVyemUiLCJzdWIiOiJ0ZXN0ZXIiLCJhdWQiOiJ0ZXN0IiwiZXhwIjoxNzA4OTU4MzE1LCJwcnAiOiJhdCJ9.KasrkJTMKjzAC5RbjvQpcqru6aCXrNwfKBVIevXBDc4",
"expires_in": 320,
"refresh_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJEZW1vdmVyemUiLCJzdWIiOiJ0ZXN0ZXIiLCJhdWQiOiJ0ZXN0IiwiaWF0IjoxNzA4OTM5MTE1LCJleHAiOjE3MDg5NTgzMTUsInBycCI6InJ0In0.C2ts75DOPtVJJX_w3c98ZE8Ji4tHg3KFnAWFkh0CFK4",
"refresh_token_expires_in": 10080
}

Přihlašování do API podporuje normu RFC 4648. V praxi to znamená, že je možné používat URL Safe verzi kódováni Base64 (base64url) v hlavičce Authorization i v Query parametr auth.
Mějme uživatele Supervisor s heslem 12345 a aliasem spojení data. Abra Web API nám poběží na lokálním portu 8082. Potom výběr z kolekce faktur vydaných, kde každá faktura bude obsahovat částku (Amount) a celý objekt firmy (Firm_ID), provedeme s parametrem auth takto.
http://localhost:8082/data/issuedinvoices?select=Amount&expand=Firm_ID&auth=U3VwZXJ2aXNvcjoxMjM0NQ
Upozorňujeme, že, jak bylo řečeno výše, parametru auth je nutno předat hodnotu jméno:heslo (v našem příkladu Supervisor:12345) zakódovanou do base64url. Samotné base64 nestačí!

Prístup k API je umožnený len užívateľom systému ABRA Gen, ktorí majú vo svojom nastavení začiarknutý príznak Prihlásenie nevizuálneho užívateľa API. Pri prístupe k dátam sú zohľadňované práva ku chráneným objektom a tiež všeobecná funkcionalita ochrany dát.
Nie sú zohľadňované práva k funkciám, ktoré sa týkajú len práce s užívateľským rozhraním ABRA Gen.

Thread pool v systému ABRA Gen Web API slouží k paralelní obsluze volání, kde maximální počet současně obsluhovaných volání je určen parametrem threadPoolSize. Každé volání musí projít procesem autentizace, který je pro opakované dotazy z téhož zdroje urychlen díky serverové keši.
V reálném provozu se však můžeme setkat s výzvou v podobě nevalidních volání generovaných typicky různými boty, což může ovlivnit celkovou výkonnost API. Pro řešení této situace byl vytvořen tzv. Connection pool.
V kontextu systému se Connection pool využívá pro nepřihlášená pracovní vlákna. Tato implementace působí jako počáteční etapa zpracování, kde probíhá ověření volání předtím, než jsou tato volání předána do hlavního Thread poolu. Tato prvotní fáze zpracování je méně náročná na systémové prostředky, neboť se soustředí především na základní ověření volání. Connection pool je konfigurovatelný pomocí parametrů connectionPoolSize, connectionQueueTimeoutMs a connectionTimeoutMs.
Pokud je skrze Connection pool ověřeno, že se jedná o validní volání (tj. volání od uživatele identifikovaného v databázi, nikoli od bota), je takové volání předáno do hlavního Thread poolu pro další zpracování. Tímto postupem je zajištěno, že výkonnost Web API je optimalizována při současném dodržování nezbytných bezpečnostních opatření.

Okrem ochrany dát v zmysle všeobecnej funkcionality ochrany dát
Vo všeobecnosti platí:
-
Na získavanie informácií o business objektoch s väzbami na chránené objekty (metódou GET v režime základného dopytovania i metódou POST v režime rozšíreného dopytovania) je potrebné právo Zobraziť ku všetkým chráneným objektom, ktoré sú na danom objekte použité.
-
Na ukladanie (metódy POST, PUT a DELETE) je potrebné právo Použiť ku všetkým chráneným objektom, na ktoré sa ukladaný business objekt odkazuje.
Obe práva teda majú pri práci v aplikácii ABRA Gen aj v rozhraní Web API rovnaký význam.
V číselníku vlastných bankových účtov je nadefinovaný účet 98765432100/5500.
Užívateľ Smith je obsadený do roly, ktorá má na tento účet právo Zobraziť, ale nemá právo Použiť. K dátam pristupuje prostredníctvom užívateľského rozhrania aplikácie ABRA Gen.
- Užívateľ Smith si môže zobraziť faktúru vydanú, ktorá má v položke Vlastný účet vyplnený odkaz na bankový účet 98765432100/5500, pretože k tomuto účtu má právo Zobraziť.
- Pokiaľ je na niektorej faktúre vydanej nastavený iný bankový účet, užívateľ Smith ho v aplikácii ABRA Gen nemôže zmeniť na 98765432100/5500, pretože k tomuto účtu nemá právo Použiť.
Užívateľ Apu je obsadený do rovnakej roly, vo vlastnostiach užívateľa má začiarknutý príznak prihlásenie nevizuálneho užívateľa API, k dátam pristupuje prostredníctvom rozhrania Web API.
- Rovnako ako užívateľ Smith môže užívateľ Apu získať (zobraziť) informácie o faktúre vydanej.
- Rovnako ako užívateľ Smith nemôže užívateľ Apu na hlavičkách faktúr nastavovať väzbu na účet 98765432100/5500, pretože k tomuto účtu nemá právo Použiť.
Pri aktualizácii business objektov je potrebné právo Použiť ku všetkým naviazaným chráneným objektom, nielen k tým, ktorých hodnoty sa menia. Pre zmenu bankového účtu na hlavičke faktúry je teda potrebné nielen právo Použiť k príslušnému bankovému účtu, ale tiež napríklad ku všetkým skladom, ktoré sú použité na riadkoch daného dokladu.
Pri práci s dokladmi tvorenými hlavičkou a riadkami platí:
- Je uplatňovaná rovnaká logika ako pri práci s dokladmi vo vizuálnom prostredí ABRA Gen - tzn. pokiaľ doklad obsahuje riadky s odkazmi na chránené objekty, ku ktorým užívateľ nemá prístup, doklad je možné načítať (vrátane riadkov), ale nie je možné ho uložiť.
Pre bezpečnostné obmedzenie (security podmienky) platí:
- Pre systémové položky na jednotlivých business objektoch sú brané do úvahy informácie zaregistrované v DynSQL - pokiaľ nie je zmena v DynSQL, použije sa východisková (DynSQL)SecurityMask z číselníka. Východisková hodnota parametra SecurityWithNull je True.
- Parametre definovateľných položiek (bežných užívateľských položiek i extra položiek) sú načítané zvlášť, bezpečnostné obmedzenia sú pri nich spoločné pre výber i pre ukladanie.
- Na vlastnené kolekcie a na odkazované business objekty nie sú bezpečnostné obmedzenia aplikované.
- Tiež na hierarchické business objekty nie sú bezpečnostné obmedzenia aplikované. Presnejšie nie sú aplikované na referenčné položky business objektu, ktoré ukazujú na rovnaký typ business objektu, ako je ten, na ktorom sú definované. Príkladom je hierarchická štruktúra stredísk - hoci je štruktúra definovaná (s využitím položky Parent_ID), bezpečnostné obmedzenie je potrebné nastaviť pre každý záznam (stredisko) zvlášť, bez ohľadu na hierarchiu.