Skip to content

Allow client-credentials tokens without an estateId claim #625

Closed

Description

@StuartFerguson

A client-credentials token has no estateId claim, so the request is rejected before the header can be used. That matches the trace: Estate Reporting receives the header, then immediately returns 403.

The middleware should distinguish user tokens from client tokens:

  • User token: require estateId claim and verify it matches the header.
  • Client token: require a valid EstateId header and use that as the tenant context.
  • Ideally, also require the expected service scope/audience so arbitrary client tokens cannot select any estate.

Proposed implementation:

private async Task HandleAuthenticatedRequestAsync(
    HttpContext httpContext,
    EstateContext estateContext,
    Guid? headerEstateId)
{
    bool isUserToken = httpContext.User.HasClaim(
        claim => claim.Type == ClaimTypes.NameIdentifier);

    if (isUserToken)
    {
        string? estateClaim = httpContext.User.FindFirst("estateId")?.Value;

        if (!Guid.TryParse(estateClaim, out Guid authenticatedEstateId) ||
            authenticatedEstateId == Guid.Empty)
        {
            httpContext.Response.StatusCode = StatusCodes.Status403Forbidden;
            return;
        }

        if (headerEstateId.HasValue &&
            headerEstateId.Value != authenticatedEstateId)
        {
            httpContext.Response.StatusCode = StatusCodes.Status403Forbidden;
            return;
        }

        estateContext.SetEstate(authenticatedEstateId);
    }
    else
    {
        // Client-credentials token: tenant comes from the trusted ACL header.
        if (!headerEstateId.HasValue)
        {
            httpContext.Response.StatusCode = StatusCodes.Status403Forbidden;
            return;
        }

        estateContext.SetEstate(headerEstateId.Value);
    }

    await _next(httpContext);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions