Levge.Identity 2.3.0

dotnet add package Levge.Identity --version 2.3.0
                    
NuGet\Install-Package Levge.Identity -Version 2.3.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="Levge.Identity" Version="2.3.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Levge.Identity" Version="2.3.0" />
                    
Directory.Packages.props
<PackageReference Include="Levge.Identity" />
                    
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 Levge.Identity --version 2.3.0
                    
#r "nuget: Levge.Identity, 2.3.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 Levge.Identity@2.3.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=Levge.Identity&version=2.3.0
                    
Install as a Cake Addin
#tool nuget:?package=Levge.Identity&version=2.3.0
                    
Install as a Cake Tool

Publish NuGet Package

Levge.Identity

.NET 10 uygulamaları için JWT tabanlı kimlik doğrulama ve yetkilendirme altyapısı.
Tenant destekli, enum tabanlı rol hiyerarşisi ve clean architecture uyumlu tasarım.

İçindekiler


Kurulum

dotnet add package Levge.Identity
dotnet add package Levge.Domain

Program.cs

builder.Services
    .AddLevgeIdentity(new JwtConfig
    {
        Secret   = "en-az-32-karakter-uzun-gizli-anahtar",
        Issuer   = "https://api.levge.com",
        Audience = "https://api.levge.com",
        AccessTokenExpirationMinutes  = 60,
        RefreshTokenExpirationMinutes = 43200   // 30 gün
    })
    .AddLevgeAuthorization();

// Middleware sırası
app.UseAuthentication();
app.UseAuthorization();

Özel bir IIdentityProvider implemente ettiyseniz:

builder.Services.AddLevgeIdentity<MyCustomProvider>(jwtConfig);

JwtConfig Referansı

Özellik Tür Varsayılan Açıklama
Secret string HMAC-SHA256 imzalama anahtarı (≥32 karakter)
Issuer string Token yayıncısı
Audience string Token izleyicisi
Authority string OIDC authority (opsiyonel)
AccessTokenExpirationMinutes int 60 Access token ömrü (dakika)
RefreshTokenExpirationMinutes int 43200 Refresh token ömrü (dakika)
EnableRefreshTokens bool true Refresh token desteği
ValidateIssuer bool true Issuer doğrulaması
ValidateAudience bool true Audience doğrulaması
ValidateLifetime bool true Süre doğrulaması
ValidateSigningKey bool true İmza anahtarı doğrulaması
AuthScheme string? "Bearer" Authentication şeması

Token Üretimi — LevgeClaimsFactory

Application katmanında token oluşturmadan önce standart claim listesi üretin:

using Levge.Identity;
using Levge.Domain.Enums;

// Temel kullanım
var claims = LevgeClaimsFactory.Create(
    userId:     user.Id,
    email:      user.Email,
    role:       AppUserRole.TenantOwner,
    tenantId:   user.TenantId,
    tenantName: user.TenantName,
    roleId:     user.RoleId
);

var accessToken  = _jwtTokenService.GenerateAccessToken(claims);
var refreshToken = _jwtTokenService.GenerateRefreshToken();
var expiresAt    = _jwtTokenService.GetAccessTokenExpireTime();

Ek claim eklemek için extra parametresini kullanın:

var claims = LevgeClaimsFactory.Create(
    userId: user.Id,
    email:  user.Email,
    role:   AppUserRole.SuperAdmin,
    extra:  [new Claim("custom_key", "custom_value")]
);

IJwtTokenService

public interface IJwtTokenService
{
    string             GenerateAccessToken(IEnumerable<Claim> claims);
    string             GenerateRefreshToken();
    DateTime           GetAccessTokenExpireTime();
    DateTime           GetRefreshTokenExpireTime();
    ClaimsPrincipal?   GetPrincipalFromExpiredToken(string accessToken);
}

Refresh Token Akışı

GetPrincipalFromExpiredToken imzayı doğrular ancak süre kontrolü yapmaz — süresi dolmuş access token'dan kullanıcıyı tanımlamak için kullanılır:

[HttpPost("refresh")]
public async Task<IActionResult> Refresh([FromBody] RefreshRequest request)
{
    var principal = _jwtTokenService.GetPrincipalFromExpiredToken(request.AccessToken);
    if (principal is null)
        return Unauthorized();

    var userId = long.Parse(principal.FindFirstValue(LevgeClaimTypes.UserId)!);
    var user   = await _userRepo.GetWithRefreshTokenAsync(userId, request.RefreshToken);

    if (user is null || user.RefreshTokenExpiry < DateTime.UtcNow)
        return Unauthorized();

    var claims       = LevgeClaimsFactory.Create(user.Id, user.Email, user.AppRole, user.TenantId);
    var accessToken  = _jwtTokenService.GenerateAccessToken(claims);
    var refreshToken = _jwtTokenService.GenerateRefreshToken();

    await _userRepo.UpdateRefreshTokenAsync(user.Id, refreshToken,
        _jwtTokenService.GetRefreshTokenExpireTime());

    return Ok(new { AccessToken = accessToken, RefreshToken = refreshToken });
}

