context_info ili gde da smestim podatke o konekciji -- sqlserver.iz.rs

6
Context_Info ili gde da smestim podatke o konekciji This entry was posted in Programiranje - napredni nivo Programiranje - pocetni nivo and tagged Context_info Login Trigger on 29/12/2011 by Miloš. Postoje prilike u kojima je potrebno neke podatke čuvati tokom trajanja jedne konekcije. To može biti recimo neka interna šifra radnika koji je ulogovan u aplikaciju, datum i vreme kada je uradio neki posao, koji objekat je neku operaciju izvršio (da li je neki update u tabeli obavila procedura, funkcija ili ad hoc upit) itd. Sve ovo se može na neki način čuvati u standardnim tabelama SQL servera. Uobičajeno je u većini softverskih proizvoda da se beleže podaci u neku tabelu prilikom logovanja, i to je sasvim u redu. Međutim, ponekad tabela može biti preglomazna, loše ogranizovana ili nedostupna, i ovaj mali savet vam može dobro doći. Zamislimo softver koji u svakom momentu koriste hiljade ili čak desetine hiljada korisnika (velika banka, državna institucija, telekomunikacioni operater…). Imamo zadatak da razvijemo neku vrstu auditing sistema. Za manje upućene – u pitanju je softverski veliki brat: kada ste kliknuli na neko dugme, koji je to rezultat proizvelo, koja je transakcija pokrenuta i u kom kontekstu, kada se transakcija završila i sa kojim rezultatom, sve se to uredno beleži u neku bazu (ili u pojednostavljenom slučaju – u jednu tabelu). Ja koristim termin audit odnosno auditing jer u našoj struci nema boljeg (bolje reći nikakvog) prevoda. Inače je prevod vrlo jednostavan – revizija, ali eto, probajte da nekome objasnite da pravite sistem za softversku reviziju… Nego, da se vratimo na temu. Možemo da napravimo tabelu koja sadrži šifru zaposlenog koji se loguje, SPID, datum i vreme logovanja i sl. Međutim, softver je za nas crna kutija a audit radimo preko triggera. E sad, zamislite tu tabelu koja se pri SVAKOJ transakciji čita, pa puta desetine hiljada korisnika, pa puta broj operacija gde se ti podaci čitaju. Vrlo vrlo sporo. Tu može da uskoči Context_info i olakša nam život. Kako? Prvo da vidimo šta je Context_info i kako radi? SQLServer.iz.rs male SQL čarolije Home » Programiranje - pocetni nivo » Context_Info ili gde da smestim podatke o konekciji Search for: Search Najsvežiji tekstovi Kategorije Arhiva Kada Select * ne znači ‘Uzmi sve’ FILESTREAM tip kolone ili kako skladištiti fajl unutar SQL Servera (2/2) FILESTREAM tip kolone ili kako skladištiti fajl unutar SQL Servera (1/2) Administracija (9) Novosti (3) Programiranje – napredni nivo (7) Programiranje – pocetni nivo (4) Programiranje – srednji nivo (10) Slobodna tema (6) 1 of 6 4/24/2015 10:13 AM

Upload: milos-tucakov

Post on 13-Nov-2015

217 views

Category:

Documents


0 download

DESCRIPTION

SQL Server context info tutorial

