context_info ili gde da smestim podatke o konekciji -- sqlserver.iz.rs
DESCRIPTION
SQL Server context info tutorialTRANSCRIPT
-
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