ICurrentUser

Herhangi bir servis veya controller'a inject ederek mevcut kullanıcıyı okuyun:

public class OrderService
{
    private readonly ICurrentUser _currentUser;

    public OrderService(ICurrentUser currentUser)
        => _currentUser = currentUser;

    public void Create()
    {
        if (!_currentUser.IsAuthenticated)
            throw new UnauthorizedAccessException();

        long   userId     = _currentUser.UserId!.Value;
        string email      = _currentUser.Email!;
        long   tenantId   = _currentUser.TenantId!.Value;
        string tenantName = _currentUser.TenantName!;
        string deviceId   = _currentUser.DeviceId ?? "unknown";

        // Enum tabanlı rol kontrolü
        AppUserRole? role = _currentUser.AppRole;  // AppUserRole.TenantOwner

        // Hiyerarşik rol kontrolü
        bool canManage = _currentUser.IsInRole(AppUserRole.TenantOwner);
        // SuperAdmin   → true (hepsi)
        // TenantOwner  → true (TenantOwner + TenantUser)
        // TenantUser   → false

        // Ham claim okuma
        string? custom = _currentUser.GetClaimValue("my_claim");
        string? header = _currentUser.GetHeaderValue("X-Correlation-Id");
    }
}

ICurrentUser Üyeleri

Üye Tür Açıklama
UserId long? Kullanıcı birincil anahtarı
RoleId long? Veritabanı rol kimliği
AppRole AppUserRole? Enum rol değeri
Role string? Rol adı (ham string)
Email string? E-posta adresi
TenantId long? Tenant birincil anahtarı
TenantName string? Tenant adı
DeviceId string? X-Device-Id başlığı
IsAuthenticated bool Kimlik doğrulandı mı
IsInRole(role) bool Hiyerarşik rol kontrolü
GetClaimValue(type) string? Claim değeri okuma
GetHeaderValue(key) string? HTTP başlığı okuma

Yetkilendirme — LevgePolicies

AddLevgeAuthorization() üç hiyerarşik policy kaydeder:

Policy sabiti Erişim
LevgePolicies.SuperAdmin Yalnızca SuperAdmin
LevgePolicies.TenantOwner SuperAdmin + TenantOwner
LevgePolicies.TenantUser SuperAdmin + TenantOwner + TenantUser
// Controller veya endpoint üzerinde kullanım
[Authorize(Policy = LevgePolicies.SuperAdmin)]
[HttpDelete("admin/users/{id}")]
public IActionResult DeleteUser(long id) { ... }

[Authorize(Policy = LevgePolicies.TenantOwner)]
[HttpGet("tenant/reports")]
public IActionResult GetReports() { ... }

[Authorize(Policy = LevgePolicies.TenantUser)]
[HttpGet("me")]
public IActionResult GetProfile() { ... }

AppUserRole Enum

public enum AppUserRole
{
    SuperAdmin  = 0,   // Tüm tenant'lar üzerinde tam yetki
    TenantOwner = 1,   // Kendi tenant'ı üzerinde tam yetki
    TenantUser  = 2    // Standart tenant kullanıcısı
}

IPasswordHasher

PBKDF2 algoritmasıyla şifre karma ve doğrulama:

public interface IPasswordHasher
{
    string Hash(string password);
    bool   Verify(string password, string hashedPassword);
}
// Kayıt
var hashed = _passwordHasher.Hash(request.Password);

// Giriş
bool valid = _passwordHasher.Verify(request.Password, user.PasswordHash);
if (!valid) return Unauthorized();

ICodeGenerator

public interface ICodeGenerator
{
    string GenerateNumericCode(int length = 6);
    string GenerateAlphaNumericCode(int length = 8);
    string GenerateScopedCode(string scopeKey, string entityId);
    string GeneratePassword(int length, int minUpper = 1, int minDigits = 1,
                            int minSpecial = 1, string specialChars = "!@#$%^&*");
}
Metot Örnek çıktı Kullanım
GenerateNumericCode(6) "483921" SMS / e-posta OTP
GenerateAlphaNumericCode(8) "K7MX2QBW" Aktivasyon kodu
GenerateScopedCode("email-verify", userId) "Xk9mT2pQrL4A" Tek kullanımlık bağlantı token'ı
GeneratePassword(12) "aB3@xKm!9Zqp" Geçici parola üretimi
// OTP
var otp = _codeGenerator.GenerateNumericCode();           // 6 hane

// E-posta doğrulama linki için
var token = _codeGenerator.GenerateScopedCode("email-verify", user.Id.ToString());

// Geçici parola
var tempPwd = _codeGenerator.GeneratePassword(length: 12, minUpper: 2, minSpecial: 2);