TRANSCRIPT

  • Context_Info ili gde dasmestim podatke o konekcijiThis entry was posted in Programiranje - napredni nivo Programiranje - pocetni nivo and tagged

    Context_info Login Trigger on 29/12/2011 by Milo.

    Postoje prilike u kojima je potrebno neke podatke uvati tokom trajanja jednekonekcije. To moe biti recimo neka interna ifra radnika koji je ulogovan u aplikaciju,datum i vreme kada je uradio neki posao, koji objekat je neku operaciju izvrio (da li jeneki update u tabeli obavila procedura, funkcija ili ad hoc upit) itd. Sve ovo se moe naneki nain uvati u standardnim tabelama SQL servera. Uobiajeno je u veinisoftverskih proizvoda da se belee podaci u neku tabelu prilikom logovanja, i to jesasvim u redu. Meutim, ponekad tabela moe biti preglomazna, loe ogranizovana ilinedostupna, i ovaj mali savet vam moe dobro doi.Zamislimo softver koji u svakom momentu koriste hiljade ili ak desetine hiljadakorisnika (velika banka, dravna institucija, telekomunikacioni operater). Imamozadatak da razvijemo neku vrstu auditing sistema. Za manje upuene u pitanju jesoftverski veliki brat: kada ste kliknuli na neko dugme, koji je to rezultat proizvelo, kojaje transakcija pokrenuta i u kom kontekstu, kada se transakcija zavrila i sa kojimrezultatom, sve se to uredno belei u neku bazu (ili u pojednostavljenom sluaju ujednu tabelu). Ja koristim termin audit odnosno auditing jer u naoj struci nema boljeg(bolje rei nikakvog) prevoda. Inae je prevod vrlo jednostavan revizija, ali eto,probajte da nekome objasnite da pravite sistem za softversku revizijuNego, da se vratimo na temu. Moemo da napravimo tabelu koja sadri ifruzaposlenog koji se loguje, SPID, datum i vreme logovanja i sl. Meutim, softver je zanas crna kutija a audit radimo preko triggera. E sad, zamislite tu tabelu koja se priSVAKOJ transakciji ita, pa puta desetine hiljada korisnika, pa puta broj operacija gdese ti podaci itaju. Vrlo vrlo sporo. Tu moe da uskoi Context_info i olaka nam ivot.Kako?

    Prvo da vidimo ta je Context_info i kako radi?

    SQLServer.iz.rsmale SQL arolije

    Home Programiranje - pocetni nivo Context_Info ili gde da smestim podatke o konekcijiSearch for:

    Search

    Najsveijitekstovi

    Kategorije

    Arhiva

    Kada Select * neznai Uzmi sve

    FILESTREAM tipkolone ili kako

    skladititi fajl unutarSQL Servera (2/2)

    FILESTREAM tipkolone ili kako

    skladititi fajl unutarSQL Servera (1/2)

    Administracija (9)Novosti (3)Programiranje

    napredni nivo (7)

    Programiranje pocetni nivo (4)

    Programiranje srednji nivo (10)

    Slobodna tema (6)

    1 of 6 4/24/2015 10:13 AM

  • Dakle u pitanju je sistemska promenljiva (varijabla, ako hoete) ija je vrednostvezana za konekciju i moe da primi 128 bajtova podataka. Vrednost se upisuje nasledei nain:

    SET CONTEXT_INFO { binary_str | @binary_var }

    Parametar moe biti konstanta ili promenljiva, tipova binary ili varbinary. Na primer:Set Context_Info 0x616161

    ili

    Declare @VarB Varbinary(128)

    Set @VarB = Convert(Varbinary,'aaa')

    Set Context_info @VarB

    Vrednost moemo dobiti na nekoliko naina. Najjednostavnije je pozvati sistemskufunkciju (vai samo za SQL server verzije 2005 i novije), na sledei nain:Select Context_info()

    A rezultat je:

    ----------------------------------------------...

    0x61616100000000000000000000000000000000000000...

    Rezultat koji dobijemo je takoe (logino) binarnog tipa, ali se moe jednostavnokonvertovati (pod uslovom da znamo ta radimo tj. da smo tu vrednost mi i postavili) udruge tipove, na primer:

    Declare @VarC Varchar(128)

    Set @VarC = Convert(Varchar(3), Context_info())

    Print @VarC

    Context_info se takoe moe proitati iz sistemskih view-ovasys.dm_exec_connections , sys.dm_exec_sessions i sys.dm_exec_requests (sva tri od

    verzije 2005) ili tabele SysProcesses na primer:

    SELECT Convert(Varchar(3), Context_info) as Res

    FROM Master.dbo.SysProcesses

    Where SPID = @@SPID

    to rezultuje sledeim:Res

    ----

    aaa

    TagoviADO ANSI SQL API

    bazirano-na-skupovimaBLOB C# Chuck NorrisContext_info CursorDatum DB2 DBA DelphiDTS EMS SQL Manager ETL

    FILESTREAMHumor IBM Indexistorija Java Job JoinLInkovani server Login Microsoft

    ODBC

    OptimizacijaOracle PostgreSQL Povezani

    server Presek RBAR SQLAzure SQL Developer SQL

    Injection SQLSERVER SSISStored

    November 2014 (1)September 2014 (1)August 2014 (1)March 2014 (1)September 2013 (1)June 2013 (1)April 2013 (1)March 2013 (1)January 2013 (1)November 2012 (2)September 2012 (1)May 2012 (1)April 2012 (1)January 2012 (1)December 2011 (2)August 2011 (1)July 2011 (2)May 2011 (1)

    2 of 6 4/24/2015 10:13 AM

  • Napomena: Kada se u Context_info upisuju stringovi, treba voditi rauna da nisu svistringovi iste irine. ASCII karakteri zauzee 1 bajt, a Unicode 2.Nazad na zadatak

    Context_info se moe vrlo lepo iskoristiti da se smeste podaci o korisniku ulogovanomna aplikaciju (ovde treba napraviti razliku izmeu korisnika aplikacije i login-a za SQLserver. Mada, ako se u oba sluaja koristi Windows autentikacija onda je to jedno isto),domenskom nalogu ili nazivu raunara sa koga se pristupa bazi (host name).Kreiraemo jednu tabelu za upisivanje transakcija. Tabela je opteg tipa, nema nekuuoptrebnu vrednost ve slui samo za ilustraciju. Staviemo oznaku transakcije (ID),datum i vreme upisa, kao i neki iznos (reda radi, da tabela sadri bar neki konkretanpodatak).Create Table dbo.Trans

    (

    ID Int Identity(1,1) Primary key,

    DT DateTime Not Null Default GetDate(),

    Amount Float

    )

    Sa druge strane, pravimo AuditLog tabelu. Ona sadri vezu sa transakcijom, i podatkeo tome koji je korisnik aplikacije izvrtio transakciju, koji je domenski nalog, nazivraunara i login na SQL Server.

    Create Table dbo.AuditLog

    (

    TransId Int Not Null,

    AppUser Varchar(40),

    DomainUser Varchar(40),

    HostName Varchar(40),

    LoginName Varchar(40) Not Null Default SYSTEM_USER,

    )

    Nad tabelom za transakcije emo kreirati trigger, koji u AuditLog tabelu upisujepotrebne podatke. E tu sada stupa na snagu Context_info. Prvo emo prilikompovezivanja aplikacije sa bazom (nakon kreiranja konekcije), upisati vrednosti uContext_info. To se moe uraditi na sledei nain:

    Declare @VarB Varbinary(128)

    Set @VarB = Convert(Varbinary(128),'MyAppUser' + '&' + 'MyDomainUser' + '&' +

    'MyHostName' )

    Set Context_info @VarB

    U mom upitu su upisane string konstante MyAppUser, MyDomainUser iMyHostName, a u realnosti umesto njih treba da stoji stvarni korisnik aplikacije,domenski nalog i host name. Poto upisujemo tri podatka, uvodimo znakove & kaoseparatore, da bismo znali gde se zavrava jedan podatak a poinje drugi. Ovajkonkretan znak sam proizvoljno izabrao, to moe biti bilo ta, samo treba voditi raunada ne postoji mogunost da se taj znak nae u upisanim informacijama.

    procedure Talend TOSTransaction log Trigger

    Ubrizgavanje SQL-a

    3 of 6 4/24/2015 10:13 AM

  • A evo i trigera, koji nakon svako upisa transakcije ita Context_info i podatke upisuje uAuditLog tabelu:

    If Exists (Select * From Sysobjects Where Name = 'TRG_TRANS' And XType = 'TR')

    Drop Trigger dbo.TRG_TRANS

    Go

    Create Trigger dbo.TRG_TRANSON dbo.TransAFTER INSERTAS

    Declare @Context_info Varchar(128)Declare @CharIndex1 SmallintDeclare @CharIndex2 SmallintDeclare @AppUser Varchar(40)Declare @DomainUser Varchar(40)Declare @HostName Varchar(40)Select @Context_info = Convert(Varchar(128), Context_info)From Master.dbo.SysProcessesWhere SPID = @@SPID

    traimo poziciju prvog znaka &, da bismo znali da izdvojimo AppUsera-aSelect @CharIndex1 = CharIndex(&,@Context_info) traimo poziciju drugog znaka &, da bismo znali da izdvojimo DomainUser-aSelect @CharIndex2 = CharIndex(&,@Context_info, @CharIndex1+1)Set @AppUser = Substring(@Context_info, 0, @CharIndex1)Set @DomainUser = Substring(@Context_info, @CharIndex1+1,@CharIndex2 @CharIndex1-1)Set @HostName = Substring(@Context_info, @CharIndex2+1, 128) i kraj, ono to smo svi ekaliInsert into dbo.AuditLog (TransId, AppUser, DomainUser, HostName)Select ID, @AppUser, @DomainUser, @HostNameFrom Inserted

    GO

    Dakle u triggeru itamo podatke iz Context_info, zatim uzimamo broj transakcije i sveto upisujemo u AuditLog tabelu. Hajde da probamo:Insert into dbo.Trans (Amount)

    Values (100.00)

    (1 row(s) affected)

    Ovaj 1 red znai da je kroz trigger ubaen i red u audit tabelu.Upit:

    Select *

    4 of 6 4/24/2015 10:13 AM

  • From dbo.Trans

    prikazuje taj ubaeni red. A ovaj upit:Select *

    From dbo.AuditLog

    Daje takoe jedan red:

    Ovde se moe videti da je natrigger uredno upisao slog sa

    odgovarajuim podacima preuzetim iz Context_info.Napomene i zakljuakUpit sa Select * je dat radi jednostavnosti, i ne koristite taj oblik kod kue. Kreirani trigger je samo za insert tj. radi nakon ubacivanja slogova u tabelu Trans.Moe se izmeniti tako da radi i za auriranje odnosno brisanje podataka.U stvarnom projektu, trebalo bi da postoji strani klju na koloni TransId tabeleAuditLog.

    U kolonu LoginName ne upisujemo podatke kroz trigger ve se kao podrazumevanavrednost uzima rezultat poziva sistemske funkcije SYSTEM_USER. Iako i ovavrednost moe da se upisuje kroz trigger, ovako je uraeno radi demontstracije Defaultconstraint-a i poziva ove funkcije.Potrebno je proveriti da li korisnik (u aktuelnom sigurnosnom kontekstu) ima pravo daita Context_info. To moe biti realizovano preko Select prava na tabeli SysProcessesbaze Master (od verzije 2000 na dalje) ili prava na pozivanje funkcije Context_info()(od verzije 2005 na dalje).Za kraj: Context_info moe da ima i druge namene, a takoe i audit sistemi su u praksidaleko kompleksniji od navedenog primera. Dosta korisnih informacija se moe nai ina sajtu:http://jasondentler.com/blog/2010/01/exploiting-context_info-for-fun-and-audit/i naravno, Microsoft Books OnLine.

    Leave a CommentYour email address will not be published. Required fields are marked *

    Name *

    Email *

    Website

    5 of 6 4/24/2015 10:13 AM

  • RBAR trougaoni join 5 nacina da optimizujete upit ili proceduru

    Comment

    You may use these HTML tags and attributes:

    Post Comment

    2015 SQLServer.iz.rs Designed byThemes & Co

    Back to top

    6 of 6 4/24/2015 10:13 AM