Demonstrates SciChart's Simple Server Validation v2 flow in an ASP.NET Core MVC application via the SciChart.AspNetCore.SimpleLicensing package.
This example uses inline meta-tag delivery as the primary path: the licence token is rendered into <head> by the layout, so SciChart validates with no XHR on each full page load. The XHR endpoint stays mapped for re-validation when long-running sessions outlive the cached cookie.
A v2 token can take one of two shapes on the wire:
- Inline (4 fields) —
v2:serverNonce:serverNow:hmac. Independent of any client state; servable to many clients and embeddable in HTML via a<meta>tag. Should still be signed per request — the embeddedserverNowages relative to the client's clock and will fall outsidemax_skewonce the token is older than the licence's tolerance, so caching past that point causes valid clients to reject otherwise-correct tokens. - Round-trip (5 fields) —
v2:clientNonce:serverNonce:serverNow:hmac. The client generates a random nonce in WASM and sends it as?nonce=<hex>; the server echoes it into the signed token. A captured response is bound to the requesting client and cannot be replayed on another origin.
For most deployments the two shapes are interchangeable under a single licence — mix inline meta-tag delivery and round-trip requests freely, the SciChart client accepts whichever arrives. Deployments that can't keep server and client clocks in reasonable alignment should be locked to round-trip only: inline tokens can drift stale, round-trip tokens are signed against the request that produced them.
The fourth field of SV:H:V:N chooses: 0 (permissive default) accepts both shapes; 1 (restricted) accepts round-trip only and disables inline delivery.
Initial validation, every full page load — no XHR:
ASP.NET Core MVC renders:
<head>
<scichart-license /> → <meta name="x-scichart-license"
content="v2:<serverNonce>:<serverNow>:<hmac>" />
</head>
Browser loads → SciChart WASM reads the meta tag, verifies the HMAC against
the runtime licence key's embedded secret, checks clock skew, and caches
the result in `scLicense` until valid_time has elapsed.
Re-validation (cached cookie expired without a page reload, or validate_nonce=1):
Browser (SciChart.js)
→ GET /api/license?orderid=<X>[&nonce=<hex>]
← 200 OK body: v2:[clientNonce:]serverNonce:serverNow:hmac
Served by `MapSciChartLicenseEndpoint()` from the same package.
AddSciChartSimpleLicensing(...) |
Registers the singleton token service; binds your Server Secret. |
<scichart-license /> |
Razor tag helper. One line in _Layout.cshtml head; emits a fresh <meta name="x-scichart-license" content="v2:..." /> per render. |
app.MapSciChartLicenseEndpoint() |
GET /api/license for re-validation after the cached cookie expires, and the only path used when validate_nonce=1. |
The package contains no native dependency — just System.Security.Cryptography.HMACSHA256.
-
.NET 10 SDK (the package itself targets
net8.0and works with .NET 8+) -
Node.js 18+ (for building the client bundle)
-
A SciChart license with the
SV:H:V:Nfeature flag, where:max_skew— accepted client/server clock skew asHorH.MM(e.g.0.05= 5 min,1= 1 h,1.30= 90 min).0disables the check.valid_time— token validity in the client's wall clock, sameH.MMformat (e.g.168= 7 days,0.30= 30 min)validate_nonce—0accepts either shape (permissive default);1restricts to round-trip only (inline delivery disabled)
Contact support@scichart.com to have an SV v2 feature added to your license.
-
Get your Server Secret Log in to SciChart MyAccount and open Orders & Keys → Manage Licenses → Runtime License Key. Copy the Server Secret (a 64-char hex string) from the Server Secret section. Only present if your license carries the Simple Server Validation (
SV) feature. -
Set the Server Secret Edit
appsettings.jsonand replaceYOUR_SERVER_SECRET_HERE:"SciChart": { "ServerSecret": "0123456789abcdef..." }
For production, override via the standard ASP.NET Core configuration sources (user secrets, environment variables, key vault).
-
Set the client license key Edit
src/index.tsand replace the key passed tosetRuntimeLicenseKeywith your full license key string. The key must carry anSV:H:V:Nfeature. -
Build the client bundle
npm install npm run build
-
Run the server
dotnet run
Open http://localhost:5000 — the chart should render without a watermark.
Program.cs:
builder.Services.AddSciChartSimpleLicensing(builder.Configuration.GetSection("SciChart"));
// ...
app.MapSciChartLicenseEndpoint();Views/_ViewImports.cshtml:
@addTagHelper *, SciChart.AspNetCore.SimpleLicensingViews/Shared/_Layout.cshtml:
<head>
<scichart-license />
...
</head>That's the entire integration. Any new view rendered through _Layout.cshtml automatically carries a fresh server-signed v2 token.
- View source on http://localhost:5000 — you should see
<meta name="x-scichart-license" content="v2:..." />in<head>. - Open browser DevTools → Network. On a fresh load with
validate_nonce=0you should see no/api/licenserequest — the meta tag covers validation. Withvalidate_nonce=1, every load firesGET /api/license?orderid=...&nonce=<hex>returning200. Either way, the same endpoint will be hit later for re-validation once the cached cookie expires. - In Application → Cookies,
scLicenseis set with a future expiry. - The console should log
Simple server license validated.
Inline shape (4 colon-separated fields):
v2:<serverNonce>:<serverNow>:<hmac>
Round-trip shape (5 colon-separated fields):
v2:<clientNonce>:<serverNonce>:<serverNow>:<hmac>
serverNonce— server-generated random hex (≥ 16 chars)serverNow— server wall-clock Unix timestamp, decimal secondsclientNonce(round-trip only) — verbatim echo of the request's?nonce=value, validated against^[0-9a-fA-F]{8,64}$hmac—HMAC-SHA256(serverSecret, payload)where the payload is everything before the final colon
See ../SimpleServerSideLicensing-Readme.md for Python, Go, Ruby, PHP, and Rust snippets.
Key point in all cases: hex-decode the Server Secret to binary bytes before passing to HMAC. Do not use the hex string directly as the key.
Inline-mode caching: not recommended. Inline tokens are not bound to a particular client, but the embedded
serverNowages relative to the client's clock and will fall outsidemax_skewonce the cache is older than the licence's tolerance — sign per request. Round-trip responses cannot be cached either.