Nuuvify.CommonPack.Security.Abstraction 2.1.0

dotnet add package Nuuvify.CommonPack.Security.Abstraction --version 2.1.0
                    
NuGet\Install-Package Nuuvify.CommonPack.Security.Abstraction -Version 2.1.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Nuuvify.CommonPack.Security.Abstraction" Version="2.1.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Nuuvify.CommonPack.Security.Abstraction" Version="2.1.0" />
                    
Directory.Packages.props
<PackageReference Include="Nuuvify.CommonPack.Security.Abstraction" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Nuuvify.CommonPack.Security.Abstraction --version 2.1.0
                    
#r "nuget: Nuuvify.CommonPack.Security.Abstraction, 2.1.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Nuuvify.CommonPack.Security.Abstraction@2.1.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Nuuvify.CommonPack.Security.Abstraction&version=2.1.0
                    
Install as a Cake Addin
#tool nuget:?package=Nuuvify.CommonPack.Security.Abstraction&version=2.1.0
                    
Install as a Cake Tool

Nuuvify.CommonPack.Security.Abstraction

Quality Gate Status Build Status - Main Build Status - QAS

Biblioteca de abstrações para segurança e autenticação JWT. Esta biblioteca contém interfaces, extensões e classes auxiliares que definem os contratos para implementações de segurança em aplicações .NET.

📋 Índice

Funcionalidades

  • Abstrações para autenticação JWT com interfaces bem definidas
  • Gerenciamento de usuários autenticados com verificação de roles e claims
  • Construção de tokens JWT com builder pattern flexível
  • Extensões para ClaimsPrincipal com métodos utilitários
  • Modelos de dados padronizados para usuários e roles
  • Validação de tokens com verificação de expiração
  • Suporte a refresh tokens para renovação automática
  • Repository pattern para gerenciamento de contas de usuário
  • Compatibilidade com .NET Standard 2.1 para máxima portabilidade

Instalação

Via Package Manager Console

Install-Package Nuuvify.CommonPack.Security.Abstraction

Via .NET CLI

dotnet add package Nuuvify.CommonPack.Security.Abstraction

Via PackageReference

<PackageReference Include="Nuuvify.CommonPack.Security.Abstraction" Version="X.X.X" />

Dependências

NuGet Packages

Package Version Descrição
System.ComponentModel.Annotations 5.0.0 Fornece atributos de validação e anotações para models

Project References

Project Descrição
Nuuvify.CommonPack.Extensions Biblioteca com padrão de notificação, extensões para collections, strings e outros utilitários essenciais

Framework

  • .NET Standard 2.1: Garante compatibilidade com .NET Core 3.0+, .NET 5+, .NET 6+, .NET 8+ e .NET Framework 4.7.2+

Configuração

Esta biblioteca contém apenas abstrações, portanto não requer configuração específica. As implementações concretas devem ser registradas via Dependency Injection:

// Program.cs ou Startup.cs
builder.Services.AddScoped<IUserAuthenticated, UserAuthenticated>();
builder.Services.AddScoped<IJwtBuilder, JwtBuilder>();
builder.Services.AddScoped<IUserAccountRepository, UserAccountRepository>();

Uso

IUserAuthenticated

Interface para gerenciamento de usuários autenticados com verificação de autenticação, autorização e acesso a claims:

public class MyController : ControllerBase
{
    private readonly IUserAuthenticated _userAuth;

    public MyController(IUserAuthenticated userAuth)
    {
        _userAuth = userAuth;
    }

    [HttpGet("profile")]
    public IActionResult GetProfile()
    {
        if (!_userAuth.IsAuthenticated())
        {
            return Unauthorized();
        }

        var username = _userAuth.Username();
        var email = _userAuth.GetClaimValue(ClaimTypes.Email);

        return Ok(new { username, email });
    }

    [HttpGet("admin")]
    public IActionResult AdminOnly()
    {
        if (!_userAuth.IsAuthorized("Admin", "SuperUser"))
        {
            return Forbid();
        }

        return Ok("Admin content");
    }
}

IJwtBuilder

Interface para construção de tokens JWT com padrão builder fluente:

public class TokenService
{
    private readonly IJwtBuilder _jwtBuilder;

    public TokenService(IJwtBuilder jwtBuilder)
    {
        _jwtBuilder = jwtBuilder;
    }

    public async Task<CredentialToken> GenerateTokenAsync(PersonWithRolesQueryResult user)
    {
        var token = _jwtBuilder
            .WithJwtClaims()
            .WithJwtUserClaims(user)
            .GetUserToken();

        return token;
    }

    public bool ValidateToken(string token)
    {
        return _jwtBuilder.CheckTokenIsValid(token);
    }
}

IUserAccountRepository

Interface para acesso a dados de contas de usuário com operações assíncronas:

