Error “Client assertion is invalid” in OAuth Token Exchange with Telia using private_key_jwt

I am working on integrating Telia’s OAuth service in a WordPress plugin and am stuck with an error during the token exchange process. Although the authentication process is completed successfully, I cannot exchange the authorization code for tokens due to a “Client assertion is invalid” error.

I’m using Firebase JWT library https://github.com/firebase/php-jwt

//Requiring jtw-php 

require_once plugin_dir_path(__FILE__) . 'php-jwt-main/src/JWT.php';
require_once plugin_dir_path(__FILE__) . 'php-jwt-main/src/Key.php';


use FirebaseJWTJWT;
use FirebaseJWTKey;
// generating the JWT and send it to Telia's token endpoint

function exchange_code_for_tokens($authorization_code) {
    error_log("Starting token exchange process.");

    $jwt_payload = [
        'iss' => CLIENT_ID,
        'sub' => CLIENT_ID,
        'aud' => "https://example.com/uas",
        'iat' => time(),
        'exp' => time() + 300,
        'jti' => bin2hex(random_bytes(16))
    ];

    error_log("JWT Payload: " . json_encode($jwt_payload));

    $client_assertion = JWT::encode($jwt_payload, PRIVATE_KEY, 'RS256');
    error_log("Client Assertion: " . $client_assertion);

    $post_data = [
        'grant_type' => 'authorization_code',
        'client_id' => CLIENT_ID,
        'client_assertion_type' => 'urn:ietf:params:oauth:client-assertion-type:jwt-bearer',
        'client_assertion' => $client_assertion,
        'code' => $authorization_code,
        'redirect_uri' => REDIRECT_URI
    ];

    $response = wp_remote_post(TOKEN_ENDPOINT, [
        'body' => http_build_query($post_data),
        'headers' => [
            'Content-Type' => 'application/x-www-form-urlencoded',
        ]
    ]);

    $body = wp_remote_retrieve_body($response);
    $response_data = json_decode($body, true);

    if (isset($response_data['error'])) {
        error_log("Error retrieving tokens: " . $response_data['error_description']);
        error_log("Full error response: " . json_encode($response_data));
        return null;
    } else {
        error_log("Tokens retrieved successfully.");
        return $response_data;
    }
}
// handling the callback from Telia's auth service

add_action('init', function () {
    if (isset($_GET['code'])) {
        $authorization_code = sanitize_text_field($_GET['code']);
        $tokens = exchange_code_for_tokens($authorization_code);
        if ($tokens) {
            error_log("Tokens retrieved successfully.");
        } else {
            error_log("Failed to retrieve tokens.");
        }
    }
});

The logs I’m getting after success Authentication

Client Assertion: xxxx

JWT Payload: {
  "iss": "d1245979-f61b-7c1b-b31e-3332204160c3",
  "sub": "d7986979-f89b-4c1b-b31e-9423404160c3",
  "aud": "https://example.com/uas",
  "iat": 1723117411,
  "exp": 1723117711,
  "jti": "d3d4a5927cc3f419386e57d13111c80f"
}

Error retrieving tokens: Client assertion is invalid
Full error response: {"error_description":"Client assertion is invalid","error":"invalid_client"}
Failed to retrieve tokens.

Here’s some general Information from Telia integration guide:

Token Request:

  • Token requests are made to the token endpoint.

  • Client authentication is performed using private_key_jwt.

  • Include client_assertion parameter, which is a JWT signed with the RS256 algorithm using the client’s private key.

  • Public key should not restrict key usage because Telia will encrypt the ID token with this key.

  • Modulus n of the public key should be base64url encoded.

Required Parameters:

  • grant_type: Must be authorization_code.

  • redirect_uri: Same as used for the authorization request.

  • code: Authorization Code from the Authorization Response.

  • client_id: OAuth Client Identifier.

  • client_assertion_type: urn:ietf:params:oauth:client-assertion-type:jwt-bearer

  • client_assertion: Contains a signed JWT.

JWT Claims in client_assertion:

  • iss: Client ID

  • sub: Client ID

  • aud: https://example.com/uas

  • exp: Expiration time in UNIX epoch time (seconds since 1/1/1970), must not be more than 60 minutes into the future.

  • jti: JWT ID, used to enforce one-time use of JWTs.

jwt.io keys testing result “Signature Verified”

Contacting Telia
I ensured with Telia that the public key in their end is correct.
They asked to ensure I’m using the right private key to sign the request, which seems to be correct in my code.

I’ve ensured the client_assertion matches the requirements and the public key for the RS256 signing is correctly set up on Telia’s server. Any ideas on what might be going wrong?

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật