Ark.oAuth.Client 2.0.1

There is a newer version of this package available.
See the version list below for details.
dotnet add package Ark.oAuth.Client --version 2.0.1
                    
NuGet\Install-Package Ark.oAuth.Client -Version 2.0.1
                    
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="Ark.oAuth.Client" Version="2.0.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Ark.oAuth.Client" Version="2.0.1" />
                    
Directory.Packages.props
<PackageReference Include="Ark.oAuth.Client" />
                    
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 Ark.oAuth.Client --version 2.0.1
                    
#r "nuget: Ark.oAuth.Client, 2.0.1"
                    
#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 Ark.oAuth.Client@2.0.1
                    
#: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=Ark.oAuth.Client&version=2.0.1
                    
Install as a Cake Addin
#tool nuget:?package=Ark.oAuth.Client&version=2.0.1
                    
Install as a Cake Tool

Ark.oAuth.Client

The OAuth 2.1 / OpenID Connect client for ASP.NET Core applications. One call in Program.cs, two required settings, and [Authorize] works.

It configures ASP.NET Core's own OpenID Connect and cookie handlers rather than hand-rolling the protocol, so PKCE, state, nonce, JWKS rollover and token refresh all come from the framework.

Built for Ark.oAuth.Oidc, but because it is the stock handler underneath, changing Authority and ClientId is enough to point the same application at Entra ID, Okta, Auth0 or Keycloak.

Install

dotnet add package Ark.oAuth.Client

Program.cs

using Ark.oAuth;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddArkOidcClient(builder.Configuration);
builder.Services.AddControllersWithViews();

var app = builder.Build();

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();          // MUST precede the next two
app.UseAuthentication();
app.UseAuthorization();

app.MapControllerRoute(name: "default", pattern: "{controller=Home}/{action=Index}/{id?}");
app.Run();

appsettings.json

Authority and ClientId are the only required keys — every endpoint is read from the provider's discovery document.

{
  "ark_oauth_client": {
    "Authority": "https://idp.example.com/my_idp",  // the issuer
    "ClientId": "my-app",
    "ClientSecret": null,                           // null = public client + PKCE
    "Scopes": [ "openid", "profile", "email", "offline_access" ],
    "CallbackPath": "/signin-oidc",
    "SignedOutCallbackPath": "/signout-callback-oidc",
    "SignedOutRedirectUri": "/",
    "AuthErrorPath": "/",                           // failed callbacks land here with ?auth_error=...
    "RequireHttpsMetadata": true,
    "CookieName": "my_app_auth",
    "RoleClaimType": "role",                        // ark_claims from the access token map onto this
    "ExpireMins": 480
  }
}

Using the result

[Authorize]
public IActionResult Secure() => View();

// Ark authorization claims (ark_claims) are projected as roles, so policies work directly
[Authorize(Roles = "billing.admin")]
public IActionResult Billing() => View();

Reading the access token — always per call, never cached; the cookie handler refreshes it underneath you:

var accessToken = await HttpContext.GetArkAccessTokenAsync();

var request = new HttpRequestMessage(HttpMethod.Get, "https://api.example.com/things");
await request.WithArkTokenAsync(HttpContext);

Protecting an API

builder.Services
    .AddAuthentication()
    .AddArkOidcApi(arkConfig);

The flows outside interactive sign-in

AddArkOidcClient also registers three services. All three work off the provider's discovery document, so they need the issuer and nothing else.

Service For
ArkSetupProbe Pairs local configuration against the provider's live metadata and returns ArkSetupModel — issuer mismatch, unregistered scopes, the exact redirect URI this app will send. Render it and a registration mistake reads as a sentence instead of invalid_client.
ArkClientCredentials The client credentials grant. GetTokenAsync caches until shortly before expiry; RequestTokenAsync forces a live exchange.
ArkRegistration Dynamic client registration (RFC 7591) and management (RFC 7592).
var model  = await setup.ProbeAsync(HttpContext);
var token  = await credentials.GetTokenAsync(clientId, secret, new[] { "reports.read" });
var client = await registration.RegisterAsync(metadata, token.AccessToken);

