Oprávnění
Jaká oprávnění potřebují návrháři a uživatelé a jak je řízen zápis konfigurace.
Přehled modelu
Konfigurace formuláře je soubor v knihovně Site Assets, takže ji chrání oprávnění SharePointu. Model má tři vrstvy:
- Kdo smí otevřít návrháře (role návrháře v konfiguraci): vlastníci webu, nebo vlastníci a vybraná skupina návrhářů.
- Kdo smí konfiguraci zapsat: určuje zámek složky
SiteAssets/FormCustomizer(unikátní oprávnění). - Kdo ji smí číst: běh formuláře čte konfiguraci jako přihlášený uživatel, proto musí mít čtení každý, kdo formulář otevírá.
Heslo „zámek editoru“ v návrháři není bezpečnostní hranice. Chrání před nechtěným otevřením editoru, ne před čtením nebo přepsáním souboru. Skutečnou ochranu dává pouze zámek složky popsaný níže.
Oprávnění návrháře
Tlačítko Nastavení formuláře (ozubené kolo) a příkaz Vlastní formulář vidí jen oprávnění uživatelé. Role se nastavuje v konfiguraci (securityConfig.allowedEditorRole, viz Zabezpečení konfigurace a uživatelská stránka o zabezpečení).
Hodnota allowedEditorRole | Kdo smí návrháře otevřít |
|---|---|
manageWeb (výchozí pro nové formuláře) | Vlastníci webu: uživatelé s oprávněním ManageWeb na seznamu. |
group | Vlastníci webu a členové SharePoint skupiny z allowedEditorGroup (podle názvu skupiny). |
manageLists (starší hodnota) | Chová se jako manageWeb: konfiguraci mění vlastníci webu. Samotné oprávnění „Správa seznamů“ nestačí, protože ho má i člen s úrovní Upravit. |
Oprávnění se ověřuje voláním effectiveBasePermissions seznamu a členství ve skupinách. Selže-li ověření (chyba REST), tlačítka se nezobrazí a uživatel se považuje za neoprávněného.
Pro samotné zamčení úložiště je potřeba oprávnění ManagePermissions na webu (vlastník webu). Návrhář ze skupiny může konfiguraci ukládat, ale oprávnění složek měnit nemůže.
Vytváření sloupců z návrháře
Nový sloupec seznamu smí z návrháře založit jen uživatel s oprávněním ManageLists (Správa seznamů) na seznamu. Oprávnění se bere z pageContext.list.permissions a poskytovatel dat ho hlásí jako canCreateFields; bez něj se akce vytvoření sloupce nenabízí. Je to samostatné od role návrháře výše: sloupec se vytváří pod identitou přihlášeného uživatele, takže ho SharePoint stejně nepustí bez práv. Sloupec se přidá jen do typů obsahu, které uživatel vybral. Selže-li přidání do některého typu (např. chybí oprávnění na typ obsahu), sloupec v seznamu zůstane a návrhář vypíše, kam se nepřidal.
Zamčené úložiště konfigurace
Dokud je úložiště nezamčené, dědí složka oprávnění knihovny Site Assets. Kdokoli s oprávněním zapisovat do knihovny (typicky člen webu s úrovní Upravit) pak může konfiguraci přepsat, a tím i podstrčit vlastní akce. Zámek tomu brání.
Co zámek dělá
Kořenová složka SiteAssets/FormCustomizer dostane unikátní oprávnění:
- Rozpojí se dědičnost s kopií dosavadních oprávnění (čtenáři nepřijdou o přístup).
- Skupina vlastníků webu a přihlášený uživatel, který zamyká, dostanou Full Control.
- Všem ostatním principálům se ponechá jen Read a Limited Access. Cokoli víc (Contribute, Edit, Design i vlastní role s oprávněním Správa seznamů nebo Správa oprávnění) se nahradí rolí Read. Role se určují podle typu, ne podle jazykového názvu.
- Pro celou organizaci (Everyone except external users, EEEU) a pro hosty (Everyone) se přidá Read. Obojí lze v návrháři vypnout: Čtení konfigurace pro celou organizaci (
securityConfig.configReadAllUsers) a Čtení konfigurace i pro externí uživatele (hosty) (securityConfig.configReadGuests); výchozí je zapnuto. - Vnořené položky s vlastními oprávněními se vrátí k dědění z kořene. Výjimkou jsou podsložky seznamů (viz dále).
Přístup se při změnách nejdřív přidává a teprve potom ubírá, takže nikdo nepřijde dočasně o čtení. Když zamčení selže, původní dědičnost se vrátí. Když se nepodaří ani návrat, zobrazí návrhář varování s příkazem pro opravu.
Součástí zámku je úklid vnořených položek pod FormCustomizer, které mají vlastní oprávnění (vrátí se k dědění). Dotaz najde vnořené položky podle FileRef a u každé zvlášť přečte příznak vlastních oprávnění (HasUniqueRoleAssignments). Pokud odpověď SharePointu některý z nich neobsahuje, zámek skončí chybou lockFailed a nic se nepovažuje za bezpečné.
Kdy se zamkne
- Automaticky při prvním uložení vlastníkem webu (uživatel s
ManagePermissions). - Tlačítkem Zamknout nyní v části Zabezpečení, sekci Úložiště konfigurace.
- Ručně příkazem z PowerShellu.
Neoprávněný uživatel (návrhář bez práva měnit oprávnění) zamknout nemůže. Návrhář dostane po uložení do nezamčeného úložiště varování „Úložiště konfigurace není zamčené“ s příkazem pro vlastníka.
Sladění oprávnění při dalším uložení
Když je úložiště už zamčené, vlastník webu při uložení konfigurace oprávnění znovu nenastavuje, pokud se nezměnily jeho vstupy: přihlášený vlastník, skupina návrhářů, čtení pro organizaci a pro hosty a tenant. Uložení je tak rychlé a nespouští desítky REST volání. Otisk těchto vstupů se ukládá do souboru SiteAssets/FormCustomizer/<listId>.perm.json v kořeni úložiště, do kterého smí zapisovat jen vlastník, takže přežije načtení stránky a návrhář ho nemůže podvrhnout. Zapíše se až po čistém sladění, tedy bez chyby a bez varování.
- Při změně kteréhokoli vstupu, chybějícím nebo nečitelném otisku se oprávnění sladí jako dříve.
- Změna oprávnění provedená ručně mimo formulář se při uložení neopraví. Vynutíte ji tlačítkem Zamknout nyní, které oprávnění vždy sladí.
- Selže-li sladění po zápisu konfigurace (například omezení požadavků 429), konfigurace zůstane uložená a zobrazí se jen varování „Úložiště konfigurace není zcela zamčené“ s příkazem pro opravu. Otisk se nezapíše, takže další uložení sladění zopakuje.
Potvrzení při prvním zamčení
Pokud konfigurační soubor vznikl před zámkem (nebo se importuje ze starého umístění), mohl ho do té doby změnit kdokoli. Builder proto před zapečetěním ukáže dialog Zamknout a uložit tuto konfiguraci? s bezpečnostním souhrnem:
- zdroj: soubor před zamčením (kdy byl uložen a kdo ho naposledy změnil), nebo starší konfigurace z property bagu,
- počet a názvy skriptů (
onFormLoad,onBeforeSave, funkce), - tlačítka s akcemi,
- počet pravidel,
- role oprávněných editorů a skupina návrhářů.
Teprve po Potvrdit, zamknout a uložit se úložiště zapečetí. Při „Zamknout nyní“ nad existujícím souborem se nabízí Zamknout a zapečetit stávající soubor. Nedůvěřujete-li obsahu, zrušte dialog a formulář uložte z návrháře: soubor se přepíše vaším konceptem. Při prvním zamčení se navíc smaže historie z doby před zámkem a záloha se nahradí zapečetěným souborem.
Skupina návrhářů
Chcete-li konfiguraci svěřit i lidem, kteří nejsou vlastníky webu, nastavte roli group a název SharePoint skupiny (allowedEditorGroup).
- Každý seznam má vlastní podsložku
SiteAssets/FormCustomizer/<listId>. Podsložka dostane unikátní oprávnění: kopie z kořene plus Contribute pro skupinu návrhářů. Skupina tak smí zapisovat jen konfiguraci tohoto seznamu, ne ostatních. - Oprávnění aplikuje až uložení vlastníkem webu. Změní-li skupinu návrhář, dostane upozornění, že se oprávnění nezměnilo, a vlastník ji musí uložit znovu.
- Nemá-li seznam skupinu návrhářů, podsložka dědí z kořene (případná dřívější vlastní oprávnění se zruší).
- Návrhář nemůže založit složku seznamu v kořeni: pokud ještě neexistuje, hlásí „Složka konfigurace tohoto seznamu ještě neexistuje. Vlastník webu musí formulář nejdřív uložit.“
Odmítnuté skupiny
Uložení se odmítne a oprávnění se nezmění, pokud je skupina návrhářů:
- přidružená skupina Členové nebo Návštěvníci webu (dala by zápis všem členům),
- skupina, jejímž členem je Everyone nebo Everyone except external users (dala by zápis všem).
Skupina, která na webu neexistuje, se uloží s varováním „skupina návrhářů … na webu neexistuje“: nemá zápis. Zkontrolujte přesný název.
Licenční soubor
Soubor license.txt leží přímo v kořenové složce FormCustomizer, takže po zamčení dědí její oprávnění: zapsat ho smí jen vlastník webu, členové a návrháři dostanou 403 a dialog licence jim to vysvětlí. Čtení zůstává všem (licence se čte i neoprávněným uživatelem). Je-li úložiště nezamčené, může soubor přepsat každý s právem zápisu do Site Assets, ale klíč je podepsaný, takže vlastní platný klíč nelze podvrhnout. Viz Licence.
Ruční zamčení a oprava v PowerShellu
Návrhář nabízí příkaz v části Zabezpečení, sekci Úložiště konfigurace, a zobrazí ho i varování po uložení (notLocked, lockFailed, rollbackFailed). Příkaz je určený pro PnP.PowerShell a vlastníka webu. Podsložku seznamu doplní, pokud je zvolena skupina návrhářů. V ukázce jsou zástupné hodnoty, skutečný příkaz si zkopírujte z návrháře (obsahuje URL webu, <listId> a název skupiny).
Connect-PnPOnline -Url "https://<tenant>.sharepoint.com/sites/<site>" -Interactive
$web = Get-PnPWeb -Includes AssociatedOwnerGroup,CurrentUser,RoleDefinitions
$ctx = Get-PnPContext
$role = { param($t) $web.RoleDefinitions | Where-Object { $_.RoleTypeKind -eq $t } | Select-Object -First 1 }
$full = & $role "Administrator"; $read = & $role "Reader"; $contrib = & $role "Contributor"
function Grant($item, $principal, $def) {
$b = New-Object Microsoft.SharePoint.Client.RoleDefinitionBindingCollection($ctx); $b.Add($def)
$null = $item.RoleAssignments.Add($principal, $b)
}
# 1) kořen FormCustomizer: rozpojit dědičnost S kopií (čtenáři nepřijdou o přístup)
$root = (Get-PnPFolder -Url "/sites/<site>/SiteAssets/FormCustomizer" -Includes ListItemAllFields).ListItemAllFields
$root.BreakRoleInheritance($true, $true); Invoke-PnPQuery
# 2) vlastníci a spouštějící uživatel = Full Control
Grant $root $web.AssociatedOwnerGroup $full; Grant $root $web.CurrentUser $full; Invoke-PnPQuery
# 3) ostatním ponechat jen Read a Limited Access
$null = Get-PnPProperty -ClientObject $root -Property RoleAssignments
foreach ($ra in @($root.RoleAssignments)) {
$null = Get-PnPProperty -ClientObject $ra -Property Member, RoleDefinitionBindings
if ($ra.Member.Id -eq $web.AssociatedOwnerGroup.Id -or $ra.Member.Id -eq $web.CurrentUser.Id) { continue }
$keep = @($ra.RoleDefinitionBindings | Where-Object { $_.RoleTypeKind -in 'Reader','Guest' })
if ($keep.Count -ne @($ra.RoleDefinitionBindings).Count) {
$ra.RoleDefinitionBindings.RemoveAll(); $ra.RoleDefinitionBindings.Add($read)
foreach ($k in $keep) { if ($k.RoleTypeKind -eq 'Guest') { $ra.RoleDefinitionBindings.Add($k) } }
$ra.Update()
}
}
Invoke-PnPQuery
# 4) čtení pro celou organizaci a hosty (vynechte, co nechcete)
$eeeu = "c:0-.f|rolemanager|spo-grid-all-users/$(Get-PnPTenantId)"
foreach ($login in $eeeu, "c:0(.s|true") { Grant $root ($web.EnsureUser($login)) $read }
Invoke-PnPQuery
# 5) jen při skupině návrhářů: podsložka seznamu (kopie z kořene + Contribute)
$sub = (Get-PnPFolder -Url "/sites/<site>/SiteAssets/FormCustomizer/<listId>" -Includes ListItemAllFields).ListItemAllFields
$sub.BreakRoleInheritance($true, $true); Invoke-PnPQuery
Grant $sub $web.SiteGroups.GetByName("Návrháři formulářů") $contrib; Invoke-PnPQuery
Příkaz vytvořený návrhářem nebyl ověřen proti živému tenantu (upozorňuje na to komentář v kódu). Před nasazením ho vyzkoušejte na testovacím webu a zkontrolujte výsledek na stránce oprávnění složky.
Zbytková rizika
- Před prvním zamčením: dokud nikdo z vlastníků formulář neuloží nebo úložiště nezamkne, může konfiguraci změnit kdokoli s právem zápisu do Site Assets. Návrhář vlastníkovi při nezamčeném úložišti ukazuje varování (Úložiště konfigurace není zamčené). Proto existuje potvrzovací dialog při prvním zamčení: prohlédněte si souhrn skriptů.
- Smazání a znovuvytvoření Site Assets: uživatel s oprávněním Správa seznamů může knihovnu Site Assets smazat a vytvořit znovu, a tím odstranit i zámek složky. Takový zásah je auditovaný a obnovitelný z koše. Při dalším uložení se úložiště znovu zamkne.
- Druhá vrstva obrany: vlastní skripty jsou ve výchozím stavu vypnuté (Politika skriptů). I při přepsané konfiguraci tak nelze spustit cizí kód, dokud politika skripty nepovolí. Výrazy jsou bezpečné vždy.
- Správci tenantu a site collection zámkem omezeni nejsou.
Oprávnění koncových uživatelů
Formulář nemá vlastní oprávnění k datům: pracuje s právy přihlášeného uživatele. Uživatel proto potřebuje:
- Nová položka: oprávnění přidávat položky do seznamu. Úprava: oprávnění upravovat položky. Zobrazení: číst položky.
- Přílohy: stejná práva jako k položce (přidání a odebrání příloh vyžaduje úpravu položky).
- Lookupy, uživatelé, taxonomie a související seznamy: čtení zdrojového seznamu, termové sady nebo knihovny. Bez něj pole nemá nabídku nebo se nenačte.
- Čtení konfigurace: čtení složky
SiteAssets/FormCustomizer. Po zamčení ho mají členové skupin webu a ti, komu je zapnuto čtení pro organizaci nebo hosty.
Pole, jejichž načtení selže (např. kvůli oprávnění nebo chybě v dávce dotazů), jsou ve formuláři jen ke čtení a při uložení se nezapisují. Viz Nenačtená pole. Režim zobrazení (DisplayForm) nikdy nehlásí neuložené změny.
Uživatelé mimo skupiny webu
Uživatel, který nemá čtení složky konfigurace (např. přístup jen přes sdílení položky, host s vypnutým čtením pro hosty), konfiguraci přečíst nemůže. Formulář pro něj běží s výchozím rozložením vygenerovaným ze sloupců seznamu, bez vašich záložek, pravidel a tlačítek. Správci webu se v takovém případě zobrazí upozornění na nepřečtenou konfiguraci, běžný uživatel dostane hlášku „Formulář se nepodařilo načíst v plném rozsahu. Kontaktujte vlastníka webu.“ Řešením je ponechat zapnuté čtení pro organizaci (a hosty, pokud je potřebujete), nebo uživatele přidat do skupiny webu.
Pokud na formulářích spoléháte na pravidla pro skrytí citlivých polí nebo blokaci uložení, zajistěte, aby ji všichni uživatelé přečetli. Pravidla nejsou bezpečnostní mechanismus: skutečnou ochranu dat poskytují jen oprávnění seznamu a sloupců v SharePointu.
NoScript weby
Na webech s DenyAddAndCustomizePages (NoScript, výchozí u moderních webů) nelze zapisovat do property bagu webu, ani to nemají vlastníci. Produkt proto property bag webu nezapisuje: konfigurace i licence se ukládají jako soubory v Site Assets. Starý klíč v property bagu se ještě čte. Nepotřebujete oprávnění AddAndCustomizePages.