Digest
Digest authentication lets you authenticate a user without actually sending the password to the server. Instead the a request is made to the server, and a challenge issued back for credentials. The authentication is then done by comparing hashes generated by the client and server using the user's password as a secret key.
Setup
To setup and start using Digest authentication in Pode you use the New-PodeAuthScheme -Digest
function, and then pipe this into the Add-PodeAuth
function. The parameters supplied to the Add-PodeAuth
function's ScriptBlock are the $username
, and a HashTable containing the parameters from the Authorization header:
Start-PodeServer {
New-PodeAuthScheme -Digest | Add-PodeAuth -Name 'Authenticate' -Sessionless -ScriptBlock {
param($username, $params)
# check if the user is valid
return @{ User = $user; Password = $password }
}
}
Unlike other forms of authentication where you only need return the User on success. Digest requires you to also return the Password of the user as a separate property. This password is what is used as the secret key to generate the client's response hash, and allows the server to re-generate the hash for validation. (Not returning the password will result in an HTTP 401 challenge response).
By default, Pode will check if the Request's header contains an Authorization
key, and whether the value of that key starts with Digest
tag. The New-PodeAuthScheme -Digest
function can be supplied parameters to customise the tag using -HeaderTag
. Pode will also gather the rest of the parameters in the header such as the Nonce, NonceCount, etc. An HTTP 401 challenge will be sent back if the Authorization header is invalid.
The HashTable of parameters sent to the Add-PodeAuth
function's ScriptBlock are the following:
Parameter | Description |
---|---|
cnonce | A nonce value generated by the client |
nc | The count of time the client has used the server nonce |
nonce | A nonce value generated by the server |
qop | Fixed to 'auth' |
realm | The realm description from the server's HTTP 401 challenge |
response | The generated hash value of all these parameters from the client |
uri | The URI path that needs authentication |
username | The username of the user that needs authenticating |
Middleware
Once configured you can start using Digest authentication to validate incoming Requests. You can either configure the validation to happen on every Route as global Middleware, or as custom Route Middleware.
The following will use Digest authentication to validate every request on every Route:
Start-PodeServer {
Add-PodeAuthMiddleware -Name 'GlobalAuthValidation' -Authentication 'Authenticate'
}
Whereas the following example will use Digest authentication to only validate requests on specific a Route:
Start-PodeServer {
Add-PodeRoute -Method Get -Path '/info' -Authentication 'Authenticate' -ScriptBlock {
# logic
}
}
Full Example
The following full example of Digest authentication will setup and configure authentication, validate that a user's username is valid, and then validate on a specific Route:
Start-PodeServer {
Add-PodeEndpoint -Address * -Port 8080 -Protocol Http
# setup digest authentication to validate a user
New-PodeAuthScheme -Digest | Add-PodeAuth -Name 'Authenticate' -Sessionless -ScriptBlock {
param($username, $params)
# here you'd check a real user storage, this is just for example
if ($username -eq 'morty') {
return @{
User = @{
'ID' ='M0R7Y302'
'Name' = 'Morty';
'Type' = 'Human';
}
Password = 'pickle'
}
}
# authentication failed
return $null
}
# check the request on this route against the authentication
Add-PodeRoute -Method Get -Path '/cpu' -Authentication 'Authenticate' -ScriptBlock {
Write-PodeJsonResponse -Value @{ 'cpu' = 82 }
}
# this route will not be validated against the authentication
Add-PodeRoute -Method Get -Path '/memory' -ScriptBlock {
Write-PodeJsonResponse -Value @{ 'memory' = 14 }
}
}