• Hi AAM team,

    First of all, thank you for a great plugin. I’ve been successfully using AAM up through version 6.9.51 in a project that requires JWT authentication and extended token payloads.

    Specifically, I’m using the documented filter aam_jwt_claims_filter to include additional custom key/value pairs in the JWT token issued by AAM. This has worked perfectly until version 7.0.

    Here’s a simplified version of my working code (still in use with AAM 6.9.51):

    function cci_aam_extend_jwt_claims($claims)
    {
    if (!isset($claims['userId'])) {
    return $claims;
    }

    $family_id = cci_get_user_family_id($claims['userId']);

    if ($family_id) {
    return array_merge($claims, [
    'house' => cci_get_apartment_number($family_id) ?? '',
    'apartment_id' => cci_get_apartment_id($family_id) ?? '',
    'family_id' => $family_id,
    'customer_number' => cci_family_customer_number($family_id) ?? '',
    ]);
    }

    return $claims;
    }

    add_filter('aam_jwt_claims_filter', 'cci_aam_extend_jwt_claims');

    When using AAM version 6.9.51, all of these claims (house, apartment_id, family_id, customer_number) are properly included in the generated JWT.

    However, after upgrading to AAM 7.0 or later, the filter is still called, and my custom claims are correctly added to the $claims array — but they no longer appear in the final JWT token payload. Only the default claims such as user_id, iat, exp, and iss remain.

    I’ve reviewed the plugin code and noticed that in newer versions, the token payload is filtered through a filterClaims() method (possibly inside JWTService), which appears to whitelist only specific keys. This internal filtering seems to override or discard custom claims added via the aam_jwt_claims_filter — even though your documentation still states that custom claims will be included.

    Can you please clarify:

    1. Is this change in behavior intentional?
    2. Is there an officially supported way to include custom claims again in AAM 7+?
    3. If so, is aam.jwt.claims.whitelist still supported (and if yes, how should it be used)?

    I’d prefer not to fork the plugin or create my own JWT issuing logic if it can be avoided.

    Thanks again for your work — I’m hoping for a clarification or a roadmap item that might help plugin developers like myself continue to use AAM’s JWT support with custom claims.

    Best regards,
    Torben 

