Tietosuojan palomuurin kulissien takana
Muistiinpano
Yksityisyystasot eivät ole tällä hetkellä käytettävissä Power Platform -tietovoissa, mutta tuotetiimi pyrkii siihen, että nämä toiminnot otetaan käyttöön.
Jos olet käyttänyt Power Queryä jonkin aikaa, olet todennäköisesti kokenut sen. Siinä on kysely poispäin, kun yhtäkkiä saat virheilmoituksen, jota mikään määrä online-hakua, kyselyn säätämistä tai näppäimistön määrittämistä ei voi korjata. Esimerkkivirhe:
Formula.Firewall: Query 'Query1' (step 'Source') references other queries or steps, so it may not directly access a data source. Please rebuild this data combination.
Tai ehkä:
Formula.Firewall: Query 'Query1' (step 'Source') is accessing data sources that have privacy levels which cannot be used together. Please rebuild this data combination.
Nämä Formula.Firewall
virheet ovat seurausta Power Queryn tietosuojan palomuurista (tunnetaan myös palomuurina), joka saattaa toisinaan vaikuttaa siltä, että se on olemassa pelkästään tietoanalyytikkojen turhauttamiseksi ympäri maailmaa. Usko tai älä, palomuurilla on kuitenkin tärkeä tarkoitus. Tässä artikkelissa tutkimme kulissien takana, jotta ymmärrämme paremmin, miten se toimii. Paremman ymmärryksen avulla pystyt toivottavasti paremmin diagnosoimaan ja korjaamaan palomuurivirheitä tulevaisuudessa.
Mikä se on?
Tietosuojan palomuurin tarkoitus on yksinkertainen: se estää Power Queryä vuotamasta tietoja tahattomasti lähteiden välillä.
Miksi tämä on tarpeellista? Voit varmasti luoda joitakin M-m-arvoja, jotka välittävät SQL-arvon OData-syötteeseen. Tämä olisi kuitenkin tarkoituksellista tietovuotoa. Mashup-tekijä tietää (tai ainakin hänen pitäisi) tietää tekevänsä näin. Miksi sitten täytyy suojautua tahattomia tietovuotoja vastaan?
Vastaus? Taitto.
Taitto?
Taittaminen on termi, joka viittaa lausekkeiden muuntamiseen M:ssä (kuten suodattimet, uudelleennimeämiset, liitokset ja niin edelleen) toiminnoiksi raakatietolähdettä vastaan (kuten SQL ja OData). Valtava osa Power Queryn voimasta johtuu siitä, että PQ voi muuntaa käyttäjän käyttöliittymän kautta suorittamat toiminnot monimutkaisiksi SQL- tai muiksi taustatietolähdekieliksi ilman, että käyttäjän tarvitsee tietää mainittuja kieliä. Käyttäjät saavat alkuperäisen tietolähdetoiminnon suorituskyvyn helposti hyödyntäen käyttöliittymää, jossa kaikki tietolähteet voidaan muuntaa käyttämällä yleisiä komentoja.
Osana lähteeseen delegointia PQ saattaa joskus päätellä, että tehokkain tapa suorittaa tietty kooste on ottaa tietoja yhdestä lähteestä ja välittää ne toiselle. Jos esimerkiksi liität pienen CSV-tiedoston valtavaan SQL-taulukkoon, et todennäköisesti halua PQ:n lukevan CSV-tiedostoa, lukevan koko SQL-taulukkoa ja liittävän sen sitten yhteen paikallisessa tietokoneessa. Haluat luultavasti, että PQ tekstiin sidotaan CSV-tiedot SQL-lauseeseen ja pyydetään SQL-tietokantaa suorittamaan liittyminen.
Näin tahaton tietovuoto voi tapahtua.
Kuvittele, että olet liittymässä SQL-tietoihin, jotka sisälsivät työntekijöiden sosiaaliturvatunnuksia ulkoisen OData-syötteen tuloksiin, ja yhtäkkiä huomasit, että SQL:n sosiaaliturvatunnuksia lähetettiin OData-palveluun. Huonoja uutisia.
Tällainen tilanne on sellainen, jonka palomuuri on tarkoitettu estämään.
Miten se toimii?
Palomuuri estää yhdestä lähteestä peräisin olevien tietojen tahattoman lähettämisen toiseen lähteeseen. Tarpeeksi yksinkertainen.
Miten se suorittaa tämän tehtävän?
Se tekee tämän jakamalla M-kyselyt osioiksi ja pakottamalla sitten seuraavan säännön:
- Osio voi joko käyttää yhteensopivia tietolähteitä tai viitata muihin osioihin, mutta ei molempiin.
Yksinkertainen... silti hämmentävää. Mikä osio on? Mikä tekee kahdesta tietolähteestä "yhteensopivan"? Ja miksi palomuurin tulisi olla varovainen, jos osio haluaa käyttää tietolähdettä ja viitata osioon?
Katsotaan tätä tarkemmin ja tarkastellaan yllä olevaa sääntöä yksi kerrallaan.
Mikä osio on?
Osio on yksinkertaisimmillaan vain yhden tai useamman kyselyn vaiheen kokoelma. Mahdollisimman tarkka osio (vähintään nykyisessä toteutuksessa) on yksittäinen vaihe. Suurimmat osiot voivat joskus kattaa useita kyselyitä. (Lisätietoja tästä myöhemmin.)
Jos et ole tutustunut vaiheisiin, voit tarkastella niitä Power Query -editori-ikkunan oikealla puolella kyselyn valitsemisen jälkeen Käytössä olevat vaiheet -ruudussa. Vaiheissa seurataan kaikkea, mitä olet tehnyt tietoihisi muuntamiseksi lopulliseen muotoon.
Osiot, jotka viittaavat muihin osioihin
Kun kysely arvioidaan palomuurin ollessa käytössä, palomuuri jakaa kyselyn ja kaikki sen riippuvuudet osioihin (eli vaiheryhmiin). Aina, kun yksi osio viittaa johonkin toiseen osioon, palomuuri korvaa viittauksen kutsulla erikoisfunktioon nimeltä Value.Firewall
. Toisin sanoen palomuuri ei salli osioiden käyttää toisiaan suoraan. Kaikkia viittauksia muokataan menemään läpi palomuurin kautta. Palomuuri on portinvartija. Osion, joka viittaa toiseen osioon, on saatava palomuurin käyttöoikeus. Palomuuri valvoo, sallitaanko viitatut tiedot osioon vai ei.
Tämä kaikki voi vaikuttaa melko abstraktilta, joten tarkastellaan esimerkkiä.
Oletetaan, että sinulla on kysely nimeltä Työntekijät, joka hakee joitakin tietoja SQL-tietokannasta. Oletetaan, että sinulla on myös toinen kysely (EmployeesReference), joka viittaa vain Työntekijöihin.
shared Employees = let
Source = Sql.Database(…),
EmployeesTable = …
in
EmployeesTable;
shared EmployeesReference = let
Source = Employees
in
Source;
Nämä kyselyt jaetaan kahdeksi osioksi: yksi Työntekijät-kyselylle ja toinen EmployeesReference-kyselylle (joka viittaa Työntekijät-osioon). Kun nämä kyselyt kirjoitetaan palomuurin ollessa käytössä, ne kirjoitetaan uudelleen seuraavasti:
shared Employees = let
Source = Sql.Database(…),
EmployeesTable = …
in
EmployeesTable;
shared EmployeesReference = let
Source = Value.Firewall("Section1/Employees")
in
Source;
Huomaa, että yksinkertainen viittaus Työntekijät-kyselyyn on korvattu kutsulla kohteeseen Value.Firewall
, joka antaa Työntekijät-kyselyn koko nimen.
Kun EmployeesReference arvioidaan, palomuuri pysäyttää kutsun Value.Firewall("Section1/Employees")
. Sillä on nyt mahdollisuus hallita, onko pyydetty tieto työnkulku EmployeesReference-osioon (ja miten). Se voi tehdä monia asioita: kieltää pyynnön, puskuroida pyydettyjä tietoja (mikä estää alkuperäisen tietolähteeseen delegoimisen edelleen) ja niin edelleen.
Näin palomuuri hallitsee osioiden välillä virtaavia tietoja.
Osiot, jotka käyttävät suoraan tietolähteitä
Oletetaan, että määrität kyselyn 1 yhdellä vaiheella (huomaa, että tämä yksi vaihe kysely vastaa yhtä palomuurin osiota) ja että tämä yksittäinen vaihe käyttää kahta tietolähdettä: SQL-tietokantataulukkoa ja CSV-tiedostoa. Miten palomuuri käsittelee tämän, koska osioviittausta ei ole, joten ei kutsuta Value.Firewall
sitä kaapata? Palataan aiemmin mainittuun sääntöön:
- Osio voi joko käyttää yhteensopivia tietolähteitä tai viitata muihin osioihin, mutta ei molempiin.
Jotta yhden osion mutta kahden tietolähteen kyselyn suorittaminen olisi sallittua, sen kahden tietolähteen on oltava "yhteensopivia". Toisin sanoen tietojen on oltava kunnossa, jotta tiedot jaetaan kaksisuuntaisesti niiden välillä. Tämä tarkoittaa sitä, että molempien lähteiden yksityisyystasojen on oltava julkisia tai molempien on oltava organisaatiollisia, koska nämä ovat ainoat kaksi yhdistelmää, jotka sallivat jakamisen molempiin suuntiin. Jos molemmat lähteet on merkitty yksityisiksi tai toinen merkitään julkiseksi ja toinen on merkitty organisaatioksi tai joillakin muilla yksityisyystasojen yhdistelmillä, kaksisuuntaista jakamista ei sallita, joten ei ole turvallista, että molemmat arvioidaan samassa osiossa. Tämä tarkoittaisi, että tietovuotoja ei voisi tapahtua lainkaan (lähteeseen delegoinnin vuoksi), eikä palomuurilla olisi mitään keinoa estää sitä.
Mitä tapahtuu, jos yrität käyttää yhteensopimattomia tietolähteitä samassa osiossa?
Formula.Firewall: Query 'Query1' (step 'Source') is accessing data sources that have privacy levels which cannot be used together. Please rebuild this data combination.
Toivottavasti nyt ymmärrät paremmin jotakin tämän artikkelin alussa luetelluista virhesanomista.
Ota huomioon, että tämä yhteensopivuusvaatimus koskee vain tiettyä osiota. Jos osio viittaa muihin osioihin, viitattujen osioiden tietolähteiden ei tarvitse olla yhteensopivia toistensa kanssa. Tämä johtuu siitä, että palomuuri voi puskuroida tietoja, mikä estää alkuperäisen tietolähteen uudelleen delegoimisen lähteeseen. Tiedot ladataan muistiin ja niitä käsitellään ikään kuin ne eivät olisi peräisin mistään.
Miksi ette tee molempia?
Oletetaan, että määrität kyselyn yhdellä vaiheella (joka vastaa jälleen yhtä osiota), joka käyttää kahta muuta kyselyä (eli kahta muuta osiota). Entä jos haluat samassa vaiheessa myös käyttää suoraan SQL-tietokantaa? Miksi osio ei voi viitata muihin osioihin ja käyttää suoraan yhteensopivia tietolähteitä?
Kuten aiemmin näit, kun yksi osio viittaa toiseen osioon, palomuuri toimii kaikkien osioon virtaavien tietojen portinvartijana. Tätä varten sen on voitava hallita sitä, mitä tietoja sallitaan. Jos osiossa on tietolähteitä ja tietoja virtaa sisään muista osioista, se menettää kykynsä olla portinvartija, koska sisään virtaavia tietoja voi vuotaa johonkin sisäisesti käytettävään tietolähteeseen tietämättä sitä. Näin ollen palomuuri estää osion, joka käyttää muita osioita, ei saa käyttää suoraan mitään tietolähteitä.
Mitä tapahtuu, jos osio yrittää viitata muihin osioihin ja käyttää myös tietolähteitä suoraan?
Formula.Firewall: Query 'Query1' (step 'Source') references other queries or steps, so it may not directly access a data source. Please rebuild this data combination.
Nyt sinun on toivottavasti helpompi ymmärtää toinen tämän artikkelin alussa mainittu virhesanoma.
Osiot tarkemmin
Kuten yllä olevista tiedoista todennäköisesti arvailet, se, miten kyselyt ositetaan, on lopulta uskomattoman tärkeää. Jos sinulla on vaiheita, jotka viittaavat muihin kyselyihin ja muihin tietolähteisiin pääsemiseen, huomaat nyt toivottavasti, että osion rajojen piirtäminen tietyissä paikoissa aiheuttaa palomuurivirheitä, kun taas niiden piirtäminen muihin paikkoihin mahdollistaa kyselyn suorittamisen helposti.
Miten kyselyt ositetaan?
Tämä osio on luultavasti tärkein tapa ymmärtää, miksi palomuurivirheitä esiintyy, ja ymmärtää niiden ratkaisemisen (jos mahdollista).
Tässä on korkean tason yhteenveto osiointilogiikasta.
- Ensimmäinen ositus
- Luo osion kullekin vaiheelle kussakin kyselyssä
- Staattinen vaihe
- Tämä vaihe ei riipu arviointituloksista. Sen sijaan se perustuu siihen, miten kyselyt on jäsennetty.
- Parametrien rajaus
- Rajaa parametri-esque-osiot, eli kaikki, jotka:
- Ei viittaa mihinkään muuhun osioon
- Ei sisällä mitään funktiokutsuja
- Ei ole syklinen (eli se ei viittaa itseensä)
- Huomaa, että osion poistaminen sisältää sen käytännössä muissa osioissa, jotka viittaavat siihen.
- Parametriosioiden rajauksen avulla tietolähdefunktiokutsuissa käytetyt parametriviittaukset (esimerkiksi
Web.Contents(myUrl)
) toimivat sen sijaan, että heität "osio ei voi viitata tietolähteisiin ja muihin vaiheisiin" -virheitä.
- Rajaa parametri-esque-osiot, eli kaikki, jotka:
- Ryhmittely (staattinen)
- Osiot yhdistetään alhaalta ylöspäin -riippuvuusjärjestyksessä. Seuraavissa yhdistetyissä osioissa seuraavat ovat erillisiä:
- Osiot eri kyselyissä
- Osiot, jotka eivät viittaa muihin osioihin (ja saavat siten käyttää tietolähdettä)
- Osiot, jotka viittaavat muihin osioihin (ja ovat siksi kiellettyjä käyttämästä tietolähdettä)
- Osiot yhdistetään alhaalta ylöspäin -riippuvuusjärjestyksessä. Seuraavissa yhdistetyissä osioissa seuraavat ovat erillisiä:
- Parametrien rajaus
- Tämä vaihe ei riipu arviointituloksista. Sen sijaan se perustuu siihen, miten kyselyt on jäsennetty.
- Dynaaminen vaihe
- Tämä vaihe riippuu arviointituloksista, mukaan lukien eri osioiden käsittelemistä tietolähteistä.
- Leikkaus
- Poistaa osiot, jotka täyttävät kaikki seuraavat vaatimukset:
- Ei käytä mitään tietolähteitä
- Ei viittaa mihinkään osioihin, jotka käyttävät tietolähteitä
- Ei ole syklinen
- Poistaa osiot, jotka täyttävät kaikki seuraavat vaatimukset:
- Ryhmittely (dynaaminen)
- Nyt kun tarpeettomat osiot on poistettu, yritä luoda mahdollisimman suuria Lähde-osioita. Tämä tehdään yhdistämällä osiot noudattamalla samoja sääntöjä, jotka on kuvattu yllä olevassa staattisen ryhmittelyn vaiheessa.
Mitä tämä kaikki tarkoittaa?
Käydään läpi esimerkki, joka havainnollistaa edellä esitetyn monimutkaisen logiikan toimintaa.
Tässä on esimerkkiskenaario. Se on melko yksinkertainen tekstitiedoston (yhteystiedot) yhdistäminen SQL-tietokantaan (Työntekijät), jossa SQL-palvelin on parametri (DbServer).
Kolme kyselyä
Tässä on M-koodi kolmelle tässä esimerkissä käytetylle kyselylle.
shared DbServer = "MySqlServer" meta [IsParameterQuery=true, Type="Text", IsParameterQueryRequired=true];
shared Contacts = let
Source = Csv.Document(File.Contents("C:\contacts.txt"),[Delimiter=" ", Columns=15, Encoding=1252, QuoteStyle=QuoteStyle.None]),
#"Promoted Headers" = Table.PromoteHeaders(Source, [PromoteAllScalars=true]),
#"Changed Type" = Table.TransformColumnTypes(#"Promoted Headers",{{"ContactID", Int64.Type}, {"NameStyle", type logical}, {"Title", type text}, {"FirstName", type text}, {"MiddleName", type text}, {"LastName", type text}, {"Suffix", type text}, {"EmailAddress", type text}, {"EmailPromotion", Int64.Type}, {"Phone", type text}, {"PasswordHash", type text}, {"PasswordSalt", type text}, {"AdditionalContactInfo", type text}, {"rowguid", type text}, {"ModifiedDate", type datetime}})
in
#"Changed Type";
shared Employees = let
Source = Sql.Databases(DbServer),
AdventureWorks = Source{[Name="AdventureWorks"]}[Data],
HumanResources_Employee = AdventureWorks{[Schema="HumanResources",Item="Employee"]}[Data],
#"Removed Columns" = Table.RemoveColumns(HumanResources_Employee,{"HumanResources.Employee(EmployeeID)", "HumanResources.Employee(ManagerID)", "HumanResources.EmployeeAddress", "HumanResources.EmployeeDepartmentHistory", "HumanResources.EmployeePayHistory", "HumanResources.JobCandidate", "Person.Contact", "Purchasing.PurchaseOrderHeader", "Sales.SalesPerson"}),
#"Merged Queries" = Table.NestedJoin(#"Removed Columns",{"ContactID"},Contacts,{"ContactID"},"Contacts",JoinKind.LeftOuter),
#"Expanded Contacts" = Table.ExpandTableColumn(#"Merged Queries", "Contacts", {"EmailAddress"}, {"EmailAddress"})
in
#"Expanded Contacts";
Tässä on ylemmän tason näkymä, joka näyttää riippuvuudet.
Osioidaan
Lähennetään hieman, lisätään vaiheita kuvaan ja aletaan käydä läpi osiointilogiikkaa. Tässä on kolmen kyselyn kaavio, jossa alkuperäiset palomuurin osiot näkyvät vihreinä. Huomaa, että kukin vaihe alkaa omasta osiostaan.
Seuraavaksi rajataan parametriosiot. Näin ollen DbServer sisällytetään implisiittisesti Lähde-osioon.
Nyt suoritamme staattisen ryhmittelyn. Tämä säilyttää osioiden erottelun erillisissä kyselyissä (huomaa esimerkiksi, että Työntekijät-kohdan kahta viimeistä vaihetta ei ryhmitetä yhteystietojen osavaiheiden kanssa) ja osioiden välillä, jotka viittaavat muihin osioihin (kuten Työntekijöiden kaksi viimeistä osavaihetta) ja niihin, jotka eivät ole (kuten Työntekijät-osion kolme ensimmäistä vaihetta).
Siirrymme nyt dynaamiseen vaiheeseen. Tässä vaiheessa edellä mainitut staattiset osiot arvioidaan. Osiot, jotka eivät käytä tietolähteitä, rajataan. Osiot ryhmitetään sitten, jotta voit luoda mahdollisimman suuria lähdeosioita. Tässä malliskenaariossa kaikki jäljellä olevat osiot käyttävät kuitenkin tietolähteitä, eikä mitään muuta ryhmittelyä voi tehdä. Mallimme osiot eivät siis muutu tämän vaiheen aikana.
Teeskentely
Katsotaan kuitenkin, mitä tapahtuisi, jos Yhteystiedot-kysely olisi tekstitiedostosta peräisin olevan kyselyn sijaan pysyväiskoodattu M-kielellä (esimerkiksi Anna tiedot -valintaikkunan kautta).
Tässä tapauksessa Yhteystietojen kysely ei käytä mitään tietolähteitä. Näin ollen se rajataan dynaamisen vaiheen ensimmäisen osan aikana.
Kun Yhteystiedot-osio on poistettu, Työntekijät-taulukon viimeiset kaksi osavaihetta eivät enää viitanneet mihinkään osioon lukuun ottamatta osiota, joka sisältää Työntekijät-taulukon kolme ensimmäistä osavaihetta. Näin kaksi osiota ryhmitettäisiin.
Osio näyttäisi tältä.
Esimerkki: Tietojen välittäminen yhdestä tietolähteestä toiseen
Riittää abstrakti selitys. Seuraavassa on yleinen skenaario, jossa todennäköisesti kohtaat palomuurivirheen, ja annetaan ohjeet sen ratkaisemiseen.
Kuvittele, että haluat etsiä yrityksen nimen Northwind OData -palvelusta ja suorittaa sitten Bing-haun yrityksen nimen avulla.
Ensin luodaan Yritys-kysely yrityksen nimen noutamiseksi.
let
Source = OData.Feed("https://services.odata.org/V4/Northwind/Northwind.svc/", null, [Implementation="2.0"]),
Customers_table = Source{[Name="Customers",Signature="table"]}[Data],
CHOPS = Customers_table{[CustomerID="CHOPS"]}[CompanyName]
in
CHOPS
Seuraavaksi luot hakukyselyn, joka viittaa yritykseen ja välittää sen Bingille.
let
Source = Text.FromBinary(Web.Contents("https://www.bing.com/search?q=" & Company))
in
Source
Tässä vaiheessa kohtaat ongelmia. Haun arviointi tuottaa palomuurivirheen.
Formula.Firewall: Query 'Search' (step 'Source') references other queries or steps, so it may not directly access a data source. Please rebuild this data combination.
Tämä johtuu siitä, että Haun Lähde-vaihe viittaa tietolähteeseen (bing.com) ja myös toiseen kyselyyn/osioon (Yritys). Se rikkoo edellä mainittua sääntöä ("osio voi joko käyttää yhteensopivia tietolähteitä tai viitata muihin osioihin, mutta ei molempiin").
Mitä pitää tehdä? Yksi vaihtoehto on poistaa palomuuri kokonaan käytöstä (Tietosuoja-asetuksen kautta, jonka nimi on Ohita yksityisyystasot, ja mahdollisesti parantaa suorituskykyä). Mutta entä jos haluat, että palomuuri on käytössä?
Voit ratkaista virheen poistamatta palomuuria käytöstä yhdistämällä Yrityksen ja etsimällä yksittäiseksi kyselyksi seuraavasti:
let
Source = OData.Feed("https://services.odata.org/V4/Northwind/Northwind.svc/", null, [Implementation="2.0"]),
Customers_table = Source{[Name="Customers",Signature="table"]}[Data],
CHOPS = Customers_table{[CustomerID="CHOPS"]}[CompanyName],
Search = Text.FromBinary(Web.Contents("https://www.bing.com/search?q=" & CHOPS))
in
Search
Kaikki tapahtuu nyt yksittäisen osion sisällä. Jos kahden tietolähteen yksityisyystasot ovat yhteensopivia, palomuurin pitäisi nyt olla tyytyväinen, eikä näyttöön enää tule virhesanoma.
Se on kääre
Vaikka tästä aiheesta voisi sanottua paljon muutakin, tämä johdantoartikkeli on jo tarpeeksi pitkä. Toivottavasti se on saanut paremman käsityksen palomuurista ja auttaa sinua ymmärtämään ja korjaamaan palomuurivirheitä, kun kohtaat ne tulevaisuudessa.