Skip to content

joelbyford/BasicAuth

Repository files navigation

PR Harness Bash Test

BasicAuth

A library which includes a dotnet Basic Authentication middleware component which can be added to dotnet web and API apps on Azure to enable classic/old RFC 2617 Basic Authentication. Please note, Basic Auth is one of the oldest forms of web authentication and is not known for being the most secure. Use and implement at your own risk and only over HTTPS/TLS to prevent sending user names and passwords unencrypted over the Internet.

Changelog

  • See CHANGELOG.md for review history and recorded security findings.

Security Requirements

  • Use HTTPS/TLS only. This middleware rejects non-HTTPS requests.
  • Do not store credentials directly in source code.
  • Add host-level rate limiting and monitoring for internet-facing workloads.
  • Prefer modern auth (OIDC/OAuth/JWT) for public-facing production apps where possible.

Install - Leveraging NuGet Package

Assuming you would like to add the library to your project via a NuGet package, the following are the steps required:

  1. Have an existing dotnet webapp or dotnet apiapp created (if starting from scratch, simply type dotnet new webapp --name "myWebApp" to create a new one).
  2. From the command line change the directory the the directory with a .csproj file in it (cd myWebApp in the example above).
  3. Add the package to your project by typing dotnet add package joelbyford.BasicAuth.
  4. Modify your code startup code as appropriate (see later in this readme).

Install - Leveraging Source Code

If you would rather use the raw source code, just copy the BasicAuth.cs file into your existing project instead.

Code Modifications

Once installed, to use the library, simply modify the Configure method in your startup.cs to call the library in any one of two ways:

Authorize a Single User

For simple use cases, this may satisfy your need. Source credentials from environment variables or a secret store.

using joelbyford;
using System;

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        ...
        string basicAuthRealm = "mywebsite.com";
        string basicAuthUser = Environment.GetEnvironmentVariable("BASIC_AUTH_USER");
        string basicAuthPass = Environment.GetEnvironmentVariable("BASIC_AUTH_PASS");
        app.UseMiddleware<joelbyford.BasicAuth>(basicAuthRealm, basicAuthUser, basicAuthPass);
    }

Authorize a Dictionary of Users

If you would like to control how and where you get the users and passwords from, this method is best (e.g. you are obtaining from a database or secure configuration source).

using joelbyford;
using System.IO;
using System.Collections.Generic;
using System.Text.Json;

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        ...
        Dictionary<string, string> myUsers = new Dictionary<string, string>();
        var packageJson = File.ReadAllText("authorizedUsers.secure.json");
        myUsers = JsonSerializer.Deserialize<Dictionary<string, string>>(packageJson);
        string basicAuthRealm = "mywebsite.com";
        app.UseMiddleware<joelbyford.BasicAuth>(basicAuthRealm, myUsers);
    }

In this example, credentials are loaded from a controlled configuration source. Avoid committing credential files to source control and rotate passwords regularly.

If you must use a local file for development, do not store production credentials in that file and exclude it from git.

Example format:

{    
    "testUser" : "testPassword",
    "devUser" : "devPassword"
}

This can of course be loaded in from a database call instead as long as users and passwords are loaded into a Dictionary<string, string>

To see an example of this in use, please see startup.cs in the https://github.com/joelbyford/CSVtoJSONcore repo.

Local Authentication Test Harness

To quickly verify middleware behavior (including a bogus endpoint auth check), a runnable sample is included at harness/BasicAuthHarness.

Run the harness:

dotnet run --project harness/BasicAuthHarness/BasicAuthHarness.csproj

In a second terminal, run the included curl test script:

powershell -ExecutionPolicy Bypass -File .\harness\BasicAuthHarness\testing\test-auth.ps1

Auth Test Scripts (PowerShell + Bash)

Both scripts validate the same 4 assertions:

  • Missing Authorization header -> 401
  • Invalid credentials -> 401
  • Valid credentials to POST /bogus -> 404
  • Valid credentials to GET /health -> 200

Each script prints PASS/FAIL for every assertion, then prints:

  • true if all assertions pass (process exit code 0)
  • false if any assertion fails (process exit code 1)

PowerShell usage:

powershell -ExecutionPolicy Bypass -File .\harness\BasicAuthHarness\testing\test-auth.ps1
powershell -ExecutionPolicy Bypass -File .\harness\BasicAuthHarness\testing\test-auth.ps1 "http://localhost:5057" "demoUser" "demoPass!123"

Bash usage:

bash harness/BasicAuthHarness/testing/test-auth.sh
bash harness/BasicAuthHarness/testing/test-auth.sh http://localhost:5057 demoUser demoPass!123

Parameter order for both scripts:

  1. BaseUrl
  2. User
  3. Pass

Alternatively you may call the tests via the REST Client VSCode plugin in the testing.http file.

Expected results:

  • Missing Authorization header -> 401 Unauthorized
  • Invalid credentials -> 401 Unauthorized
  • Valid credentials to POST /bogus -> 404 Not Found (auth passed, route missing)
  • Valid credentials to GET /health -> 200 OK

Note: The harness runs on HTTP for convenience and uses X-Forwarded-Proto: https in curl commands to simulate TLS termination at a reverse proxy.

Recommended Branch Protection Check

If you use GitHub branch protection for main, require the status check from this workflow:

  • Workflow: PR Harness Bash Test
  • Job/check name: harness-bash-test

In GitHub, go to Settings -> Branches -> Branch protection rules for main and add this check under Require status checks to pass before merging.

Test Usage of X-Forwarded-Proto: https

PLEASE NOTE this library allows the developer to use X-Forwarded-Proto: https in the API calls to ease development and testing in environments (like local workstations) that do not have SSL certificates installed. Do NOT use this in production as it will expose passwords in clear text without a secure SSL socket.

About

Allows adding RFC 2617 Basic Auth to Azure App Service

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors