Skip to content

OAuth 2.0 & OIDC

The OAuth2 authentication lets you setup authentication with services that support OAuth 2.0.

To use this scheme, you'll need to supply an Authorise/Token URL, as well as setup a app registration to acquire a Client ID and Secret. There is also support for converting an OpenID Connect Discovery URL to a Pode OAuth2 scheme.

Setup

Before using the OAuth2 authentication in Pode, you first need to register a new app within your service of choice. This registration will supply you with the required Client ID and Secret (if you're using PKCE then the Client Secret is optional).

To setup and start using OAuth2 authentication in Pode you use New-PodeAuthScheme -OAuth2, and then pipe this into the Add-PodeAuth function.

Grant Types

Pode supports the grant types of authorization_code and password. By default OAuth2 will use the authorization_code grant type, which will require an -AuthoriseUrl and -RedirectUrl.

If you want to use the password grant type, and have users enter their credentials via a form or Basic authentication, then you'll need to supply an -InnerScheme type to New-PodeAuthScheme -OAuth2.

These types are described below.

Authorisation Code

This is the default grant type, and requires an -AuthoriseUrl to be supplied. A -RedirectUrl is also required, but if not supplied an default one will be setup internally.

You will need to supply the service's Authorise and Token URLs to New-PodeAuthScheme as below:

Start-PodeServer {
    $scheme = New-PodeAuthScheme `
        -OAuth2 `
        -ClientID '<clientId>' `
        -ClientSecret '<clientSecret>' `
        -AuthoriseUrl 'https://some-service.com/oauth2/authorize' `
        -TokenUrl 'https://some-service.com/oauth2/token'

    $scheme | Add-PodeAuth -Name 'Login' -FailureUrl '/login' -SuccessUrl '/' -ScriptBlock {
        param($user, $accessToken, $refreshToken, $response)

        # check if the user is valid

        return @{ User = $user }
    }
}

If you don't specify a -RedirectUrl, then an internal default one is created as /oauth2/callback on the first endpoint.

When a user accesses your site unauthenticated, they will be redirected to the service to login, and then redirected back to your site. Pode will supply to your Add-PodeAuth the user object (if available), and the access/refresh tokens, and the raw token response object.

You can optional specify a -UserUrl endpoint, if the service supports it, and Pode will use this to acquire user details. If one is not supplied then Pode will attempt to parse the id_token from the -AuthoriseUrl for the user details, otherwise the $user object supplied to Add-PodeAuth's ScriptBlock will be an basic hashtable:

@{
    Provider = 'OAuth2'
}

If you define a Login route, you don't need to set the -Login switch, due to the redirecting of OAuth2. A login route can be a simple route with no view defined:

Add-PodeRoute -Method Get -Path '/login' -Authentication Login

Password

Important

This flow will not work if 2FA is setup on accounts. In most cases, for some providers, you also need to explicitly enable this grant type.

Using this grant type allows you to support authentication in flows where redirecting is impossible - such as REST APIs using Basic authentication.

To use this grant type, you need to define another Scheme - such as Basic or Form - and then supply that Scheme to the -InnerScheme parameter of New-PodeAuthScheme -OAuth2. Pode will automatically switch to the password grant type.

Start-PodeServer {
    $form = New-PodeAuthScheme -Form

    $scheme = New-PodeAuthScheme `
        -OAuth2 `
        -ClientID '<clientId>' `
        -ClientSecret '<clientSecret>' `
        -TokenUrl 'https://some-service.com/oauth2/token' `
        -InnerScheme $form

    $scheme | Add-PodeAuth -Name 'Login' -FailureUrl '/login' -SuccessUrl '/' -ScriptBlock {
        param($user, $accessToken, $refreshToken, $response)

        # check if the user is valid

        return @{ User = $user }
    }
}

When using the password grant, an -AuthoriseUrl and -RedirectUrl are not required.

If you define a Login route, you define it in the usual way using the -Login switch, as OAuth2 won't be redirecting to the service to authenticate the user:

Add-PodeRoute -Method Get -Path '/login' -Authentication Login -Login -ScriptBlock {
    Write-PodeViewResponse -Path 'login' -FlashMessages
}

Add-PodeRoute -Method Post -Path '/login' -Authentication Login -Login

PKCE

Important

When using PKCE, you will need to enable the use of sessions in Pode.

If your app is setup as a "Single Page Application" then you'll be able to use PKCE in your OAuth2 requests. To enable Pode's OAuth2 authentication to use PKCE, supply the -UsePKCE switch:

Start-PodeServer {
    $scheme = New-PodeAuthScheme `
        -OAuth2 `
        -ClientID '<clientId>' `
        -AuthoriseUrl 'https://some-service.com/oauth2/authorize' `
        -TokenUrl 'https://some-service.com/oauth2/token' `
        -UsePKCE

    $scheme | Add-PodeAuth -Name 'Login' -FailureUrl '/login' -SuccessUrl '/' -ScriptBlock {
        param($user, $accessToken, $refreshToken, $response)

        # check if the user is valid

        return @{ User = $user }
    }
}

When using PKCE the -ClientSecret is optional, and doesn't need to be supplied.

Middleware

Once configured you can start using the OAuth2 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 Oauth2 Authentication to validate every request on every Route:

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

Whereas the following example will use Oauth2 Authentication to only validate requests on specific a Route:

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

OIDC Discovery

If the provider you're wanting to use OAuth2 for supports OpenID Connect Discovery, and has an appropriate /.well-known/openid-configuration endpoint, then you can use this with ConvertFrom-PodeOIDCDiscovery to automatically build a Pode OAuth2 scheme.

For example, if you were using Google OAuth2 with PKCE, then the following example would build an OAuth2 scheme:

$scheme = ConvertFrom-PodeOIDCDiscovery -Url 'https://accounts.google.com' -ClientId '<client_id>' -UsePKCE

$scheme | Add-PodeAuth -Name 'Login' -FailureUrl '/login' -SuccessUrl '/' -ScriptBlock {
    param($user, $accessToken, $refreshToken, $response)

    # check if the user is valid

    return @{ User = $user }
}

If the -Url supplied doesn't end with /.well-known/openid-configuration, then Pode will append it to the URL automatically.

Full Example

The following is an example of OAuth2 authentication usin the authorization_code grant type. This will setup and configure authentication, redirect a user to some service for validation, and then validate on a specific Route:

Start-PodeServer {
    Add-PodeEndpoint -Address * -Port 8080 -Protocol Http
    Set-PodeViewEngine -Type Pode

    # setup authentication to validate a user
    $scheme = New-PodeAuthScheme `
        -OAuth2 `
        -ClientID '<clientId>' `
        -ClientSecret '<clientSecret>' `
        -AuthoriseUrl 'https://some-service.com/oauth2/authorize' `
        -TokenUrl 'https://some-service.com/oauth2/token'

    $scheme | Add-PodeAuth -Name 'Login' -FailureUrl '/login' -SuccessUrl '/' -ScriptBlock {
        param($user, $accessToken, $refreshToken, $response)

        # check if the user is valid

        return @{ User = $user }
    }

    # home page:
    # redirects to login page if not authenticated
    Add-PodeRoute -Method Get -Path '/' -Authentication Login -ScriptBlock {
        Write-PodeViewResponse -Path 'home' -Data @{ Username = $WebEvent.Auth.User.name }
    }

    # login - this will just redirect to the service
    # NOTE: you do not need the -Login switch
    Add-PodeRoute -Method Get -Path '/login' -Authentication Login

    # logout
    Add-PodeRoute -Method Post -Path '/logout' -Authentication Login -Logout
}