LeanOAuth.Core 2.0.0

dotnet add package LeanOAuth.Core --version 2.0.0
                    
NuGet\Install-Package LeanOAuth.Core -Version 2.0.0
                    
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="LeanOAuth.Core" Version="2.0.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="LeanOAuth.Core" Version="2.0.0" />
                    
Directory.Packages.props
<PackageReference Include="LeanOAuth.Core" />
                    
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 LeanOAuth.Core --version 2.0.0
                    
#r "nuget: LeanOAuth.Core, 2.0.0"
                    
#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 LeanOAuth.Core@2.0.0
                    
#: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=LeanOAuth.Core&version=2.0.0
                    
Install as a Cake Addin
#tool nuget:?package=LeanOAuth.Core&version=2.0.0
                    
Install as a Cake Tool

LeanOAuth

OAuth 1.0a (RFC 5849) for .NET, as three layers:

  • LeanOAuth.Core — credentials, percent-encoding, normalization, and the signer. No HTTP, no framework dependency.
  • LeanOAuth.Http — signs an HttpRequestMessage, a DelegatingHandler that signs automatically, and the three-legged flow (temporary credentials → authorization → token credentials).
  • LeanOAuth.AspNetCore — an ASP.NET Core authentication handler for "sign in with OAuth 1.0a", built on LeanOAuth.Http with no privileged access to its internals.

The protocol core has no knowledge of any particular provider. This repository is provider-neutral by decision: no provider-specific code, configuration, or tests live here, and nothing in it proves interoperability with a real provider. Conformance to RFC 5849 is established by the test suite; interoperability with any given provider is the consuming project's responsibility to verify.

Upgrading from 1.x? See Release notes first — the query-string and form-body signing change is silent and will change signatures your application already produces.

Table of contents

Vocabulary

Type names follow RFC 5849, because a credential in this protocol is always a key/secret pair and the RFC's names say so. Most provider documentation uses the older OAuth 1.0 Core vocabulary instead. Every public type whose name follows RFC 5849 names its OAuth 1.0 Core synonym in its XML doc, so a reader arriving from provider docs can find the right type. The mapping:

RFC 5849 OAuth 1.0 Core
Client credentials (ClientCredentials and subtypes) Consumer key / consumer secret
Temporary credentials (TemporaryCredentials) Request token
Token credentials (TokenCredentials) Access token

Installation

dotnet add package LeanOAuth.Core
dotnet add package LeanOAuth.Http
dotnet add package LeanOAuth.AspNetCore

Install LeanOAuth.Core alone for a console app, daemon, or MCP server that only needs to sign; add LeanOAuth.Http for the three-legged flow and the HttpClient integration; add LeanOAuth.AspNetCore only for browser sign-in.

LeanOAuth.Core

One call signs a request and returns the Authorization header value together with the signature base string that produced it — so when a provider returns a bare 401, there is something concrete to compare against the provider's own documented example.

The signature method is not a setting: it is carried by which ClientCredentials subtype you construct. HmacSha1ClientCredentials and PlainTextClientCredentials hold a shared secret; RsaSha1ClientCredentials holds an RSA private key instead. Pointing the wrong method at a provider becomes a compile error rather than an undiagnosable 401.

using LeanOAuth.Core;
using LeanOAuth.Core.Credentials;

var clientCredentials = new HmacSha1ClientCredentials("consumer-key", "consumer-secret");
var tokenCredentials = new OAuthToken("token", "token-secret");

var signer = new OAuthSigner();
var signature = signer.Sign(
    HttpMethod.Get,
    new Uri("https://example.com/resource?page=2"),
    clientCredentials,
    tokenCredentials
);

Console.WriteLine(signature.AuthorizationHeaderValue);
Console.WriteLine(signature.SignatureBaseString); // compare this against the provider's docs on a 401

Query-string parameters on the request URI are collected and signed automatically, per RFC 5849 §3.4.1.3.1 — pass form-body parameters through the additionalParameters argument of Sign if you are not using LeanOAuth.Http to build the request.

LeanOAuth.Http

Signs an HttpRequestMessage directly, or automatically via a DelegatingHandler registered on an HttpClient.

using LeanOAuth.Core.Credentials;
using LeanOAuth.Http;

var clientCredentials = new HmacSha1ClientCredentials("consumer-key", "consumer-secret");
var tokenCredentials = new OAuthToken("token", "token-secret");

var handler = new SocketsHttpHandler { AllowAutoRedirect = false };
using var httpClient = new HttpClient(
    new OAuthSigningHandler(clientCredentials, tokenCredentials) { InnerHandler = handler }
);

using var response = await httpClient.GetAsync("https://example.com/resource?page=2");

Two pipeline hazards OAuthSigningHandler cannot see from inside itself:

  • OAuthSigningHandler must sit inside any retry handler, closer to the transport — each retry needs a fresh nonce and timestamp, and a signature computed once and replayed across retries is bound to a stale nonce on every attempt after the first. With Polly, register this handler with AddHttpMessageHandler before AddPolicyHandler, so Polly wraps it rather than the other way around.
  • Automatic redirects must be disabled (AllowAutoRedirect = false above). The handler signs the request URI; a redirect the runtime follows automatically re-sends to a different URI the signature was never bound to, and the provider always rejects it. OAuthSigningHandler throws if it observes a redirect response, so this fails loudly rather than silently, but disabling auto-redirect and handling the redirect explicitly is what you want in practice.