Viewing 6 replies - 1 through 6 (of 6 total)
  • Plugin Support Vasyl Martyniuk

    (@mvb_wordpress)

    @tohevi thank you for the report. Likely the issue is with:

    if (!isset($claims['userId'])) {        return $claims;    }

    To standardize props, the userId now is user_id.

    Give a try and keep us posted.

    Thread Starter Torben Heikel Vinther

    (@tohevi)

    Hi @mvb_wordpress

    Thanks a lot for your quick reply and suggestion.

    Unfortunately, changing from userId to user_id didn’t solve the issue on its own. I updated the code to the following for compatibility:

    $user_id = $claims['user_id'] ?? $claims['userId'] ?? null;
    if (!$user_id) {
    return $claims;
    }

    This ensures support for both older and newer AAM versions. However, the custom claims I’m adding (like house, apartment_id, etc.) are still not included in the final JWT when using AAM 7.0 or later. They work perfectly with AAM 6.9.51.

    Please let me know if there’s an officially supported way to include additional claims in the JWT in AAM 7+, or if the behavior has changed intentionally.

    Thanks again for your help – I appreciate it.

    Best regards,
    Torben 

    Thread Starter Torben Heikel Vinther

    (@tohevi)

    Hi @mvb_wordpress

    I just upgraded to version 7.0.4 but it didn’t solve the bug.

    Do you have any idea when you’ll be able to fix the issue?

    Best regards
    Torben

    Plugin Support Vasyl Martyniuk

    (@mvb_wordpress)

    @tohevi thank you for the follow up. I’ve tested custom filter functionality over and over again and can’t reproduce an issue. My best guess is that you register aam_jwt_claims_filter filter likely after the token is issued. Here is what I’ve done to test it.

    #1. Created a custom plugin to test the filter:

    <?php

    /**

    * Plugin Name: AAM Test Bug

    * Description: Just a playground for any functionality that is related to AAM

    * Version: 1.0.0

    * Author: Vasyl Martyniuk <vasyl@vasyltech.com>

    * Author URI: https://vasyltech.com

    *

    * -------

    * LICENSE: This file is subject to the terms and conditions defined in

    * file 'LICENSE', which is part of AAM Protected Media Files source package.

    **/

    if (defined('ABSPATH')) {

    function cci_aam_extend_jwt_claims($claims) {

    return array_merge($claims, [

    'house' => 'house',

    'apartment_id' => 'apartment_id',

    'family_id' => 'family_id',

    'customer_number' => 'custom_number',

    ]);

    }

    add_filter('aam_jwt_claims_filter', 'cci_aam_extend_jwt_claims');

    }

    Issued a token with AAM UI and custom claims are in the token:

    {
    "jti": "a8fc8b70-8b46-476b-882d-ae3a29d9acfd",
    "revocable": true,
    "refreshable": false,
    "house": "house",
    "apartment_id": "apartment_id",
    "family_id": "family_id",
    "customer_number": "custom_number",
    "iat": 1749427205,
    "iss": "http://demo.local",
    "exp": 1751068802,
    "user_id": 1
    }
    Thread Starter Torben Heikel Vinther

    (@tohevi)

    Hi @mvb_wordpress

    Thanks again for taking the time to test this thoroughly and share your setup.

    That helps clarify things, and it confirms that the filter itself still works as intended — under the right circumstances.

    In my case, I’m issuing the token via the REST API endpoint wp-json/aam/v2/authenticate, and my plugin hooks into the aam_jwt_claims_filter like this:

    add_filter('aam_jwt_claims_filter', 'cci_aam_extend_jwt_claims');

    function cci_aam_extend_jwt_claims($claims)
    {
    $user_id = $claims['user_id'] ?? $claims['userId'] ?? null;
    if (!$user_id) {
    return $claims;
    }

    $family_id = cci_get_user_family_id($user_id);
    if ($family_id) {
    return array_merge($claims, [
    'house' => cci_get_apartment_number($family_id) ?? '',
    'apartment_id' => cci_get_apartment_id($family_id) ?? '',
    'family_id' => $family_id,
    'customer_number' => cci_family_customer_number($family_id) ?? '',
    ]);
    }

    return $claims;
    }

    The exact same code works perfectly when using AAM 6.9.51, but in version 7.x, the additional claims don’t appear in the token.

    Based on your note, I now suspect that the filter may not be hooked early enough when using the /aam/v2/authenticate endpoint. Would you happen to know the right timing or action hook to guarantee the filter is registered before the token is generated on that route?

    Thanks again — I really appreciate your support and the transparency of your process.

    Best regards,
    Torben

    Thread Starter Torben Heikel Vinther

    (@tohevi)

    Hi again Vasyl,

    Thank you very much for taking the time to investigate and provide guidance.

    After further debugging and reviewing how the aam_jwt_claims_filter behaves in AAM 7.x, I discovered that the root of the issue was a change in when the filter is executed. In AAM 6.x, the filter received a full claims array that included userId, making it easy to enrich the token. However, in AAM 7.x, the filter is triggered earlier in the process — before standard JWT claims (like user_id) are added — which means there’s no user context available when the filter runs.

    This timing change broke my existing implementation because it relied on accessing the user ID directly from the claims array.

    To fix this, I implemented a workaround where I store the user context during the login process (via wp_login), and then retrieve it inside the filter if the ID isn’t already available in the claims array. This allowed me to restore the ability to add custom claims like house, apartment_id, family_id, and customer_number — and have them show up correctly in the final JWT token.

    Thanks again for your help — and for continuing to maintain such a powerful plugin!

    Best regards,

    Torben Heikel Vinther

Viewing 6 replies - 1 through 6 (of 6 total)

The topic ‘aam_jwt_claims_filter no longer works as expected’ is closed to new replies.