Aliasi, katalog in osrednje pravilo
Podatkovni prehod stavke SQL sestavlja sam. Namesto imena podatkovne zbirke uporabi alias, imena objektov poišče v katalogu podatkovne zbirke, vrednosti pa poda kot parametre. Na tej strani je opisan model, na katerem temelji vsaka zahteva, in dve poti za stavke, ki jih napiše klicatelj sam: preverjeni stavki, ki jih prehod razčleni in preveri objekt za objektom, in nepreverjena prepustna pot, ki jo je treba posebej omogočiti.
Ključne funkcije
- Podatkovne zbirke so navzven vidne samo pod aliasi, ki jih sprostite.
- Vsako ime objekta se preveri v katalogu, vsaka vrednost pa se poda kot parameter.
- Stavki klicatelja gredo po eni od dveh poti: kot preverjeni stavki, ki jih prehod razčleni in vsak objekt v njih preveri v katalogu in pravilih, ali kot nepreverjeni stavki po posebej omogočeni poti, kjer jih omejujejo samo dovoljenja prijave v podatkovno zbirko.
Osnovni pojmi
Aliasi namesto imen podatkovnih zbirk
Klicatelj imena podatkovne zbirke nikoli ne vidi. Do podatkovnih zbirk dostopa prek sproščenih aliasov, preslikava aliasov v nize povezave pa je zapisana v konfiguraciji prehoda.
Klicatelji tudi niso ločeni po vratih, temveč po poverilnicah in obsegu, ki jim je dodeljen. Vsi
dostopajo do prehoda prek istih vrat HTTPS (privzeto 8433, po zgledu vrat 1433 SQL Serverja).
Vrata HTTP 8434 odgovarjajo samo na strežniku samem: za orodja, preverjanje stanja in spletni
strežnik pred prehodom.
Osrednje pravilo
Prehod ne izvede nobenega stavka SQL, ki ga ni sam sestavil ali preveril. Stavek sestavi iz tipiziranega opisa zahteve: iz sproščenega imena vira, izbranih polj, strukturiranega filtra ter podatkov o razvrščanju in straneh. Stavek, ki ga napiše klicatelj, izvede šele potem, ko ga razčleni in preveri vsak objekt v njem (preverjeni stavki). Edina izjema je nepreverjena prepustna pot, ki jo je treba posebej omogočiti.
Prehod zavrne:
| Zavrnjeno | Zakaj |
|---|---|
| SQL klicatelja, ki ga prehod ne more razčleniti in preveriti, razen po omogočeni prepustni poti | sicer preverjanje ne bi imelo smisla |
| nepreverjena imena tabel ali stolpcev | imen ni mogoče podati kot parametre, mogoče jih je le preveriti na seznamu dovoljenih |
| prosti izrazi za razvrščanje | iz istega razloga |
| poljubna imena procedur | sicer bi bilo mogoče poklicati katero koli proceduro v podatkovni zbirki |
| branje brez zgornje meje | en sam klic bi sicer lahko zasedel prehod |
Vse vrednosti so podane kot parametri, vsa imena pa so preverjena na seznamu sproščenih. To sta dva različna zaščitna ukrepa in potrebna sta oba.
Edina izjema: prepustna pot
Prek POST /api/v1/cf/{alias}/sql.json prehod sprejme stavek, ki ga je napisal klicatelj, in ga
izvede. Pravilo s tem ni omiljeno: gre za ločeno pot, ki jo je treba posebej omogočiti, in namenoma
za edino, po kateri prehod izvede besedilo, ne da bi ga presojal.
Zakaj obstaja. Odjemalec, ki lahko hkrati naslovi samo en objekt, sploh ne more izraziti spoja tabel, združevanja ali spremembe več vrstic hkrati. Vse vpletene vrstice bi moral prenesti k sebi in delo opraviti lokalno, namesto da bi prejel samo rezultat; čas in promet bi naraščala z velikostjo tabel, ne z velikostjo rezultata. Prav zato orodja za podatkovne zbirke poznajo prepustne poizvedbe.
Kaj jo omejuje in česa ne. Prehod stavka ne bere: ne razčleni ga, ne primerja ga z vzorci in
ga ne razvršča na bralne in pisalne. Tako preverjanje bi bilo obljuba, ki je prehod ne more
izpolniti, saj SELECT sam po sebi ne pove, kaj je dosegljivo prek pogledov, funkcij in verig
lastništva. Meja je zato tam, kjer se dejansko uveljavlja: pri dovoljenjih prijave, pod katero se
stavek izvede. Kar sme ta prijava, sme tudi prepustni stavek, vključno z branjem, pisanjem in
spremembami sheme. Katera prijava je to, je odvisno od načina prijave v prehod (glejte
Posredovanje identitete):
| Klicatelj | Stavek se izvede kot | Kdaj je prepustna pot dosegljiva |
|---|---|---|
ključ storitve; račun Windows pri aliasu brez Persons: Impersonate | prijava aliasa | pravilo izrecno navaja sql |
| prijava SQL Server (HTTP Basic) | ločena povezava te prijave | zadošča katero koli pravilo za alias, ki ni samo za branje |
račun Windows ali osebni ključ z vpisano prijavo SQL Server pri aliasu s Persons: Impersonate | EXECUTE AS LOGIN osebe | zadošča katero koli pravilo za alias, ki ni samo za branje |
izbrana identiteta podatkovne zbirke vrste Login ali Own | EXECUTE AS LOGIN skupne oziroma lastne prijave | zadošča katero koli pravilo za alias, ki ni samo za branje |
V primerih brez sql seznami objektov v pravilu stavka ne omejujejo; stavek se izvede z vsemi
dovoljenji te prijave.
Pod lastno prijavo osebe SQL Server vsak stavek preveri glede na dovoljenja te prijave, tako kot pri
neposredni povezavi prek Microsoftovega gonilnika ODBC. Pravica sql tam ne bi dodala ničesar, vsem
uporabnikom brez nje pa bi onemogočila spoje, združevanja in klice funkcij, ki jih Access pošilja
kot lastne stavke; sem sodi vsaka shranjena poizvedba nad več povezanimi tabelami. Pod prijavo
aliasa nepreverjenega stavka ne omejuje nič razen pravila, zato je tam sql edini dostop do te
poti. Kdor pravice sql nima, pošilja namesto tega
preverjene stavke.
Račun Windows brez lastne prijave v SQL Server prehod pri aliasu s Persons: Impersonate zavrne že
ob odpiranju seje (403); pod prijavo aliasa se namesto tega nikoli ne izvede. Osebni ključ, katerega
oseba nima vpisane prijave SQL Server, pa se izvede pod prijavo aliasa, zato zanj velja prva vrstica
tabele.
Poleg tega morata vedno veljati še dva pogoja, sicer prehod odgovori z 403:
| Pogoj | Kje ga nastavite |
|---|---|
| alias sprejema lastne stavke | AllowPassThrough: true pri vnosu podatkovne zbirke |
| klicatelj ni omejen na branje | ReadOnly: false |
Zvezdica * v Resources te poti ne odpre. Zvezdica se nanaša na vrste objektov v katalogu. Če
bi pomenila tudi “in vsak stavek, ki ga napišeš”, bi se vsako prej zapisano pravilo razširilo v
trenutku, ko je ta pot nastala. Klicatelj, omejen na branje, je zavrnjen v celoti in ni zgolj omejen
na bralne stavke; prehod obojih ne more razlikovati, zato “samo za branje” tu pomeni: brez lastnih
stavkov. Obe protislovji ujame preverjanje ob zagonu: če pravilo navaja sql in je hkrati samo za
branje, se prehod ne zažene.
Preverjeni stavki: brez pravice sql
Access spoje, podpoizvedbe, vsote prek več tabel, funkcije in spremembe več vrstic hkrati v
povezanih tabelah pošlje kot en stavek in jih ne izračuna sam, če jih gonilnik zavrne. Z
Microsoftovim gonilnikom ODBC to deluje, ker dovoljenja preveri SQL Server. Da bi enako delovalo prek
prehoda, ne da bi vsak uporabnik dobil pravico sql, prehod na istem naslovu sprejema
preverjene stavke: od vsakega klicatelja, katerega pravila navajajo alias, če alias to dovoli
(AllowCheckedStatements, privzeto vklopljeno).
Prehod stavek razčleni z Microsoftovim razčlenjevalnikom T-SQL in ga sprejme samo, če so izpolnjeni vsi trije pogoji:
- Vsak stavek v paketu je ena od teh vrst:
SELECT(s spoji, podpoizvedbami,UNION,WITH, združevanjem in okenskimi funkcijami),INSERT,UPDATE,DELETEali klic poimenovane procedure. Več stavkov v enem paketu (SELECT …; SELECT …) se izvede tako kot z Microsoftovim gonilnikom ODBC; vsak se preveri posebej, ločilna vrsticaGOpa je zavrnjena. - Vsaka uporabljena oblika je na zaključenem seznamu dovoljenih: brez sprememb sheme, brez dinamičnega SQL, brez
SELECT … INTO, brez spremenljivk razen vezanih parametrov, brez imen, ki vsebujejo podatkovno zbirko ali strežnik, in brez funkcij, ki opisujejo strežnik, prijavo ali druge objekte. - Vsak navedeni objekt je v katalogu aliasa in sproščen za to, kar stavek z njim počne, po istih pravilih kot zahteva neposredno na ta objekt: branje kot
GET, vstavljanje kotPOST, spreminjanje kotPATCH, brisanje kotDELETEin izvedba procedure kotPOST. Cilj spremembe potrebuje še pravico za branje, ker pogoj nad njegovimi stolpci razkrije vrednosti. Enako veljajo pravice za posamezne objekte (Objects,ExceptObjects).
Prehod ne izvede besedila klicatelja, temveč na novo zapisano različico, v kateri ima vsak objekt
shemo, na podlagi katere ga je preveril. Klicatelj tako ne doseže ničesar, česar ne bi dosegel tudi
objekt za objektom prek OData; prihrani si le prenos vseh vrstic. Pravilo samo za branje dopušča samo
bralne stavke. Kdor ima pravico sql ali dela pod lastno prijavo, ima še naprej na voljo nepreverjeno
prepustno pot.
Veliki rezultati se pošiljajo sproti. Če stavek vrne več kot 500 vrstic, prehod začne pošiljati
odgovor (JSON) s prvimi vrsticami, medtem ko SQL Server preostale še pripravlja; manjše rezultate
zbere in pošlje v celoti. Obe obliki sta isti dokument: najprej columns, nato data, nato števci.
Odgovor se tako začne približno takrat, ko SQL Server vrne prvo vrstico, in ne čaka na zadnjo.
Če stavek odpove potem, ko je pošiljanje odgovora že steklo, prehod prekine povezavo. Stanje 200
je takrat že poslano, pravilno zaključen, a nepopoln dokument pa bi bil videti kot popoln. Vsak
bralnik prekinjen dokument sporoči kot napako, vzrok pa najdete v dnevniku pod ID-jem korelacije. Če
stavek odpove v prvih 500 vrsticah, prehod odgovori z ustreznim stanjem. Če klicatelj branja ne
dokonča in zapre povezavo, prehod stavek v SQL Serverju prekliče, namesto da bi preostanek prebral
in zavrgel. Odgovor v obliki XML prehod še vedno najprej zbere v celoti.
Besedilo stavka se zapiše v revizijsko sled, in sicer pred izvedbo in pod istim ID-jem korelacije kot izid zahteve. Vrednosti so izpuščene, ker so to podatki. Pri drugih zahtevah revizijska sled stavkov ne vsebuje, ker zadošča navedba vira, iz katere je razvidno, kaj se je zgodilo. Tu pa je besedilo edini opis tega, kar se je zgodilo.
Namenoma ni na voljo
Treh na videz samoumevnih možnosti prehod namenoma ne ponuja:
| Možnost | Zakaj ne |
|---|---|
| OData v različicah protokola pred 4 (Atom) | Prehod uporablja vmesnik OData v4. Različica 4 sama opisuje tipe, lastnosti in ključe, odjemalci Office pa jo znajo brati |
| povezava iz naslova (ime podatkovne zbirke ali strežnika v URL) | prehod bi povezavo sestavil iz URL in s tem izničil model aliasov, katerega namen je ravno to, da klicatelj podatkovne zbirke ne more izbrati |
| drugi sistemi za upravljanje podatkovnih zbirk kot SQL Server brez ponudnika | vsak sistem potrebuje svojega ponudnika; alias, katerega ponudnik ni naložen, prepreči zagon prehoda, namesto da bi bil sprejet kot prazna lupina |