Licenze in Qualsiasi Linguaggio
L’API di Auris Licensing è un’API REST/JSON standard. Non hai bisogno di un SDK — qualsiasi linguaggio in grado di effettuare una POST HTTP e analizzare JSON può validare licenze, attivare dispositivi e controllare le funzionalità.
Se stai usando JavaScript/TypeScript, usa invece l’SDK @auris/js — gestisce automaticamente il fallback offline e la cache delle revoche.
L’Unico Endpoint di Cui Hai Bisogno
POST https://your-auris-domain/api/licensing/validate
// Request
{
"key": "VIG-A8BC-D3EF-G4HJ-K5LM"
}
// Response (valid)
{
"valid": true,
"features": ["threat-intel", "vuln-scan"],
"seats": { "used": 1, "max": 5 },
"expiresAt": "2027-03-15T00:00:00Z"
}
// Response (invalid)
{
"valid": false,
"reason": "EXPIRED"
}Header: Content-Type: application/json e x-tenant: your-tenant (opzionale, predefinito altovar).
Nessun Bearer token necessario. Questo è un endpoint pubblico.
Esempi per Linguaggio
C#
C# (.NET)
using System.Net.Http;
using System.Text;
using System.Text.Json;
public record LicenseResult(bool Valid, string? Reason, string[]? Features, DateTime? ExpiresAt);
public class AurisLicense
{
private static readonly HttpClient _http = new();
private readonly string _baseUrl;
private readonly string _tenant;
public AurisLicense(string domain, string tenant = "altovar")
{
_baseUrl = $"https://{domain}";
_tenant = tenant;
}
public async Task<LicenseResult> ValidateAsync(string key)
{
var request = new HttpRequestMessage(HttpMethod.Post, $"{_baseUrl}/api/licensing/validate")
{
Content = new StringContent(
JsonSerializer.Serialize(new { key }),
Encoding.UTF8, "application/json")
};
request.Headers.Add("x-tenant", _tenant);
var response = await _http.SendAsync(request);
var json = await response.Content.ReadAsStringAsync();
return JsonSerializer.Deserialize<LicenseResult>(json,
new JsonSerializerOptions { PropertyNameCaseInsensitive = true })!;
}
public async Task ActivateAsync(string key, string fingerprint, string? name = null)
{
var request = new HttpRequestMessage(HttpMethod.Post, $"{_baseUrl}/api/licensing/activate")
{
Content = new StringContent(
JsonSerializer.Serialize(new { key, fingerprint, name }),
Encoding.UTF8, "application/json")
};
request.Headers.Add("x-tenant", _tenant);
var response = await _http.SendAsync(request);
if (!response.IsSuccessStatusCode)
throw new Exception($"Activation failed: {response.StatusCode}");
}
public async Task DeactivateAsync(string key, string fingerprint)
{
var request = new HttpRequestMessage(HttpMethod.Post, $"{_baseUrl}/api/licensing/deactivate")
{
Content = new StringContent(
JsonSerializer.Serialize(new { key, fingerprint }),
Encoding.UTF8, "application/json")
};
request.Headers.Add("x-tenant", _tenant);
await _http.SendAsync(request);
}
}Utilizzo:
var license = new AurisLicense("auth.yourdomain.com");
// Validate
var result = await license.ValidateAsync("VIG-A8BC-D3EF-G4HJ-K5LM");
if (result.Valid)
{
Console.WriteLine($"Valid! Features: {string.Join(", ", result.Features ?? [])}");
}
// Activate device
await license.ActivateAsync("VIG-A8BC-D3EF-G4HJ-K5LM", GetMachineId(), Environment.MachineName);
// Feature gating
if (result.Features?.Contains("threat-intel") == true)
{
// Enable threat intel module
}curl
Per test o script shell:
# Validate
curl -s -X POST https://auth.yourdomain.com/api/licensing/validate \
-H "Content-Type: application/json" \
-H "x-tenant: altovar" \
-d '{"key": "VIG-A8BC-D3EF-G4HJ-K5LM"}' | jq
# Activate device
curl -s -X POST https://auth.yourdomain.com/api/licensing/activate \
-H "Content-Type: application/json" \
-H "x-tenant: altovar" \
-d '{"key": "VIG-A8BC-D3EF-G4HJ-K5LM", "fingerprint": "abc123", "name": "Dev Machine"}'
# Deactivate device
curl -s -X POST https://auth.yourdomain.com/api/licensing/deactivate \
-H "Content-Type: application/json" \
-H "x-tenant: altovar" \
-d '{"key": "VIG-A8BC-D3EF-G4HJ-K5LM", "fingerprint": "abc123"}'Validazione Offline (JWT)
Quando una chiave viene emessa, è accompagnata da un jwtToken — un JWT firmato contenente i diritti. Per la validazione offline senza SDK, decodifica il payload JWT (base64url) e verifica:
- Scadenza: il claim
exp(timestamp Unix) deve essere nel futuro - Revoca: recupera periodicamente
/api/licensing/revocation-liste verifica se iljtidel JWT è nella lista delle revoche - Diritti:
auris_lic.features,auris_lic.seats.max,auris_lic.devices.max
// JWT payload (decoded)
{
"jti": "key_abc123",
"iss": "auris",
"sub": "VIG-A8BC-D3EF-G4HJ-K5LM",
"exp": 1804723200,
"auris_lic": {
"features": ["threat-intel", "vuln-scan"],
"seats": { "max": 5 },
"devices": { "max": 3 }
}
}Per una validazione offline completa con verifica della firma, usa la chiave pubblica di Auris da /.well-known/jwks.json. La maggior parte dei linguaggi dispone di librerie JWT (es. System.IdentityModel.Tokens.Jwt per C#, crate jsonwebtoken per Rust, golang-jwt per Go).
Fingerprinting del Dispositivo
Per le licenze basate su dispositivo, genera un identificatore macchina stabile:
| Linguaggio | Metodo |
|---|---|
| C# | System.Management → Win32_ComputerSystemProduct.UUID o Environment.MachineName |
| Rust | crate machine-uid o /etc/machine-id su Linux |
| C/C++ | /etc/machine-id (Linux), IOPlatformUUID (macOS), registro MachineGuid (Windows) |
| Go | github.com/denisbrodbeck/machineid |
| Python | uuid.getnode() o platform.node() |
| Java | InetAddress.getLocalHost().getHostName() + indirizzo MAC |
Il fingerprint deve essere semplicemente una stringa stabile e unica per la macchina. Invialo ad activate e deactivate.
Riepilogo
Lo schema è lo stesso in ogni linguaggio:
1. POST /api/licensing/validate {"key": "..."} → {valid, features, seats, ...}
2. POST /api/licensing/activate {"key": "...", "fingerprint": "..."} → 200 OK
3. POST /api/licensing/deactivate {"key": "...", "fingerprint": "..."} → 200 OKTre endpoint. Nessun SDK necessario. Nessuna API key. Nessun Bearer token. Solo HTTP + JSON.