Registering the application

Three things have to line up on the provider, not one:

  1. Create the client.
  2. Register both redirect URIs — {host}/signin-oidc and {host}/signout-callback-oidc — matched byte for byte. No wildcards, no prefix matching.
  3. Grant each user access to that client. Without the mapping, sign-in fails with a message that looks like a wrong password.

Scopes on a client record are a whitelist: an unregistered scope is rejected, not dropped. offline_access is what produces a refresh token. Never add a controller action at CallbackPath — it shadows the handler. Sign out of both ArkOidcClient.CookieScheme and ArkOidcClient.OidcScheme, or the provider session survives and the next sign-in is silent.

Legacy flow

ark_oauth_client:UseLegacyFlow keeps the original cookie/bearer middleware for deployments migrating off the v1 endpoints. It does not validate state or nonce — treat it as a migration aid, not a supported configuration.

Documentation

A complete, runnable client application and the full walkthrough are in the repository: https://github.com/ir-dev/ark-oauth-oidc

License

MIT

Product Compatible and additional computed target framework versions.
.NET net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  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

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
2.0.10 151 9/12/2026
2.0.9 167 9/3/2026
2.0.8 133 9/2/2026
2.0.7 115 9/1/2026
2.0.6 116 9/1/2026
2.0.5 144 8/30/2026
2.0.4 129 8/29/2026
2.0.3 121 8/29/2026
2.0.2 143 8/19/2026
2.0.1 141 8/18/2026
2.0.0 124 8/17/2026
1.0.5.45 202 3/22/2026
1.0.5.44 189 3/20/2026
1.0.5.43 331 10/12/2025
1.0.5.42 345 7/9/2025
1.0.5.41 326 7/3/2025
1.0.5.40 328 7/3/2025
1.0.5.39 315 7/2/2025
1.0.5.38 313 7/2/2025
1.0.5.37 322 7/2/2025
Loading failed

2.0.1 — maintenance release.

No API change over 2.0.0. Rebuilt and republished alongside Ark.oAuth.Oidc 2.0.1 to keep the two
halves on the same version, and to carry the packaging fixes below. Consumers on 2.0.0 can upgrade
with no code change; the 2.0.0 notes apply unchanged and are kept below.

Packaging: the package icon (ark_logo.png) and the readme are packed at the root of the .nupkg, so
nuget.org and the Visual Studio package manager show both. The icon is referenced through
PackageIcon rather than the deprecated PackageIconUrl, and is included with an empty PackagePath so
it lands at the package root on a non-Windows build too.

2.0.0 — the standards release.

* AddArkOidcClient now configures ASP.NET Core's OpenID Connect and cookie handlers against the
 provider's discovery document. Real PKCE, state and nonce validation, JWKS rollover and silent
 refresh all come from the framework instead of being hand-rolled.
* Authority and ClientId are the only required settings — no pasted rsaPublic, no issuer/audience
 to mirror, no per-tenant key table to keep in step with rotation.
* AddArkOidcApi for protecting an API with bearer tokens from the same provider.
* Ark authorization claims (ark_claims) are projected onto the principal as role claims, so
 [Authorize(Roles = "...")] and policies work directly.
* GetArkAccessTokenAsync / WithArkTokenAsync read the current token per call, so a token refreshed
 by the cookie handler is picked up automatically.
* New services for the non-interactive flows: ArkSetupProbe (configuration vs. live metadata),
 ArkClientCredentials (client credentials grant with caching) and ArkRegistration (RFC 7591/7592).

Breaking / migration: the standard flow is now the default. Set ark_oauth_client:UseLegacyFlow to
true to keep the original cookie/bearer middleware while migrating — it does not validate state or
nonce and should be treated as a migration aid, not a supported configuration.

Packaging: the package no longer ships a sample appsettings file into consuming projects, and now
carries a readme, an SPDX license expression and a symbol package.