public class UserService
{
    private readonly IUserAccountRepository _userRepo;

    public UserService(IUserAccountRepository userRepo)
    {
        _userRepo = userRepo;
    }

    public async Task<bool> HasPermissionAsync(string login, string permission)
    {
        return await _userRepo.PersonIsMemberOf(login, permission);
    }

    public async Task<IEnumerable<PersonRoleQueryResult>> GetUserRolesAsync(string login)
    {
        return await _userRepo.GetUserRoles(login);
    }
}

ClaimsPrincipalExtensions

Métodos de extensão para facilitar extração de informações do ClaimsPrincipal:

public class ProfileService
{
    public UserProfileDto GetCurrentUserProfile(ClaimsPrincipal principal)
    {
        if (principal == null)
            throw new ArgumentNullException(nameof(principal));

        return new UserProfileDto
        {
            Login = principal.GetLogin(),
            Name = principal.GetName(),
            Email = principal.GetEmail()
        };
    }
}

// Uso em Controllers
[HttpGet("me")]
public IActionResult GetCurrentUser()
{
    var profile = new UserProfileDto
    {
        Login = User.GetLogin(),
        Name = User.GetName(),
        Email = User.GetEmail()
    };

    return Ok(profile);
}

CredentialToken

Classe para gerenciamento de tokens com validação automática de expiração:

public class AuthService
{
    public CredentialToken CreateToken(string loginId, string password)
    {
        var credential = new CredentialToken
        {
            LoginId = loginId,
            Password = password,
            ExpiresIn = 3600 // 1 hora em segundos
        };

        // Token e Expires são calculados automaticamente
        return credential;
    }

    public bool IsTokenValid(CredentialToken credential)
    {
        // Verifica se expira em 5 minutos (padrão)
        return credential.IsValidToken();

        // Ou verifica com margem customizada
        return credential.IsValidToken(-10); // Expira em 10 minutos
    }
}

Exemplos Práticos

Exemplo 1: Middleware de Autenticação

public class AuthenticationMiddleware
{
    private readonly RequestDelegate _next;
    private readonly IUserAuthenticated _userAuth;

    public AuthenticationMiddleware(RequestDelegate next, IUserAuthenticated userAuth)
    {
        _next = next;
        _userAuth = userAuth;
    }

    public async Task InvokeAsync(HttpContext context)
    {
        if (context.Request.Path.StartsWithSegments("/api/secure"))
        {
            if (!_userAuth.IsAuthenticated(out string token))
            {
                context.Response.StatusCode = 401;
                await context.Response.WriteAsync("Token required");
                return;
            }

            // Token disponível para uso posterior
            context.Items["AuthToken"] = token;
        }

        await _next(context);
    }
}

Exemplo 2: Autorização Baseada em Roles

[ApiController]
[Route("api/[controller]")]
public class AdminController : ControllerBase
{
    private readonly IUserAuthenticated _userAuth;

    public AdminController(IUserAuthenticated userAuth)
    {
        _userAuth = userAuth;
    }

    [HttpGet("users")]
    public IActionResult GetUsers()
    {
        if (!_userAuth.IsInRole("Admin"))
        {
            return Forbid("Acesso negado. Role 'Admin' necessária.");
        }

        // Lógica para buscar usuários
        return Ok();
    }

    [HttpDelete("users/{id}")]
    public IActionResult DeleteUser(int id)
    {
        if (!_userAuth.IsAuthorized("SuperAdmin", "UserManager"))
        {
            return Forbid("Acesso negado. Permissões insuficientes.");
        }

        // Lógica para deletar usuário
        return NoContent();
    }
}

Exemplo 3: Service para Geração de Tokens

public class TokenGenerationService
{
    private readonly IJwtBuilder _jwtBuilder;
    private readonly IUserAccountRepository _userRepo;

    public TokenGenerationService(IJwtBuilder jwtBuilder, IUserAccountRepository userRepo)
    {
        _jwtBuilder = jwtBuilder;
        _userRepo = userRepo;
    }

    public async Task<CredentialToken> AuthenticateAsync(string login, string password)
    {
        // Validar credenciais (implementação específica)
        if (!await ValidateCredentialsAsync(login, password))
        {
            return null;
        }

        // Obter roles do usuário
        var roles = await _userRepo.GetUserRoles(login);

        var user = new PersonWithRolesQueryResult
        {
            Login = login,
            Email = $"{login}@company.com",
            Name = "User Name",
            Groups = roles
        };

        // Gerar token
        return _jwtBuilder
            .WithJwtClaims()
            .WithJwtUserClaims(user)
            .GetUserToken();
    }

