SQL dotaz navrh DB
Zdravim, chtel jsem si pro nas zajmovy krouzek naprogramovat jednoduchou aplikaci s DB serverem a chtel jsem Vas pozadat o pomoc. Vzhledem k tomu, ze budu ukladat nejake citlive udaje, tak uplne nechci podcenit pristupy uzivatelu a proto jsem se chtel poradit s moznostmi pristupu.
Idea je takova :
Data budou bud automaticky ci mnou rucne nahravany do tabulek s prefixem IN_
Aplikace bude zpracovavat vlozena data a bude ukladat vysledky do tabulek s prefixem OUT_
DB bude bezet na MS SQL 2005 db na windows serveru. Aplikaci ma nekolik jednotlivcu na svem PC, kazdy jednotlivec bude mit pristup do jine casti aplikace (pripadne nejake tlacitka v aplikaci budou seda a nebude moci je tim padem zmacknout. Navic i v ramci stejne obrazovky aplikace bych chtel zobrazovat odlisna data v zavislosti na damen uzivateli (aby napr. vedouci sveho taboru mohl v aplikaci zpracovat a vyexportovat a videl rodna cisla apod pouze zaku urciteho oddilu, ne vsech). Proto me napadlo nekolik moznosti jak toto resit:
1} Aplikace se pripoji na DB server (nejsou ve stejne domene) a zde bude na MS SQL serveru bude jeden databazovy ucet pro komunikaci s aplikaci. Nechal bych naprogramovat, aby aplikace poslala (skrz jediny ucet v db pro tuto aplikaci) uzivatele prave nalogovaneho do aplikace (pri zapnuti aplikace zadal login a heslo, to by se zkontrolovalo s DB, kde by byla tabulka Uzivatele s heslem a role na zaklade cehoz by se zpet poslala informace, jake aplikacni menu a funkce maji byt v aplikaci viditelne/spustitelne? Cela komunikace by byla pres jeden aplikacni ucet. Plus krome toho bych mel tabulku pro uzivatele k jakym datum by mel pristup, tzn. napr pro roli vedouci oddilu bych mel definovane kam ma v aplikaci pristup a na zaklade druhe tabulky by se vzalo ze osoba 1 s roli vedouci oddilu pristup k temto clenum oddilu a osoba 2 zase k jinym (vyuzitim pohledu). Tuto tabulku by spravoval napr. nejaky jeden admin.
2) Druha varianta pokud by Windows Server i uzivatelske PC byli ve stejne domene, tak by slo vyuzit windows autentikace s tim ze by se nemuseli pripojovat pres logovani do aplikace a porovnani hesla, ale primo by byla skupina v domene s nazvem napr. SKAUTSKY ODDIL ve ktere by byli pridani clenove. Ti by se pak po prihlaesni do aplikace dokazali pripojit na SQL server (zde by byl dan pristup skupine SKATSKY ODDIL) a na zaklade domenoveho uctu by se z tabulky uzivatelu opet vzala role a data k jakym je v ramci apliakce pristup a jake funkec se jim zpristupni.
Myslite ze budou fungovat obe varianty? S tim ze preferovana je asi 2.
Muj treti dotaz je v SQL s jakym datovym typem bych mel udelat pole "heslo" v ramci tabulky uzivatelu pro variantu 1, aby bylo sifrovane. Chtel bych pak pouzit napr. takovouto funkci pro porovnani zda uzivatel ktery se do aplikace hlasi ma prava: pwdcompare(HESLO PRIJATE ZADANIM Z APLIKACE, password_hash)
Dekuji mnohokrat
V podstatě ano ale ne přesně tak. Zaprvé, zmiňuješ, že by přístup byl přes aplikační účet a nějakou matici přístupů. To je OK - a naprosto standardní postup, ale ty přístupy v té tvé definiční tabulce musí být pro aplikaci, ne pro DB! Tj. například "vidí tlačítko ULOŽ", ne "má SELECT na tabuli X". Pokud jsi tím myslel, že chceš přímo podstčit nějakého uživatele MS SQL Serveru když jsi už pod nějakým účtem připojený (což nejde), tak když by to bylo z nějakého důvodu nutné (třeba chceš aby uživatelé importovali data pod svým vlastním účtem se vším všudy, aplikace by musela vytvořit ještě jednu connection do databáze, tentokrát s jiným přístupem.
U 1) by musel uživatel zadat username a heslo, nejde přes nějakou tabuli rolí impersonovat uživatele pro MSSQL když jsi přihlášený do db jako aplikační účet
u 2) by se musela vytvořit zase druhá connection, tentokrát s parametrem SSPI (integrované ověření windows) a přes tu by se lezlo do těch dalších tabulí.
Hashované heslo můžeš ukládat úplně obyčejně jako varchar.
Hashovat - třeba jako MD5 - to můžeš buď v aplikaci, nebo třeba:
RIGHT(master.dbo.fn_varbintohexstr (HashBytes(‚MD5‘,‚testovací řetězec‘)) ,32)
Vladimíre, díky za odpověď.
Ano myslel jsem tak ze by pristupy byly pro aplikaci. Mozna jsem to popsal ne zcela presne, ale kdyz to hodne zjednodusim a odprostim se od idealniho db navrhu tak v zasade bych si predstavoval nasledujici k jednotlivym bodum:
1) v DB bych mel jeden databazovy ucet nazvany aplikacni_ucet a ve vytvorene tabulce napr. s jmenem "users" bych mel id, username, password hash a role
uzivatel by prisel k aplikaci zadal by username novak a heslo 123 a aplikace by se pres ucet aplikacni_ucet pripojila na DB, podivala se do tabulky "users" zda sedi hash hesla a pokud ano tak by zobrazila prislusnou obrazovku (na zaklade hodnoty, kterou by si precetla z pole role tabulky "users"). Uzivatel by mel napr. v aplikaci moznost stisknout export a tak by se data zapsala do nejake tabulky treba out_vysledky. Komunikace by probihala z pohledu DB pres tento jeden ucet aplikacni_ucet. Nechapu z tve odpovedi zda tedy musi mit kazdy uzivatel svuj databazovy ucet, nebo jestli by to takto jak popisuji slo pres jeden aplikacni_ucet (ktery by byl jediny v databazi - napr. jako dbo).
2) ma predstava byla ze by byla opet tabulka "users" s roli definujici pristup. Uzivatel by zapnul aplikaci ale uz by nezadaval heslo nebot by byl v domenove skupine s prislusnym pristupem k DB. Zde jako spravny novacek uplne nehcapu Vasi odpoved.
Znamena to ze aplikace nedokaze vzit windows udaje potrebne pro autentikaci a jako jako kdyz napr. zapinam management studio a pripojuji se na server s windows autentikaci, ze by se rovnou pripojila pod danym uzivatelem? Nechci Vazat prava select apod k temto jednotlivym tabulkam pro jednotlive, ale pouze aby mel uzivatel pravo se podivat do tabulky user a tim padem mu DB vratila hodnotu role (tabulka user) a aplikace na zaklade teto role zobrazila prislusne menu a obrazovky.
Tato varianta 2 je preferovana v tech oddilech kde by meli server a uzivatelske PC ve stejne domene (odpada nutnost se prihlasovat a pristupy jsou reseny ze admin pouze prida prislusne osoby do skupiny, ktera je schopna se pripojovat na DB server), nemate prosim nekde po ruce odkaz ktery by se pekne z SQL pohledu touto variantou zabyval?
Dekuji za trpelivost
osobne to mame podobne resene v informacnim systemu s tim, ze aplikace do databaze pristupuje pres jedno jmeno a heslo.
V DB je tabulka uzivatelu + jejich nastaveni prav atd.
Podporujeme oba pristupy:
1. uzivatel pri spusteni aplikace zada jmeno a heslo, to se overi proti tabulce v DB
2. uzivatel jmeno a heslo nezadava a automaticky se bere jeho domenove jmeno (overil se pri prihlasovani do PC)
Prepnuti je jen veci konfiguracniho souboru aplikace.
a jde prosim u obou metod tedy zajistit, aby uzivatel nemohl menit data v in tabulkach a jen je cist?
Tzn ze pro metodu 1 to nastavim pro aplikacni_ucet a pro metodu 2 pro celou skupinu s pristupem, ze budou mit jen pravo execute preddefinovane views, ktere zobrazi prislusne vysledky (na zaklade toho do jakeho oddilu vedouci spada, tak jeden view mu ukaze pouze osobni udaje POUZE clenu sveho oddilu?)
Uzivatel se primo do databaze pomoci nejakeho nastroje neprihlasi, protoze pristupove udaje nezna
Jestli uzivatel muze menit tabulky, zalezi pak na nastaveni prav a vlastni aplikaci.
Pokud bys to chtel resit pomoci overovani a domenove ucty, pak by bylo nejrozumnejsi vytvorit na serveru uzivateleske skupiny a ten pridelit pristup k objektum serveru (tabulka).
Nektera skupina by mela tabulky jen pro cteni (grant select on tabulka to skupina), nektera i pro zapis a zmeny
Jeste bych se chtel zeptat na jeden dotaz
1) zda se da nejak nastavit hromadne v MS SQL Server 2005 na vsechny tabulky, aby uzivatelska skupina mela moznost pouze select a update.
V security-user-properties-Securables-Add-all object of type - table dokazu vylistovat vsechny tabulky, ale nenasel jsem moznost to hromadne oznacit ale musim tabulku po tabulce zaskrtavat GRANT na SELECT. Jde to nejak hromadne?
Postupne bych to udelal treba takhle:
use [databaze]
GO
GRANT SELECT ON [dbo].[tabulka1] TO [MASINA\LICusers]
GO
use [databaze]
GO
GRANT SELECT ON [dbo].[tabulka2] TO [MASINA\LICusers]
GO
....
Ale jde to udelat nejak na vsechny tabulky?
Seznam tabulek, ktere zacinaji na "IN" dostanes napr. pomoci prikazu:
Takze ve spojeni s kurzorem jsi schopny nastavit granty na vsechny tabulky, zacinajici na IN automaticky
Good point s kurzorem, avsak jeste bych Vas poprosil o radu. Pokud zakomentuji cast s pridavanim prav
, tak vse funguje v poradku a vypise to. Pokud ji vsem necham tak mi to pise nasledujici chybu:
A jeste me napadlo, setkavam se v SQL kdzy mam v ciyi klic a do jedne tabulky se snazim vlozit zaznam, ktery neni v druhe proklicovane tabulce to hodi exceptions a nic se nevlozi. Vkladam vsak selectem hromadne dat ada se nejak toto omezit, aby to preskocilo tyto zaznamy, ktere nemaji odpovidajici hodnotu a importovali se jen ty spravne??