Overview
Authentication & Authorizations
This section covers the login flow and the main authorization levels: access UI, metadata (table/column/menu), and route-guard on the Angular host side.
1) Login
Reference screen:
manual__auth_login__01.png: login screen (username/password + auth actions).
Captcha (enablement):
- Captcha is enabled when both keys are populated:
captcha_public_keycaptcha_private_key- The pre-login configuration is exposed by
GET /api/Meta/AuthConfig(captchaEnabled,captchaSiteKey).
Registration (enablement):
- Registration is exposed in the UI when
registrationEnabled = trueinAuthConfig. - In the backend,
registrationEnableddepends onemail-sender-address-registrationbeing populated. - At login, the
Registerlink appears; the register form includes username, email, password, and (if active) captcha.
Password recovery:
- At login, the
Forgot password?link is available. - The reset request uses
MetaService.requestPasswordResetand sends an email with a link containing atoken. - Minimum keys to configure for the email flow:
email-hostemail-portemail-sslemail-useremail-pwdemail-sender-address-registrationsite-url(base URL used to build the reset link).
Recommended AppSettings (extract):
{
"AppSettings": {
"captcha_public_key": "your-public-key",
"captcha_private_key": "your-private-key",
"email-sender-address-registration": "no-reply@your-domain.tld",
"email-host": "smtp.your-domain.tld",
"email-port": "587",1bis) Admin flag model (server + client)
The framework uses three flags with increasing granularity, evaluated from most restrictive to most permissive:
| Flag | DB source | Scope | Used in |
|---|---|---|---|
isSuperAdmin | ruoli.superadmin (bit) | Maximum privilege: may modify project metadata | Server gate on every metadata mutation (RawHelpers.checkAdmin) + client UI gate (UserInfoService.isUserAdmin / isCurrentUserAdmin) |
isRoleAdmin | ruoli.admin (bit) | Nominal "Administrator" role (e.g. seed id_ruolo=2) | Per-route fallback grant only (does not bypass checkAdmin) |
isAdmin (legacy) | utenti.isAdmin (bit) | Historical per-user flag | Per-route fallback grant only (does not bypass checkAdmin) |
The two applicative semantics:
- "Metadata mutation" gate (scaffolding, board content save, edit column/table metadata, etc.):
- server: RawHelpers.checkAdmin(uid) in Helpers.cs — throws AuthenticationException("Need administrative rights!") if !user.isSuperAdmin.
- client: UI hides/disables actions read via UserInfoService.isUserAdmin(userLike) which returns userLike.isSuperAdmin.
- About ~40 endpoints are affected (see MetaService.cs, metaModelRaw.cs, scaffolding.asmx.cs, _Metadati_methods_xml.cs).
- Per-route fallback grant (when a table has
md_grant_by_default = falseand no explicit user/role/azienda grant exists):
- server: applyTableRestrictions in _Metadati_Tabelle.cs — grants view/edit/insert/delete if user.hasAdminGrant, where:
hasAdminGrant = isSuperAdmin OR isRoleAdmin OR isAdmin - The cascade is permissive for backward compatibility: a superadmin always passes, but a role with admin=1 or a user with legacy utenti.isAdmin=1 also stays authorized.
The k-user payload (cookie / sessionStorage) after login carries both flags:
{
"user_id": 100274,
"user_name": "admin",
"role": "Admin",
"role_id": 1,
"isAdmin": true,
"isSuperAdmin": true,Operational notes:
- The legacy
utenti.isAdminflag is still populated on theusermodel but should no longer drive new authorization decisions: preferisSuperAdmin(gate) orhasAdminGrant(permissive fallback). - On the Angular host, the
roleRouteCanMatchGuarduses therolelabel (string"Admin"/"Amministratore"/ etc.) to match againstFRAMEWORK_ROUTE_ROLE_RULES. It is an applicative routing decision, independent of the DB flags.
2) Authorization Metadata: Tables, Columns, Menu
Screens taken from existing metadata documentation:
metadata-integration__metadata-editor-auth-table__desktop.png: table authorizations.metadata-integration__metadata-editor-auth-table-edit-popup__desktop.png: table authorization edit popup.metadata-integration__metadata-editor-auth-column__desktop.png: column authorizations.metadata-integration__metadata-editor-auth-column-edit-popup__desktop.png: column authorization edit popup.metadata-integration__metadata-menu-management__desktop.png: metadata menu management.metadata-integration__metadata-menu-management-edit-popup__desktop.png: menu item edit popup.
Metadata involved:
_Metadati_Utenti_Autorizzazioni_Tabelle: view/edit/insert/delete permissions at the route/table level._Metadati_Utenti_Autorizzazioni_Colonne: field-level permissions (e.g., editability/required per role or user)._metadati__menu: menu item visibility/navigation in combination with route permissions.
3) Route-Guard Usage (Host Project)
Objective: block reserved routes based on user roles and redirect to /unauthorized.
Host files to modify (WuicTest example):
C:\src\Wuic\WuicTest\wwwroot\src\app\routing\route-role-map.tsC:\src\Wuic\WuicTest\wwwroot\src\app\routing\role-route.guard.tsC:\src\Wuic\WuicTest\wwwroot\src\app\wuic-bridges\routes.tsC:\src\Wuic\WuicTest\wwwroot\src\app\app.routes.tsC:\src\Wuic\WuicTest\wwwroot\src\app\component\unauthorized\unauthorized.component.ts
Example 1: role/route rules map
export const FRAMEWORK_ROUTE_ROLE_RULES: RouteRoleRule[] = [
{ key: 'designer', routePattern: 'designer', roles: ['admin'] },
{ key: 'workflow-designer', routePattern: 'workflow-designer', roles: ['admin'] },
{ key: 'dashboard', routePattern: ':route/dashboard', roles: ['admin'] },
{ key: 'report-designer', routePattern: ':route/report-designer', roles: ['admin'] }
];Example 2: attaching guards to routes
{
path: ':route/dashboard',
loadComponent: () => import('wuic-framework-lib-src/component/designer/designer.route.component').then((m) => m.DesignerRouteComponent),
canMatch: [menuRouteAccessCanMatchGuard, roleRouteCanMatchGuard],
canActivate: [menuRouteAccessCanActivateGuard, roleRouteCanActivateGuard],
data: { breadcrumbs: 'dashboard', roleRuleKey: 'dashboard' }
}Example 3: redirect to unauthorized page
return router.createUrlTree(['/unauthorized'], {
queryParams: { from: attemptedPath || '/' }
});Operational notes:
roleRuleKeyinroute.datais preferable when the route contains dynamic parameters.- As a fallback, the guard can use
route.pathfor direct match. - The
unauthorizedpage must be registered in the host routes and show the requested route (queryParam from).
Screenshot
