Sang.AspNetCore.SignAuthorization 2.2.0

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

SignAuthorization

NuGet version (Sang.AspNetCore.SignAuthorization)

A simple API URL signature verification middleware to validate requests through straightforward URL parameters.

English | 简体中文

How It Works

  1. Sort the token, timestamp, and nonce parameters in lexicographic order.
  2. Concatenate the three parameters into a single string and encrypt it using SHA1.
  3. Developers can then compare the obtained encrypted string with the signature.

Instructions

Step 1: Add the Package

Install-Package Sang.AspNetCore.SignAuthorization

or

dotnet add package Sang.AspNetCore.SignAuthorization

Step 2: Enable the Middleware

Enable this middleware before app.MapControllers();.

app.UseSignAuthorization(opt => {
    opt.sToken = "your-api-token";
});

Step 3: Use SignAuthorizeAttribute

Add SignAuthorizeAttribute where signing is required.

Example:

app.MapGet("/weatherforecast", () =>
{
    // your code
}).WithMetadata(new SignAuthorizeAttribute());

or:

[HttpGet]
[SignAuthorize]
public IEnumerable<WeatherForecast> Get()
{
    // your code
}

Settings

SignAuthorizationOptions

Parameter Default Value Description
UnauthorizedBack {"success":false,"status":10000,"msg":"Unauthorized"} JSON return content after validation failure
UnauthorizedBackJson null Pre-serialized JSON response for AOT scenarios
UnauthorizedStatusCode 401 HTTP status code for unauthorized response
sToken SignAuthorizationMiddleware API token for signing
WithPath false Include the requested path in the signature, starting with '/'
Expire 5 Signature expiration time (unit: seconds)
nTimeStamp timestamp GET parameter name for timestamp
nNonce nonce GET parameter name for the random number
nSign signature GET parameter name for the signature
nExtra Extra GET parameter name
UseHeader false Use the header to pass the signature

Examples

PHP Example

$sToken = "your-api-token";
$sReqTimeStamp = time();
$sReqNonce = getNonce();
$tmpArr = array($sToken, $sReqTimeStamp, $sReqNonce);
sort($tmpArr, SORT_STRING);
$sign = sha1(implode($tmpArr));
$url = "http://localhost:5177/weatherforecast?timestamp=$sReqTimeStamp&nonce=$sReqNonce&signature=$sign";
echo "$url\n";
echo file_get_contents($url);

function getNonce(){
    $str = '1234567890abcdefghijklmnopqrstuvwxyz';
    $t1='';
    for($i=0;$i<30;$i++){
        $j=rand(0,35);
        $t1 .= $str[$j];
    }
    return $t1;
}

.Net Example

var unixTimestamp = DateTimeOffset.Now.ToUnixTimeSeconds();
var sNonce = Guid.NewGuid().ToString();

ArrayList AL = new ArrayList();
AL.Add("your-api-token");
AL.Add(unixTimestamp.ToString());
AL.Add(sNonce);
AL.Sort(StringComparer.Ordinal);

var raw = string.Join("", AL.ToArray());
using System.Security.Cryptography.SHA1 sha1 = System.Security.Cryptography.SHA1.Create();
byte[] encry = sha1.ComputeHash(Encoding.UTF8.GetBytes(raw));
string sign = string.Join("", encry.Select(b => string.Format("{0:x2}", b)).ToArray()).ToLower();

var client = new HttpClient();
string jsoninfo = await client.GetStringAsync($"http://localhost:5177/weatherforecast?timestamp={unixTimestamp}&nonce={sNonce}&signature={sign}");

Use MakeSignAuthorization

Make sign authorization string.

var unixTimestamp = DateTimeOffset.Now.ToUnixTimeSeconds().ToString();
var sNonce = Guid.NewGuid().ToString("N");
var sToken = "your-api-token";
var sPath = "/weatherforecast";
var sExtra = "1"; // extra parameter: extra=1
string sign = MakeSignAuthorization.MakeSign(sToken, unixTimestamp, sNonce, sPath, sExtra);

Make sign URL.

var url = MakeSignAuthorization.MakeSignUrl("http://localhost:5177",  new SignAuthorizationOptions());

Use Cookie-based authorization for simple user scenarios (for example root, admin, init). The cookie stores username|timestamp|signature.

var cookieOptions = new CookieAuthorizationOptions
{
    sToken = "your-api-token",
    CookieName = "SignAuthorization",
    Expire = 3600,
    ReuseExpire = true
};

cookieOptions.AllowedUsers.UnionWith(new[] { "root", "admin", "init" });

app.UseCookieAuthorization(opt =>
{
    opt.sToken = cookieOptions.sToken;
    opt.CookieName = cookieOptions.CookieName;
    opt.Expire = cookieOptions.Expire;
    opt.ReuseExpire = cookieOptions.ReuseExpire;
    opt.CookieSeparator = cookieOptions.CookieSeparator;
    opt.AllowedUsers.UnionWith(cookieOptions.AllowedUsers);
});
app.MapGet("/login/{user}", (string user, HttpContext context) =>
{
    var timeStamp = DateTimeOffset.Now.ToUnixTimeSeconds().ToString();
    var cookieValue = MakeSignAuthorization.MakeCookieValue(
        "your-api-token",
        user,
        timeStamp,
        "|");

    context.Response.Cookies.Append(
        "SignAuthorization",
        cookieValue,
        new CookieOptions
        {
            HttpOnly = true,
            IsEssential = true,
            Expires = DateTimeOffset.Now.AddSeconds(3600)
        });

    return Results.Ok(new { success = true, user });
});

Protect Endpoint

app.MapGet("/secure", (HttpContext context) =>
{
    return Results.Ok(new
    {
        user = context.User.Identity?.Name,
        item = context.Items["SignAuthorizationUserName"]
    });
}).WithMetadata(new CookieAuthorizeAttribute("root", "admin"));

CookieAuthorizationOptions

Parameter Default Value Description
UnauthorizedBack {"success":false,"status":10000,"msg":"Unauthorized"} JSON return content after validation failure
UnauthorizedBackJson null Pre-serialized JSON response for AOT scenarios
UnauthorizedStatusCode 401 HTTP status code for unauthorized response
sToken CookieAuthorizationMiddleware Token used to sign cookie values
CookieName SignAuthorization Cookie name
CookieSeparator Separator for cookie values
Expire 3600 Cookie expiration time (unit: seconds)
ReuseExpire true Refresh cookie timestamp on successful validation
CookieOptions HttpOnly/IsEssential set Cookie options to use when refreshing
UserNameClaimType ClaimTypes.Name Claim type for user name
UserNameItemKey SignAuthorizationUserName Key for storing user name in HttpContext.Items
AllowedUsers empty Allowed user list (empty for no restriction)
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 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 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.
  • net9.0

    • No dependencies.

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.2.0 90 2/4/2026
2.1.0 86 2/3/2026
1.1.0 238 4/26/2024
1.0.6 218 1/20/2024
1.0.5 289 11/15/2023
1.0.4 204 10/31/2023
1.0.2 355 8/29/2022
1.0.1 340 8/29/2022
1.0.0 344 8/29/2022