SDK Integration Guide

Integrating the Orion .NET SDK into your application

Back to Documentation

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 address
  • Firstname — First name
  • Surname — Last name
  • PermId — Permanent unique identifier (GUID)
  • OrganisationId — The user's organisation PublicId
  • Role — UserRole (Standard or Administrator)
  • Phone — Phone number (if available)

Code Examples

1

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();
    }
}

2

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...

3

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",
    "{}"
);

4

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();
    }
}

5

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: OAuthFederated is the recommended filter type for all new web applications.
  • Client ID = Application.PublicId: Your OAuth client_id is 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. For OAuthUserBearer, 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-configuration and JWKS endpoint to verify your setup.
← API Reference Back to Documentation