Skip to content

Negotiate

Negotiate authentication lets you use Kerberos or NTLM authentication with an Active Directory (AD) server. This enables the use of, for example, -UseDefaultCredentials on Invoke-WebRequest and Invoke-RestMethod. The Negotiate authentication in Pode is built using the Kerberos.NET library.

Important

To use the Negotiate authentication you will require a valid keytab file, which can be generated using the ktpass command-line tool.

KeyTab

To generate the required keytab file, ensure that the ktpass command-line tool is available. Additionally, you must have a user account in the Active Directory (AD) your are configuring for Negotiate authentication

Once available, you can either generate a keytab using ktpass directly, such as:

# generates a pode.keytab file in the current directory
ktpass /princ HTTP/pode.example.com@example.com /mapuser example\pode-user /pass * /out pode.keytab /crypto all /ptype KRB5_NT_PRINCIPAL /mapop set

Or, you can use the simple helper New-PodeAuthKeyTab function in Pode - this does still call ktpass under the hood:

# generates a pode.keytab file in the current directory
New-PodeAuthKeyTab -Hostname 'pode.example.com' -DomainName 'example.com' -Username 'example\pode_user'

In both, the /princ or -Hostname should be the hostname that your Pode server endpoint is running as:

Add-PodeEndpoint -Address localhost -Port 8080 -Host 'pode.example.com' -Protocol Http

Note

In the above examples, ktpass will prompt for the user's password.

SPN

In most cases, ktpass will setup the relevant SPN for you. However, if you need to set this up, then an example of doing so is a follows using setspn:

setspn -A HTTP/pode.example.com example\pode-user

Setup

To use Negotiate authentication in Pode, after you've created a keytab file, you can use New-PodeAuthScheme and the pipe the result into Add-PodeAuth. The scriptblock for Add-PodeAuth will be supplied the ClaimsPrincipal object for the authenticated AD user:

$keytab = '.\pode.keytab'
New-PodeAuthScheme -Negotiate -KeytabPath $keytab | Add-PodeAuth -Name 'Login' -Sessionless -ScriptBlock {
    param($claim)

    # perform any optional additional validation on the claim
    # the user's name will be under $claim.Identity.Name

    return @{ User = $claim }
}

Middleware

Once configured you can start using Negotiate 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 Negotiate authentication to validate every request on every Route:

Start-PodeServer {
    Add-PodeAuthMiddleware -Name 'GlobalAuthValidation' -Authentication 'Login'
}

Whereas the following example will use Negotiate authentication to only validate requests on specific a Route:

Start-PodeServer {
    Add-PodeRoute -Method Get -Path '/info' -Authentication 'Login' -ScriptBlock {
        # logic
    }
}

Full Example

The following full example of Negotiate authentication will setup and configure authentication, and then validate on a specific Route:

Start-PodeServer -Threads 2 {
    Add-PodeEndpoint -Address localhost -Port 8080 -Host 'pode.example.com' -Protocol Http

    # setup negotiate authentication
    $keytab = '.\pode.keytab'
    New-PodeAuthScheme -Negotiate -KeytabPath $keytab | Add-PodeAuth -Name 'Login' -Sessionless -ScriptBlock {
        param($claim)
        return @{ User = $claim }
    }

    # check the request on this route against the authentication
    Add-PodeRoute -Method Get -Path '/cpu' -Authentication 'Login' -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 }
    }
}