Manzke.Mongo.RBAC
0.1.6
dotnet add package Manzke.Mongo.RBAC --version 0.1.6
NuGet\Install-Package Manzke.Mongo.RBAC -Version 0.1.6
<PackageReference Include="Manzke.Mongo.RBAC" Version="0.1.6" />
<PackageVersion Include="Manzke.Mongo.RBAC" Version="0.1.6" />
<PackageReference Include="Manzke.Mongo.RBAC" />
paket add Manzke.Mongo.RBAC --version 0.1.6
#r "nuget: Manzke.Mongo.RBAC, 0.1.6"
#:package Manzke.Mongo.RBAC@0.1.6
#addin nuget:?package=Manzke.Mongo.RBAC&version=0.1.6
#tool nuget:?package=Manzke.Mongo.RBAC&version=0.1.6
Manzke.Mongo.RBAC
Biblioteca C# que implementa o RBAC nativo do MongoDB para aplicações .NET (em especial Blazor Server). Ao ser compilada, gera um pacote NuGet.
Com ela você obtém:
- Injeção dinâmica de
IMongoClientpor sessão de usuário (clientes segregados: Porteiro/Singleton vs. User Client/Scoped); - Connection string dinâmica baseada nas credenciais do usuário logado (sem armazenar senhas);
- Criação e gestão de usuários e roles do MongoDB via
db.runCommand(createUser,createRole,updateRole,dropUser,dropRole,grantPrivilegesToRole, etc.); - Roles granulares por collection (ex.: ler a collection
pedidose ler/gravar a collectionlogs); - Usuário administrador protegido contra edição/exclusão;
- Tratamento de erros de autorização (
MongoCommandExceptioncomCodeName == "Unauthorized").
Instalação
dotnet add package Manzke.Mongo.RBAC
Pré-requisitos
O usuário administrador precisa existir no MongoDB antes de usar a biblioteca — ele não é
criado automaticamente. Crie-o manualmente (uma única vez) com o mongosh, no banco de autenticação
(database_name):
use database_name
db.createUser({
user: "administrador",
pwd: "1234", // Altere para uma senha segura
roles: [
{ role: "userAdmin", db: "database_name" },
{ role: "readWrite", db: "database_name" },
{ role: "dbAdmin", db: "database_name" }
]
})
O nome do usuário deve corresponder ao AdminUsername configurado (padrão: administrador).
As roles userAdmin (criar/editar usuários e roles), dbAdmin e readWrite dão ao administrador
as permissões para gerenciar usuários, roles e privilégios.
O usuário técnico Porteiro (referenciado por
PorteiroConnectionString) também precisa existir no MongoDB. Veja a criação da role e do usuário "Porteiro" emdocs/RBAC.md.
Configuração
Adicione a seção MongoRbac no appsettings.json:
{
"MongoRbac": {
"DatabaseName": "database_name",
"ConnectionStringTemplate": "mongodb://{0}:{1}@localhost:27017/database_name?authSource=database_name",
"PorteiroConnectionString": "mongodb://porteiro:SenhaTecnicaSegura@localhost:27017/database_name?authSource=database_name",
"GuestConnectionString": "mongodb://localhost:27017/database_name",
"AdminUsername": "administrador"
}
}
| Propriedade | Descrição |
|---|---|
DatabaseName |
Banco da aplicação (onde usuários e roles são criados). |
ConnectionStringTemplate |
Template usado para montar a connection string do usuário logado. Os placeholders {0} (username) e {1} (password) são obrigatórios. |
PorteiroConnectionString |
Connection string completa do usuário técnico "Porteiro" (valida login e lê metadados). |
GuestConnectionString |
(Opcional) Connection string de um cliente "Guest" com permissão zero, usada antes do login. |
AdminUsername |
Nome do usuário administrador protegido (padrão: administrador). |
Configuração via variáveis de ambiente
Todas as propriedades da seção MongoRbac também podem ser definidas por variáveis de ambiente,
que têm precedência sobre o appsettings.json. O separador de seção é __ (dois underlines):
| appsettings.json | Variável de ambiente |
|---|---|
MongoRbac:DatabaseName |
MongoRbac__DatabaseName |
MongoRbac:ConnectionStringTemplate |
MongoRbac__ConnectionStringTemplate |
MongoRbac:PorteiroConnectionString |
MongoRbac__PorteiroConnectionString |
MongoRbac:GuestConnectionString |
MongoRbac__GuestConnectionString |
MongoRbac:AdminUsername |
MongoRbac__AdminUsername |
$env:MongoRbac__DatabaseName = "database_name"
$env:MongoRbac__ConnectionStringTemplate = "mongodb://{0}:{1}@localhost:27017/database_name?authSource=database_name"
$env:MongoRbac__PorteiroConnectionString = "mongodb://porteiro:Senha@localhost:27017/database_name?authSource=database_name"
$env:MongoRbac__AdminUsername = "administrador"
- Os placeholders
{0}e{1}doConnectionStringTemplatedevem permanecer literais (sem escape).- Em
docker-compose/.env, coloque a connection string entre aspas para o shell não interpretar caracteres como?,&,@e:.
Registro no Program.cs
using Manzke.Mongo.RBAC;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddServerSideBlazor();
// Registra os serviços do RBAC
builder.Services.AddMongoRbac();
var app = builder.Build();
// ...
Fluxo de login (Blazor Server)
No componente de login, valide as credenciais com o Porteiro e, em seguida, estabeleça o cliente da sessão:
@page "/login"
@inject IPorteiroService Porteiro
@inject IMongoClientProvider MongoProvider
@inject NavigationManager Nav
<EditForm Model="model" OnValidSubmit="OnLoginSubmit">
<InputText @bind-Value="model.Username" />
<InputText Type="InputType.Password" @bind-Value="model.Password" />
<button type="submit">Entrar</button>
</EditForm>
@code {
private readonly LoginModel model = new();
private async Task OnLoginSubmit()
{
// 1. Valida as credenciais sem criar sessão permanente
var valido = await Porteiro.ValidateCredentialsAsync(model.Username, model.Password);
if (!valido)
{
// exibir erro de login
return;
}
// 2. Cria o cliente do usuário para esta sessão (Scoped)
await MongoProvider.SetUserClientAsync(model.Username, model.Password);
Nav.NavigateTo("/home");
}
private sealed class LoginModel
{
public string Username { get; set; } = string.Empty;
public string Password { get; set; } = string.Empty;
}
}
A senha é mantida apenas em memória durante a sessão (nunca persistida).
Uso nas páginas
Injete IMongoClientProvider e use o cliente da sessão para as operações do dia a dia:
@page "/pedidos"
@inject IMongoClientProvider MongoProvider
<button @onclick="CarregarPedidos">Carregar pedidos</button>
@code {
private async Task CarregarPedidos()
{
var client = await MongoProvider.GetClientAsync();
var database = client.GetDatabase("database_name");
var pedidos = await database.GetCollection<BsonDocument>("pedidos")
.Find(new BsonDocument())
.ToListAsync();
// ...
}
}
Tratamento de erro de autorização
Se o usuário tentar acessar um dado que a role dele não permite, o driver lança MongoCommandException com CodeName == "Unauthorized":
try
{
var client = await MongoProvider.GetClientAsync();
var database = client.GetDatabase("database_name");
await database.GetCollection<BsonDocument>("config").Find(new BsonDocument()).ToListAsync();
}
catch (MongoCommandException ex) when (ex.IsUnauthorized())
{
// Feedback: "Você não tem permissão para visualizar estas configurações."
}
Criação de usuários e roles granulares (Administrador)
Injete IMongoUserManager e IMongoRoleManager para administrar usuários e privilégios.
O administrador também faz login normalmente (usando SetUserClientAsync), e a connection
string dele é gerada dinamicamente a partir do ConnectionStringTemplate — não há connection
string de admin estática. Os gerenciadores usam o cliente da sessão atual, então, enquanto o
administrador estiver logado, ele terá permissões totais para gerenciar usuários e roles.
Role granular: ler pedidos e ler/gravar logs
using Manzke.Mongo.RBAC.Models;
await RoleManager.CreateRoleAsync(
"RoleOperacional",
privileges: new[]
{
new MongoPrivilege
{
Resource = new MongoResource { Database = "database_name", Collection = "pedidos" },
Actions = RbacActions.Read
},
new MongoPrivilege
{
Resource = new MongoResource { Database = "database_name", Collection = "logs" },
Actions = RbacActions.ReadWrite
}
});
Criando um usuário e atribuindo a role
await UserManager.CreateUserAsync(
"operador",
"SenhaSegura",
roles: new[] { new MongoRoleRef("RoleOperacional", "database_name") });
Outras operações comuns
// Usuários
await UserManager.DropUserAsync("operador");
await UserManager.GrantRolesToUserAsync("operador", new[] { new MongoRoleRef("read", "database_name") });
await UserManager.RevokeRolesFromUserAsync("operador", new[] { new MongoRoleRef("read", "database_name") });
// Roles
await RoleManager.GrantPrivilegesToRoleAsync("RoleOperacional", privileges);
await RoleManager.RevokePrivilegesFromRoleAsync("RoleOperacional", privileges);
await RoleManager.DropRoleAsync("RoleOperacional");
Usuário administrador protegido
Tentativas de editar ou excluir o usuário AdminUsername lançam RbacAdminUserProtectedException:
try
{
await UserManager.DropUserAsync("administrador");
}
catch (RbacAdminUserProtectedException ex)
{
// "O usuário administrador 'administrador' não pode ser alterado nem excluído."
}
Logout
No logout, invalide o cliente da sessão:
MongoProvider.Reset();
Documentação
A especificação funcional completa (conceito de segurança, arquitetura de clientes segregados e criação de usuários/roles) está em docs/RBAC.md.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 8.0.0)
- Microsoft.Extensions.Options (>= 8.0.0)
- Microsoft.Extensions.Options.ConfigurationExtensions (>= 8.0.0)
- Microsoft.Extensions.Options.DataAnnotations (>= 8.0.0)
- MongoDB.Driver (>= 3.11.1)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.