Skip to main content

LgAuthorizeView & LgCascadingPolicies

Two components govern authorizations in the UI:

  • LgAuthorizeView conditions the display (PolicyVisible) and editing (PolicyEdit) of its content based on policies, and propagates these policies cascading to child Lagoon components;
  • LgCascadingPolicies declares policies always validated in its subtree, avoiding re-evaluation of rights component by component.

Policies themselves are declared on the server side — see Roles and policies.

<LgAuthorizeView PolicyVisible="@Policies.IsAdmin">
...
</LgAuthorizeView>
  • Namespace: Lagoon.UI.Components
  • Inherits from: ComponentBase (both)
  • Interfaces: ILgComponentPolicies (LgAuthorizeView); IComponentContextProvider (LgCascadingPolicies)
  • NuGet package: Lagoon.UI

Usage​

Hide an area based on a policy​

The content of LgAuthorizeView is only rendered if the user satisfies PolicyVisible. NotAuthorized provides fallback content and Authorizing provides content while rights are being evaluated asynchronously.

AdminSectionPage.razor
<LgAuthorizeView PolicyVisible="@Policies.IsAdmin">
<ChildContent>
<LgTitle Text="#Administration" TitleLevel="TitleLevel.Level2" />
<LgButton Text="#PurgeData" OnClick="PurgeAsync" />
</ChildContent>
<NotAuthorized>
<LgBigMessage Title="#AccessDenied" />
</NotAuthorized>
</LgAuthorizeView>
AdminSectionPage.razor.cs
public partial class AdminSectionPage : LgPage
{
// Action reserved for administrators: the entire area is hidden without the policy.
private async Task PurgeAsync(ActionEventArgs args)
{
await Task.Delay(100, args.CancellationToken);
ShowSuccess("#DataPurged");
}
}

Authorized is equivalent to ChildContent (with authentication state in context) — do not define both, an exception would be raised.

Make an area read-only​

PolicyEdit leaves the content visible but makes it non-editable if the policy is not satisfied: child Lagoon fields (consuming the cascading parameter ParentAuthorizeView) switch to read-only.

OrderFormPage.razor
<LgAuthorizeView PolicyEdit="@Policies.CanEditOrders">
<LgTextBox Label="#Reference" @bind-Value="_model.Reference" />
<LgDateBox Label="#OrderDate" @bind-Value="_model.OrderDate" />
</LgAuthorizeView>
OrderFormPage.razor.cs
public partial class OrderFormPage : LgPage
{
private readonly OrderVm _model = new();

private sealed class OrderVm
{
public string Reference { get; set; }
public DateTime? OrderDate { get; set; }
}
}

Child Lagoon components also expose PolicyVisible / PolicyEdit individually (e.g., LgButton): LgAuthorizeView serves to factorize the rule across an entire area.

Render container​

By default, authorized content is rendered without a wrapper element, unless CssClass is defined. ShowDiv forces (or prevents) encapsulation in a <div>.

DashboardPage.razor
<LgAuthorizeView PolicyVisible="@Policies.SeeStatistics" CssClass="dashboard-stats">
...
</LgAuthorizeView>

Propagate validated policies with LgCascadingPolicies​

LgCascadingPolicies marks policies as already validated for its entire subtree: child components that require one of these policies (via PolicyVisible / PolicyEdit) consider them satisfied without re-evaluation. This is useful when a screen has already verified the right upstream, or for repeated renders (grid rows, lists).

ProjectPage.razor
<LgCascadingPolicies ValidatedPolicies="@_validatedPolicies">
@foreach (TaskVm task in _tasks)
{
<LgButton Text="@task.Name" PolicyEdit="@Policies.CanEditTasks" />
}
</LgCascadingPolicies>
ProjectPage.razor.cs
public partial class ProjectPage : LgPage
{
// Policies already verified on screen entry: avoids re-evaluation per button.
private string _validatedPolicies = Policies.CanEditTasks;

private readonly List<TaskVm> _tasks = new();

private sealed class TaskVm
{
public string Name { get; set; }
}
}

The AuthorizeAsync(policyName) method (via @ref) verifies a policy in the component's context.

Properties​

All [Parameter] properties of both components.

LgAuthorizeView​

NameTypeDefaultDeclared inDescription
AuthorizedRenderFragment<AuthenticationState>nullLgAuthorizeViewContent displayed if the user is authorized. Incompatible with ChildContent.
AuthorizingRenderFragmentnullLgAuthorizeViewContent displayed while rights are being evaluated asynchronously.
ChildContentRenderFragmentnullLgAuthorizeViewContent displayed if the user is authorized.
CssClassstringnullLgAuthorizeViewCSS classes for the wrapper <div> (its presence enables encapsulation).
NotAuthorizedRenderFragment<AuthenticationState>nullLgAuthorizeViewContent displayed if the user is not authorized.
PolicyEditstringnullLgAuthorizeViewPolicy required to edit the content; otherwise child components switch to read-only.
PolicyVisiblestringnullLgAuthorizeViewPolicy required to display the content.
ShowDivbool?nullLgAuthorizeViewForces (true) or prevents (false) encapsulation in a <div>. If null, a <div> is only rendered if CssClass is defined.

LgCascadingPolicies​

NameTypeDefaultDeclared inDescription
ChildContentRenderFragmentnullLgCascadingPoliciesContent of the subtree benefiting from validated policies.
ValidatedPoliciesstringnullLgCascadingPoliciesPolicies considered as always validated in the subtree.

Methods & events​

MemberSignatureDescription
LgCascadingPolicies.AuthorizeAsyncTask<bool> AuthorizeAsync(string policyName)Verifies whether the user satisfies the policy in the component's context.

Best practices / accessibility​

  • Declare policy names in a shared client/server class (Policies.XXX) rather than as literal strings.
  • Client-side hiding is a UI convenience, not protection: controllers must carry their own [Authorize] attributes — see Roles and policies.
  • Use LgCascadingPolicies for areas with repeated rendering: each avoided policy evaluation is one fewer round-trip to the authorization context.
  • LgButton — PolicyVisible / PolicyEdit at the component level.
  • LgEditForm — form whose fields inherit cascading policies.