Error Handlers

Error Handlers are responsible for execution of logic if any of the authenticators, authorizers, contextualizers or unifiers fails. The error handler mechanisms range from a simple error response to the client which sent the request to sophisticated ones, supporting complex logic and redirects.

Error Handler Types

The following sections describe the available error handler types in more detail. Some of these may support or require additional configuration. The corresponding properties are annotated with mandatory, respectively optional to denote configuration requirement, as well as with overridable, not overriddable and partially overridable to indicate whether the property can be overridden in a rule pipeline.

Default

This mechanism is always there and is executed if no other error handler mechanism is responsible for the error. Actually, there is no need to explicitly configure it. The only exception is to allow overriding the default rule’s error handler chain in a specific rule for performance reasons (if configured error handlers in the default rule should not be considered). This mechanism type doesn’t have any configuration options.

To enable the usage of this mechanism, you have to set the type property to default.

Example 1. Configuring Default error handler to enable referencing it from rules
id: foo
type: default

Redirect

This error handler mechanism allows redirecting the client to another endpoint, e.g. to let the user authenticate. Technically this error handler returns e.g. a HTTP 302 Found response code and sets the HTTP Location header.

To enable the usage of this mechanism, you have to set the type property to redirect.

Configuration using the config property is mandatory. Following properties are available:

  • to: URL (mandatory, not overridable)

    The url to redirect the client to via the Location header. Can be templated and has access to the Request object.

    When creating query parameters by making use of templates, don’t forget to encode the values using the urlenc function. See also examples below.
  • code: int (optional, not overridable)

    The code to be used for the redirect. Defaults to 302 Found.

    Heimdall does not check the configured code for HTTP redirect validity!
  • when: Error Condition array (mandatory, overridable)

    Conditions, which must hold true for this error handler to execute. The defined conditions are evaluated using a boolean or. So at least one of the defined conditions must evaluate to true to have this error handler executed.

Example 2. Redirect error handler configuration

The redirect error handler below is configured to kick in if either

  • the first error condition evaluates to true. This condition is for web requests (HTTP Accept header contains text/html) if an authentication_error error occurred (an error raised by authenticators). In this case, it will redirect the client (for web requests, usually a browser) to http://127.0.0.1:4433/self-service/login/browser and also add the return_to query parameter set to the URL encoded value of the current url.

  • Or, if the second condition evaluates to true. The only difference to the previous one is the error type, which is authorization_error in this case.

So, e.g. if Heimdall was handling the request for http://my-service.local/foo and run into an error like described above, the value of the HTTP Location header will be set to http://127.0.0.1:4433/self-service/login/browser?return_to=http%3A%2F%2Fmy-service.local%2Ffoo

id: authenticate_with_kratos
type: redirect
config:
  to: http://127.0.0.1:4433/self-service/login/browser?return_to={{ .Request.URL | urlenc }}
  when:
    - error:
        - type: authentication_error
      request_headers:
        Accept:
          - text/html
    - error:
        - type: authorization_error
      request_headers:
        Accept:
          - text/html

In this case the error condition can actually be simplified, so the mechanism configuration can look like this:

id: authenticate_with_kratos
type: redirect
config:
  to: http://127.0.0.1:4433/self-service/login/browser?return_to={{ .Request.URL | urlenc }}
  when:
    - error:
        - type: authentication_error
        - type: authorization_error
      request_headers:
        Accept:
          - text/html

WWW-Authenticate

This error handler mechanism responds with HTTP 401 Unauthorized and a WWW-Authenticate HTTP header set. As of now, this error handler is the only one error handler, which transforms heimdall into an authentication system, a very simple one though ;). By configuring this error handler you can implement the Basic HTTP Authentication Scheme by also making use of the Basic Auth authenticator. Without that authenticator, the usage of this error handler does actually not make any sense.

To enable the usage of this error handler, you have to set the type property to www_authenticate.

Configuration using the config property is mandatory. Following properties are available:

  • realm: string (optional, overridable)

    The "realm" according to RFC 7235, section 2.2. Defaults to "Please authenticate".

  • when: Error Condition array (mandatory, overridable)

    Conditions, which must hold true for this error handler to execute. The defined conditions are evaluated using a boolean or. So at least one of the defined conditions must evaluate to true to have this error handler executed.

Example 3. Configuration of WWW-Authenticate error handler

The www authenticate error handler below is configured to kick in for web requests (HTTP Accept header contains text/html) if an authentication_error error occurred (an error raised by authenticators) and has been raised by an authenticator with id equal to basic_auth_authenticator. In this case, it will respond with HTTP 401 Unauthorized and a WWW-Authenticate header set to Basic realm="My fancy app".

id: basic_authenticate
type: www_authenticate
config:
  realm: "My fancy app"
  when:
    - error:
        - type: authentication_error
          raised_by: basic_auth_authenticator
      request_headers:
        Accept:
          - text/html

Last updated on Apr 17, 2023