LevgeClaimTypes

Token üretimi ve okuma arasında tutarlılık için sabitler — her iki tarafta da bu sabitleri kullanın:

public static class LevgeClaimTypes
{
    public const string UserId     = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier";
    public const string Email      = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress";
    public const string Role       = "http://schemas.microsoft.com/ws/2008/06/identity/claims/role";
    public const string RoleId     = "role_id";
    public const string TenantId   = "tenant_id";
    public const string TenantName = "tenant_name";
}

Clean Architecture Örneği

src/
├── MyApp.Domain/
├── MyApp.Application/
│   └── Features/Auth/
│       ├── LoginCommand.cs
│       └── LoginCommandHandler.cs     ← LevgeClaimsFactory + IJwtTokenService burada
├── MyApp.Infrastructure/
│   └── Persistence/UserRepository.cs
└── MyApp.WebApi/
    ├── Program.cs                     ← AddLevgeIdentity + AddLevgeAuthorization
    └── Controllers/AuthController.cs
// Application katmanı — LoginCommandHandler.cs
public class LoginCommandHandler
{
    private readonly IJwtTokenService _jwt;
    private readonly IPasswordHasher  _hasher;
    private readonly IUserRepository  _users;

    public async Task<TokenResponse> Handle(LoginCommand cmd)
    {
        var user = await _users.FindByEmailAsync(cmd.Email)
            ?? throw new UnauthorizedException();

        if (!_hasher.Verify(cmd.Password, user.PasswordHash))
            throw new UnauthorizedException();

        var claims = LevgeClaimsFactory.Create(
            userId:     user.Id,
            email:      user.Email,
            role:       user.AppRole,
            tenantId:   user.TenantId,
            tenantName: user.TenantName
        );

        return new TokenResponse(
            AccessToken:  _jwt.GenerateAccessToken(claims),
            RefreshToken: _jwt.GenerateRefreshToken(),
            ExpiresAt:    _jwt.GetAccessTokenExpireTime()
        );
    }
}

// WebApi katmanı — Controller
[ApiController, Route("api/auth")]
public class AuthController : ControllerBase
{
    private readonly ICurrentUser _currentUser;

    [HttpPost("login")]
    [AllowAnonymous]
    public Task<IActionResult> Login([FromBody] LoginCommand cmd) { ... }

    [HttpGet("me")]
    [Authorize(Policy = LevgePolicies.TenantUser)]
    public IActionResult Me() => Ok(new
    {
        _currentUser.UserId,
        _currentUser.Email,
        _currentUser.AppRole,
        _currentUser.TenantId,
        _currentUser.TenantName
    });
}

Bağımlılıklar

Paket Amaç
Microsoft.AspNetCore.App (FrameworkReference) ASP.NET Core altyapısı
Microsoft.AspNetCore.Authentication.JwtBearer JWT middleware
Levge.Domain AppUserRole enum ve domain primitives
Levge.Exceptions LevgeException temel exception türleri
Product 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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (5)

Showing the top 5 NuGet packages that depend on Levge.Identity:

Package Downloads
Levge.AuditLog

EF Core tabanlı otomatik audit log altyapısı. Tenant ve soft-delete desteğiyle birlikte clean architecture uyumlu denetim kaydı çözümü.

Levge.Tenancy

SaaS uygulamaları için çok kiracılı (multi-tenant) altyapı. JWT tabanlı tenant çözümleme, EF Core Global Query Filter ve tenant yaşam döngüsü yönetimi.

Levge.MediatR

MediatR tabanlı domain event dispatcher, EF Core interceptor ve FluentValidation pipeline behavior. IDomainEventDispatcher implementasyonu, SaveChanges sonrası otomatik domain event dispatch ve ValidationBehavior altyapısı.

Levge.Caching

Levge ekosistemi için opsiyonel önbellekleme altyapısı. Memory Cache ve Redis desteği, JWT token revoke servisi. AddLevgeCaching() ile projeye eklenebilir.

Levge.Subscription

Levge ekosistemi için opsiyonel abonelik ve kota takip altyapısı. Plan, modül, tenant aboneliği, kullanım takibi ve yenileme job desteği. AddLevgeSubscription() ile projeye eklenebilir.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
2.3.0 159 4/29/2026
2.1.0 117 4/27/2026
2.0.1 131 4/27/2026
1.1.46 145 1/22/2026
1.1.45 288 1/20/2026
1.1.44 111 1/20/2026
1.1.43 506 7/3/2025
1.1.42 233 7/3/2025
1.1.41 256 6/22/2025
1.1.21 185 6/22/2025
1.1.1 492 6/18/2025
1.1.0 228 6/18/2025
1.0.5 212 6/17/2025
1.0.4 218 6/17/2025
1.0.3 215 6/17/2025
1.0.2 217 6/17/2025
1.0.0 234 6/16/2025