SDK Integration Guide
Integrating the Orion .NET SDK into your application
Installation
Install the Orion SDK from NuGet:
dotnet add package Clashawaun.Orion.Sdk.NetCore
Or via the NuGet Package Manager:
Install-Package Clashawaun.Orion.Sdk.NetCore
The SDK targets .NET 6+ and is compatible with ASP.NET Core applications.
IFederationConfig Setup
Register IFederationConfig in your
application's dependency injection container. This tells the SDK how to communicate with Orion.
using OrionDotNetCore.Entities; var builder = WebApplication.CreateBuilder(args); // Register Orion SDK configuration builder.Services.AddSingleton<IFederationConfig>(new FederationConfig { // Required: URL of the Orion federation endpoint FederationServer = "https://login.shanecraven.com/federation", // Required: Your application identifier ApplicationId = "my-application", // Required: Authentication filter type (see below) FilterType = FederationFilterType.OAuthFederated, // Whether auth is optional (allows anonymous access) IsOptional = false, // OAuth-specific settings (required for OAuth filter types) OAuthOrganisationId = "your-org-public-id", OAuthClientId = "your-app-public-id", // Same as Application.PublicId OAuthScopes = "openid profile email", OAuthAudience = "your-app-public-id", // Sovereign Signing (optional — enables out-of-band JWT signing) // Choose ONE validation mode: // Mode 1: Cert chain — auto-rotation, recommended for production with PKI SovereignSigningPoolId = "guardian-pool", SovereignTrustedRootCertificates = new[] { "-----BEGIN CERTIFICATE-----\n..." }, // Mode 2: Thumbprint pinning — no PKI required // SovereignSigningPoolId = "guardian-pool", // SovereignKeyThumbprints = new[] { "sha256:a1b2c3d4..." }, // Mode 3: Embedded keys — maximum isolation, no JWKS fetch // SovereignPublicKeys = new[] { "-----BEGIN PUBLIC KEY-----\n..." }, // Optional: pin to a specific key version // SovereignRequiredKeyId = "guardian-pool-v1", }); var app = builder.Build(); app.Run();
Sovereign Signing
Sovereign Signing enables external agents to hold JWT signing keys on separate servers, completely disconnected from Orion. The Orion server never possesses the private key material — even a full server compromise cannot forge tokens.
| Mode | Config Property | Server Trust | Key Rotation |
|---|---|---|---|
| Cert chain | SovereignTrustedRootCertificates |
Verifies x5c chain to trusted root | Automatic (no redeploy) |
| Thumbprint | SovereignKeyThumbprints |
Verifies key material hash | Update allowlist |
| Embedded keys | SovereignPublicKeys |
None — no JWKS fetch | Redeploy required |
| Pool-only | SovereignSigningPoolId only |
Trusts pool JWKS directly | Automatic |
Production deployments must use cert chain, thumbprint, or embedded key mode. Pool-only mode trusts the server JWKS and is only for dev/staging.
FederationFilterType Options
The FilterType property determines
how the SDK authenticates requests. Choose based on your application type:
| FilterType | Use Case | Mechanism |
|---|---|---|
| UserFederated | Web app (legacy federation) | Cookie redirect to /federation/Login |
| OAuthFederated | Web app (OAuth 2.0 SSO) | OAuth authorization code + PKCE flow |
| OAuthUserBearer | API (JWT validation) | Validates Bearer token from Authorization header |
| SystemAccountExternal | Service-to-service (HMAC) | HMAC-SHA256 signature in Authorization header |
| None | Optional auth / custom | No automatic authentication (manual handling) |
OrionPrincipal
After successful authentication, HttpContext.User
is populated with an OrionPrincipal containing
the authenticated user's data.
using OrionDotNetCore.Principal; // Cast HttpContext.User to OrionPrincipal var user = (OrionPrincipal)User; // Access user properties var email = user.User.Email; var firstName = user.User.Firstname; var surname = user.User.Surname; var permId = user.User.PermId; // Unique user identifier var orgId = user.User.OrganisationId; // Organisation PublicId var role = user.User.Role; // UserRole enum var phone = user.User.Phone;
Available properties on OrionPrincipal.User:
Email— User's email addressFirstname— First nameSurname— Last namePermId— Permanent unique identifier (GUID)OrganisationId— The user's organisation PublicIdRole— UserRole (Standard or Administrator)Phone— Phone number (if available)
Code Examples
OAuth Web Application (SSO)
A web application that authenticates users via OAuth 2.0 with PKCE:
using OrionDotNetCore.Entities; using OrionDotNetCore.Filters; using OrionDotNetCore.Principal; using Microsoft.AspNetCore.Mvc; // Program.cs var builder = WebApplication.CreateBuilder(args); builder.Services.AddControllersWithViews(); builder.Services.AddSingleton<IFederationConfig>(new FederationConfig { FederationServer = "https://login.shanecraven.com/federation", ApplicationId = "my-web-app", IsOptional = false, FilterType = FederationFilterType.OAuthFederated, OAuthOrganisationId = "your-org-id", OAuthClientId = "your-client-id", OAuthScopes = "openid profile email", OAuthAudience = "your-client-id", }); var app = builder.Build(); app.MapControllerRoute("default", "{controller=Home}/{action=Index}"); app.Run(); // HomeController.cs [OrionFederationFilter] public class HomeController : Controller { public ActionResult Index() { var user = (OrionPrincipal)User; ViewBag.Welcome = $"Hello, {user.User.Firstname}!"; return View(); } }
Protected API (Bearer Token)
An API that validates JWT access tokens from the Authorization header:
// Program.cs builder.Services.AddSingleton<IFederationConfig>(new FederationConfig { FederationServer = "https://login.shanecraven.com/federation", ApplicationId = "my-api", IsOptional = false, FilterType = FederationFilterType.OAuthUserBearer, OAuthOrganisationId = "your-org-id", OAuthClientId = "your-client-id", OAuthAudience = "your-client-id", }); // ApiController.cs [OrionFederationFilter] [ApiController] [Route("api/[controller]")] public class DataController : ControllerBase { [HttpGet] public ActionResult GetData() { var user = (OrionPrincipal)User; return Ok(new { message = $"Authenticated as {user.User.Email}" }); } } // Client sends: // GET /api/data // Authorization: Bearer eyJhbGciOiJSUzI1NiIs...
System Account (HMAC Client)
A backend service making authenticated API calls using HMAC:
using System.Security.Cryptography; using System.Text; public class OrionApiClient { private readonly string _publicKey; private readonly string _secretKey; private readonly HttpClient _http; public OrionApiClient(string publicKey, string secretKey) { _publicKey = publicKey; _secretKey = secretKey; _http = new HttpClient(); } public async Task<string> CallApi(string url, string jsonBody) { // Compute HMAC-SHA256 signature var keyBytes = Encoding.UTF8.GetBytes(_secretKey); var bodyBytes = Encoding.UTF8.GetBytes(jsonBody); using var hmac = new HMACSHA256(keyBytes); var hash = hmac.ComputeHash(bodyBytes); var signature = Convert.ToBase64String(hash); // Build request var request = new HttpRequestMessage(HttpMethod.Post, url); request.Content = new StringContent(jsonBody, Encoding.UTF8, "application/json"); request.Headers.Add("Authorization", $"{_publicKey}:{signature}"); var response = await _http.SendAsync(request); return await response.Content.ReadAsStringAsync(); } } // Usage: var client = new OrionApiClient("public-key-guid", "secret-key-base64"); var result = await client.CallApi( "https://login.shanecraven.com/legacy/api/User/Profile/my-app/session-key", "{}" );
Legacy Federation (Cookie Redirect)
The original authentication method for .NET web applications:
// Program.cs builder.Services.AddSingleton<IFederationConfig>(new FederationConfig { FederationServer = "https://login.shanecraven.com/federation", ApplicationId = "my-legacy-app", IsOptional = false, FilterType = FederationFilterType.UserFederated, }); // Controller — exact same pattern [OrionFederationFilter] public class DashboardController : Controller { public ActionResult Index() { var user = (OrionPrincipal)User; // user.User.Email, user.User.Firstname, etc. return View(); } }
Optional Authentication
Allow both authenticated and anonymous users to access a page:
// Set IsOptional = true in FederationConfig builder.Services.AddSingleton<IFederationConfig>(new FederationConfig { FederationServer = "https://login.shanecraven.com/federation", ApplicationId = "my-app", IsOptional = true, // Key: allows anonymous FilterType = FederationFilterType.OAuthFederated, OAuthOrganisationId = "your-org-id", OAuthClientId = "your-client-id", OAuthScopes = "openid profile email", OAuthAudience = "your-client-id", }); // In your controller, check if user is authenticated [OrionFederationFilter] public class HomeController : Controller { public ActionResult Index() { if (User is OrionPrincipal orionUser) { ViewBag.Name = orionUser.User.Firstname; ViewBag.IsLoggedIn = true; } else { ViewBag.IsLoggedIn = false; } return View(); } }
Tips & Best Practices
- Use OAuth for new projects:
OAuthFederatedis the recommended filter type for all new web applications. - Client ID = Application.PublicId: Your OAuth
client_idis the same GUID shown in the Application Manager. - Keep secrets out of code: Store
OAuthClientId, secrets, and configuration in environment variables or a secrets manager. - Handle token refresh: The SDK handles refresh automatically for
OAuthFederated. ForOAuthUserBearer, clients must refresh tokens before expiry. - Apply the filter globally or per-controller: Use
[OrionFederationFilter]on individual controllers or register it globally in MVC filters. - Test OAuth configuration: Use the OIDC discovery endpoint
/oauth/{org}/.well-known/openid-configurationand JWKS endpoint to verify your setup.