The three-legged flow

OAuthFlow runs RFC 5849 §2 against plain HttpClient calls — no browser, no web framework, no test host — so it is reachable from a console app or a daemon:

using LeanOAuth.Core.Credentials;
using LeanOAuth.Http;

var clientCredentials = new HmacSha1ClientCredentials("consumer-key", "consumer-secret");
var endpoints = new OAuthProviderEndpoints(
    new Uri("https://example.com/oauth/request_token"),
    new Uri("https://example.com/oauth/authorize"),
    new Uri("https://example.com/oauth/access_token")
);

using var httpClient = new HttpClient(new SocketsHttpHandler { AllowAutoRedirect = false });
var flow = new OAuthFlow(httpClient, endpoints, clientCredentials);

var temporaryCredentials = await flow.RequestTemporaryCredentialsAsync(OAuthCallback.OutOfBand);
var authorizationUri = flow.BuildAuthorizationUri(temporaryCredentials);

// Send the resource owner to authorizationUri; they authorize and are given a verifier.
var verifier = /* obtained out-of-band, or from the callback URI's "oauth_verifier" query parameter */ "";

var tokenCredentials = await flow.ExchangeAsync(temporaryCredentials, verifier);

See samples/LeanOAuth.Samples.Console for the complete, runnable version of this flow.

LeanOAuth.AspNetCore

One adapter over LeanOAuth.Http, for "sign in with OAuth 1.0a" in an ASP.NET Core application:

using LeanOAuth.AspNetCore;
using LeanOAuth.Core.Credentials;
using LeanOAuth.Http;
using Microsoft.AspNetCore.Authentication.Cookies;

builder
    .Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
    .AddCookie(CookieAuthenticationDefaults.AuthenticationScheme)
    .AddOAuth10A(
        "oauth1a",
        options =>
        {
            options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
            options.ClientCredentials = new HmacSha1ClientCredentials("consumer-key", "consumer-secret");
            options.Endpoints = new OAuthProviderEndpoints(
                new Uri("https://example.com/oauth/request_token"),
                new Uri("https://example.com/oauth/authorize"),
                new Uri("https://example.com/oauth/access_token")
            );
        }
    );

app.MapGet(
    "/signin",
    () => Results.Challenge(new AuthenticationProperties { RedirectUri = "/" }, ["oauth1a"])
);

RFC 5849 defines no standard profile endpoint, so the handler does not fetch or expose provider profile data itself. To fetch one, use OAuth10AEvents.OnCreatingTicket: it hands you a OAuth10ACreatingTicketContext carrying the backchannel HttpClient, the client credentials, and the token credentials — the same public surface any headless caller uses to sign a request.

See samples/LeanOAuth.Samples.AspNetCore for the complete, runnable version.

Samples

  • samples/LeanOAuth.Samples.Console — completes the out-of-band flow against endpoints and credentials given on the command line. Names no provider.
  • samples/LeanOAuth.Samples.AspNetCore — demonstrates sign-in. Endpoints and credentials come from configuration, not code.

Neither sample contains provider-specific code, configuration, or endpoints.

Security responsibilities this library does not carry

LeanOAuth signs requests and runs the three-legged flow. It does not, and its use does not imply:

  • Token storage and encryption at rest. Temporary and token credentials are plain strings; where and how you persist them is your application's responsibility.
  • Transport security. The library signs over whatever HttpClient/Uri you give it; it does not enforce TLS. Send credentials only over HTTPS.
  • Callback URL validation. The library builds the authorization URI and reads back whatever the provider sends to your callback endpoint; validating that your callback route is reachable only as intended is your application's responsibility.
  • Request forgery prevention. LeanOAuth.AspNetCore correlates the challenge and callback through its own state cookie, matching the returned oauth_token against the one it requested. Beyond that, general CSRF and session-fixation hardening of your application is your responsibility.
  • Credential rotation. The library has no opinion on how long a consumer key/secret or token pair lives; rotating them is between you and the provider.

Release notes

See CHANGELOG.md.

Contributing

Contributions are welcome! Please fork the repository and submit pull requests for any improvements or bug fixes.

License

This project is licensed under the MIT License. See LICENSE.

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

    • No dependencies.
  • net8.0

    • No dependencies.

NuGet packages (1)

Showing the top 1 NuGet packages that depend on LeanOAuth.Core:

Package Downloads
LeanOAuth.Http

HttpRequestMessage signing, the signing DelegatingHandler, and the three-legged flow for LeanOAuth, an open source implementation of the OAuth1.0A RFC 5849 protocol in .NET. Part of LeanOAuth project.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
2.0.0 72 8/13/2026
1.0.1 351 6/22/2024
1.0.0 264 6/22/2024