Digest - mdaneri/Pode GitHub Wiki
Digest authentication allows secure user authentication without sending the password to the server. Instead, the client receives a challenge from the server and responds with a hash-based authentication response. The server then verifies the hash using the stored password as a secret key.
Pode's Digest Authentication is compliant with RFC 7616, ensuring compatibility with standard authentication mechanisms.
To configure Digest authentication in Pode, use the New-PodeAuthScheme -Digest function and pass it to Add-PodeAuth. The parameters supplied to the Add-PodeAuth function's ScriptBlock include the $username and a hashtable containing the authentication parameters extracted from the Authorization header:
Start-PodeServer {
New-PodeAuthScheme -Digest -Algorithm "SHA-256" -QualityOfProtection "auth-int" | Add-PodeAuth -Name 'Authenticate' -Sessionless -ScriptBlock {
param($username, $params)
# check if the user is valid
return @{ User = $user; Password = $password }
}
}Unlike other authentication methods, where only a user object is returned on success, Digest authentication requires returning the password (or hash) as a separate property. The password acts as the secret key to regenerate the client’s hash response for verification. Not returning the password results in an HTTP 401 Unauthorized challenge response.
Pode’s Digest authentication implementation adheres to RFC 7616, ensuring:
- Use of nonce-based challenge-response authentication
- Support for multiple hashing algorithms beyond MD5
- Support for Quality of Protection (QoP), including
authandauth-int - Correct formatting of WWW-Authenticate headers on authentication failure
!!! note SHA-384 is not part of RFC 7616 but has been added for consistency with other modern cryptographic algorithms and to provide additional security options.
Pode now supports multiple algorithms for Digest authentication. The -Algorithm parameter allows selecting one or more of the following:
MD5SHA-1SHA-256SHA-384SHA-512SHA-512/256
Pode automatically includes all supported algorithms in the WWW-Authenticate challenge header, allowing clients to select the strongest available option.
The -QualityOfProtection parameter (-qop) allows choosing between:
-
"auth"(authentication only) -
"auth-int"(authentication with message integrity protection)
If auth-int is used, the client includes a hash of the request body in the authentication response, ensuring the request content has not been altered.
By default, Pode checks if the request contains an Authorization header with the Digest scheme. The New-PodeAuthScheme -Digest function can be customized using the -HeaderTag parameter to modify the tag used in the request header. Pode also extracts all required parameters from the header, including the nonce, nonce count, and QoP options.
If the Authorization header is missing or invalid, Pode returns an HTTP 401 Unauthorized response with a WWW-Authenticate challenge.
The hashtable of parameters passed to the Add-PodeAuth function’s ScriptBlock includes the following:
| Parameter | Description |
|---|---|
cnonce |
A nonce value generated by the client. |
nc |
The count of times the client has used the server nonce. |
nonce |
A nonce value generated by the server. |
qop |
The quality of protection requested (auth or auth-int). |
realm |
The authentication realm from the server's challenge. |
response |
The hash generated by the client for authentication. |
uri |
The URI path that requires authentication. |
username |
The username provided for authentication. |
Digest authentication can be applied globally to all requests using Add-PodeAuthMiddleware or to specific routes via the -Authentication parameter.
To apply Digest authentication globally to all routes:
Start-PodeServer {
Add-PodeAuthMiddleware -Name 'GlobalAuthValidation' -Authentication 'Authenticate'
}To enforce Digest authentication only on specific routes:
Start-PodeServer {
Add-PodeRoute -Method Get -Path '/info' -Authentication 'Authenticate' -ScriptBlock {
# logic
}
}The following example sets up Digest authentication with SHA-256 and auth-int, validates a user, and applies authentication to a specific route:
Start-PodeServer {
Add-PodeEndpoint -Address * -Port 8080 -Protocol Http
# Setup Digest authentication with SHA-256 and auth-int
New-PodeAuthScheme -Digest -Algorithm "SHA-256" -QualityOfProtection "auth-int" | Add-PodeAuth -Name 'Authenticate' -Sessionless -ScriptBlock {
param($username, $params)
# Example user validation
if ($username -eq 'morty') {
return @{
User = @{
'ID' = 'M0R7Y302'
'Name' = 'Morty'
'Type' = 'Human'
}
Password = 'pickle'
}
}
# Authentication failed
return $null
}
# Protect the /cpu route with Digest authentication
Add-PodeRoute -Method Get -Path '/cpu' -Authentication 'Authenticate' -ScriptBlock {
Write-PodeJsonResponse -Value @{ 'cpu' = 82 }
}
# The /memory route is accessible without authentication
Add-PodeRoute -Method Get -Path '/memory' -ScriptBlock {
Write-PodeJsonResponse -Value @{ 'memory' = 14 }
}
}Windows' built-in Digest authentication has several critical limitations that restrict its compatibility with modern security practices:
- Limited to MD5: Windows does not support stronger hashing algorithms like SHA-256 or SHA-512.
-
No Support for
auth-int: Integrity protection (auth-int) is not available, making it less secure. -
Fails with Multiple Algorithms: If the
WWW-Authenticateheader lists multiple algorithms, Windows' built-in implementation fails to negotiate properly. - Lack of Algorithm Negotiation: Windows cannot automatically select the strongest supported algorithm from a list.
To bypass these Windows client limitations, Pode provides a custom client module that supports full RFC 7616-compliant Digest authentication. This module allows PowerShell scripts to authenticate using modern algorithms, multiple QoP modes, and cross-platform compatibility.
The client module is available under:
Import-Module ./examples/Authentication/Modules/Invoke-Digest.psm1By using this module, you can perform secure Digest authentication in PowerShell, even on Windows, without being restricted to MD5-only authentication.
The module includes the following functions:
A replacement for Invoke-WebRequest that supports Digest authentication.
Import-Module './examples/Authentication/Modules/Invoke-Digest.psm1'
# Define the URI and credentials
$uri = 'http://localhost:8081/users'
$username = 'morty'
$password = 'pickle'
# Convert the password to a SecureString and create a credential object
$securePassword = ConvertTo-SecureString $password -AsPlainText -Force
$credential = [System.Management.Automation.PSCredential]::new($username, $securePassword)
# Make a GET request using Digest authentication
$response = Invoke-WebRequestDigest -Uri $uri -Method 'GET' -Credential $credential
# Display response headers and content
$response.Headers | Format-List
Write-Output $response.ContentA replacement for Invoke-RestMethod that supports Digest authentication.
Import-Module './examples/Authentication/Modules/Invoke-Digest.psm1'
# Define the URI and credentials
$uri = 'http://localhost:8081/users'
$username = 'morty'
$password = 'pickle'
# Convert the password to a SecureString and create a credential object
$securePassword = ConvertTo-SecureString $password -AsPlainText -Force
$credential = [System.Management.Automation.PSCredential]::new($username, $securePassword)
# Make a GET request and automatically parse JSON response
$response = Invoke-RestMethodDigest -Uri $uri -Method 'GET' -Credential $credential
# Output the parsed response
$response