    private async Task<bool> ValidateCredentialsAsync(string login, string password)
    {
        // Implementar validação de credenciais
        await Task.Delay(100); // Simular async operation
        return !string.IsNullOrEmpty(login) && !string.IsNullOrEmpty(password);
    }
}

API Reference

Interfaces

IUserAuthenticated
  • string Username(): Obtém o login do usuário autenticado
  • bool IsAuthenticated(): Verifica se existe um usuário autenticado
  • bool IsAuthenticated(out string token): Verifica autenticação e obtém o token
  • bool IsAuthorized(params string[] groups): Verifica se o usuário pertence aos grupos informados
  • string GetClaimValue(string claimName): Obtém o valor de uma claim específica
  • IEnumerable<Claim> GetClaims(): Retorna todas as claims do usuário
  • bool IsInRole(string role): Verifica se o usuário está no role especificado
IJwtBuilder
  • long ToUnixEpochDate(DateTime dateTime): Converte DateTime para Unix timestamp
  • IJwtBuilder WithJwtClaims(): Adiciona claims padrão do JWT
  • IJwtBuilder WithJwtUserClaims(PersonWithRolesQueryResult personGroups): Adiciona claims específicas do usuário
  • ClaimsIdentity GetClaimsIdentity(): Obtém a identidade com claims configuradas
  • string BuildToken(): Constrói o token JWT como string
  • CredentialToken GetUserToken(): Obtém o token como objeto CredentialToken
  • bool CheckTokenIsValid(string token): Valida se um token é válido
IUserAccountRepository
  • Task<IEnumerable<PersonRoleQueryResult>> GetUserRoles(string login): Obtém roles do usuário
  • Task<bool> PersonIsMemberOf(string login, string claimType): Verifica se usuário pertence a um grupo

Extensions

ClaimsPrincipalExtensions
  • string GetLogin(this ClaimsPrincipal principal): Obtém o login do ClaimsPrincipal
  • string GetName(this ClaimsPrincipal principal): Obtém o nome do ClaimsPrincipal
  • string GetEmail(this ClaimsPrincipal principal): Obtém o email do ClaimsPrincipal

Models

CredentialToken

Propriedades:

  • string LoginId: Login da aplicação ou usuário
  • string Password: Senha do usuário
  • string Token: JWT gerado
  • string RefreshToken: Token para renovação
  • DateTimeOffset Expires: Data de expiração do token
  • DateTimeOffset Created: Data de criação do token
  • long ExpiresIn: Tempo de vida em segundos (calcula Expires automaticamente)
  • IDictionary<string, string> Warnings: Notificações/avisos

Métodos:

  • bool IsValidToken(int minutes = -5): Verifica se o token é válido considerando margem de minutos
PersonQueryResult
  • string Email: Email do usuário
  • string Login: Login do usuário
  • string Name: Nome da pessoa
PersonWithRolesQueryResult : PersonQueryResult
  • IEnumerable<PersonRoleQueryResult> Groups: Grupos/roles do usuário

Troubleshooting

Problemas Comuns

ArgumentNullException em ClaimsPrincipalExtensions

Problema: ArgumentNullException ao usar extensões do ClaimsPrincipal

// ❌ Incorreto
var login = principal.GetLogin(); // principal pode ser null

Solução: Sempre verificar se o principal não é null

// ✅ Correto
if (principal != null)
{
    var login = principal.GetLogin();
}
Token Inválido Mesmo Dentro do Prazo

Problema: IsValidToken() retorna false mesmo com token válido

Causa: Margem de segurança padrão de 5 minutos

Solução: Ajustar a margem de validação

// ✅ Sem margem de segurança
bool isValid = credential.IsValidToken(0);

// ✅ Margem personalizada (10 minutos)
bool isValid = credential.IsValidToken(-10);
Configuração de Dependency Injection

Problema: Interfaces não resolvidas pelo DI container

Solução: Registrar as implementações concretas

// ✅ Registrar implementações
services.AddScoped<IUserAuthenticated, UserAuthenticated>();
services.AddScoped<IJwtBuilder, JwtBuilder>();
services.AddScoped<IUserAccountRepository, UserAccountRepository>();

Logs e Debugging

Para debugging, implemente logging nas implementações concretas:

public class UserAuthenticated : IUserAuthenticated
{
    private readonly ILogger<UserAuthenticated> _logger;

    public UserAuthenticated(ILogger<UserAuthenticated> logger)
    {
        _logger = logger;
    }

    public bool IsAuthenticated()
    {
        _logger.LogDebug("Verificando autenticação do usuário");
        // Implementation...
    }
}

Changelog

Ver arquivo CHANGELOG.md para histórico detalhado de alterações.


📞 Suporte

Para dúvidas, issues ou contribuições:


Nuuvify CommonPack - Construindo soluções robustas para .NET 🚀

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  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. 
.NET Core netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.1 is compatible. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (3)

Showing the top 3 NuGet packages that depend on Nuuvify.CommonPack.Security.Abstraction:

Package Downloads
Nuuvify.CommonPack.Security

Implementa Autorizacco e Autenticacco com OAuth2, JWT - deve ser baixado no projeto IoC, aqui nco contempla OpenId que esta em outra Lib

Nuuvify.CommonPack.StandardHttpClient

Cliente HTTP otimizado para .NET com gerenciamento automctico de tokens, retry policies com Polly, resource management otimizado e performance aprimorada. Inclui ConfigureAwait(false) para bibliotecas, proper disposal patterns e prevencco de memory leaks. Ideal para comunicacco resiliente com APIs REST e web services SOAP.

Nuuvify.CommonPack.Security.JwtCredentials

Gerencia seu JWK e proteção do seu JWT signing

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
2.1.0 0 10/21/2025
2.1.0-preview.25102003 0 10/20/2025
2.0.0 3,425 2/11/2025
2.0.0-preview.24111902 1,974 11/20/2024
2.0.0-preview.24102502 492 10/25/2024
2.0.0-preview.24102402 301 10/24/2024
2.0.0-preview.24101505 443 10/15/2024
2.0.0-preview.24100802 544 10/8/2024
2.0.0-preview.24092503 95 9/25/2024
2.0.0-preview.24092002 82 9/20/2024
2.0.0-preview.24080103 3,306 8/2/2024
2.0.0-preview.24071802 299 7/18/2024
2.0.0-preview.24071704 240 7/17/2024
2.0.0-preview.24071702 93 7/17/2024
2.0.0-preview.24071602 82 7/17/2024
2.0.0-preview.24070101 254 7/2/2024
2.0.0-preview.24062102 88 6/22/2024
2.0.0-preview.24052601 92 5/27/2024
2.0.0-preview.24051602 70 5/17/2024
2.0.0-preview.24050501 98 5/6/2024
2.0.0-preview.24032102 121 3/21/2024
2.0.0-preview.24031501 94 3/15/2024
1.7.3-preview.24042902 76 4/29/2024
1.7.2 11,282 11/23/2023
1.7.2-preview.23112304 95 11/23/2023
1.7.1 1,805 11/7/2023
1.7.1-preview.23110605 91 11/7/2023
1.7.0 405 11/6/2023
1.7.0-preview.23102502 159 10/25/2023
1.6.2-preview.23100404 111 10/4/2023
1.6.1 5,875 7/12/2023
1.6.1-preview.23080204 184 8/3/2023
1.6.1-preview.23071208 139 7/12/2023
1.6.0 1,137 6/23/2023
1.6.0-preview.23071206 130 7/12/2023
1.6.0-preview.23062304 133 6/23/2023
1.6.0-preview.23061906 178 6/19/2023
1.5.0 1,340 4/14/2023
1.5.0-preview.23022802 210 3/1/2023
1.4.0 1,094 2/10/2023
1.4.0-preview.23021002 166 2/10/2023
1.3.2 1,812 1/10/2023
1.3.2-preview.23011008 179 1/10/2023
1.3.2-preview.22122623 280 12/27/2022
1.3.2-preview.22112903 196 11/29/2022
1.3.2-preview.22112802 170 11/29/2022
1.3.2-preview.22112503 187 11/25/2022
1.3.1 1,439 11/25/2022
1.3.1-preview.22112404 172 11/25/2022
1.3.0 1,316 11/24/2022
1.3.0-preview.22112302 180 11/23/2022
1.3.0-preview.22112203 177 11/23/2022
1.2.0 2,523 10/21/2022
1.2.0-preview.22101902 236 10/19/2022
1.1.0 1,734 9/1/2022
1.1.0-preview.22083104 171 9/1/2022
1.1.0-preview.22083102 180 8/31/2022
1.1.0-preview.22072003 429 7/20/2022
1.0.5 2,363 6/28/2022
1.0.5-preview.22062802 194 6/28/2022
1.0.4-preview.22062202 206 6/22/2022
1.0.3 1,740 6/20/2022
1.0.3-preview.22061502 198 6/15/2022
1.0.3-preview.22060102 257 6/1/2022
1.0.3-preview.22052702 403 5/27/2022
1.0.3-preview.22051801 381 5/18/2022
1.0.3-preview.22033004 501 3/31/2022
1.0.3-preview.22033002 232 3/30/2022
1.0.3-preview.22032902 212 3/30/2022
1.0.3-preview.22031108 248 3/11/2022
1.0.2 1,807 3/11/2022
1.0.1 1,712 3/10/2022
1.0.0-preview.22030702 212 3/7/2022
1.0.0-preview.22030206 213 3/2/2022
1.0.0-preview.22030205 213 3/2/2022