FusionAuth
    • Home
    • Categories
    • Recent
    • Popular
    • Pricing
    • Contact us
    • Docs
    • Login

    Lambda reconcile does not remove role from registration

    Scheduled Pinned Locked Moved
    Q&A
    azure lambda oidc reconcile registration
    0
    12
    5.2k
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • T
      tl+fa
      last edited by tl+fa

      Lambda reconcile with Azure AD OIDC

      I have set up an azure application like described here. To match the group-ids on azure to our application-specific roles, I set up a reconcile lamba (as the jwt-populate lambda is not available while on oidc), which is as follows:

      function reconcile(user, registration, jwt) {
        //groupId matching
        var admin = 'd166c6a0-...';
        var superuser = '738d97af-...';
        var viewer = '8932d06f-...';
      
        //azure groups are like this
        // "groups": [["d166c6a0-..."]];
        var groupsAzure = JSON.parse(jwt.groups);
      
        registration.roles = [];
      
        user.email = jwt.upn;
        if(Array.isArray(groupsAzure)){
          groupsAzure.forEach(function(groups){      						
            if(groups === admin){
              registration.roles.push('admin', 'superuser', 'viewer');
            }
            if(groups === superuser){
              console.info('superuser!!!!');
              registration.roles.push('superuser', 'viewer');
            }
            if(groups === viewer){
              console.info('viewer!!!!');
              registration.roles.push('viewer');
            }
      
          });
        }
      }
      

      This works perfectly fine (only for testing!) If I login with a "viewer" user, the registration gets the right rule. If I "upgrade" the "viewer" with "admin" permissions, this is also updated in the registration.
      But if I "downgrade" a user while removing him from the admin group, the lambda does not update the registration roles.
      Do I miss something? Currently using 1.15.2. Thanks a lot!

      1 Reply Last reply Reply Quote 0
      • joshuaJ
        joshua
        last edited by

        Hi @tl-fa,

        Were you able to figure this out? If not, I can review the tutorial that you are working through to see if I have any thoughts.

        Thanks,
        Josh

        1 Reply Last reply Reply Quote 0
        • T
          tl+fa
          last edited by

          Hi Josh,
          I was not yet able to get this done. The problem still is, that the assignment of registration rules inside the reconcile lambda. Your help is greatly appreciated.

          Thanks a lot,
          Thomas

          joshuaJ 1 Reply Last reply Reply Quote 0
          • joshuaJ
            joshua @tl+fa
            last edited by

            Hi @tl-fa,

            After discussing this issue, there are three troubleshooting strategies for you to consider:

            1. Add debugging statements
              -- Add console log statements just preceding and immediately following any time registration.roles array changes.
              -- Any other location you can think of to confirm assumptions vs actual behavior
            2. Decouple the Azure OIDC protocol
              -- Reproducing the same lambda/js code but using a different OIDC partner/choice would confirm it is not Azure AD creating the issue.
              -- Obviously, this is extra lifting codewise, but could prove illuminating and would be confirming.
            3. Change the order of your roles
              -- Confirm that if you were to reverse the roles on different groups, you have the opposite behavior
              -- For instance, if you were to push admin, superuser, and viewer on to groups.user (and so forth) would things act incorrectly on the 'upgrade' but work correctly on the downgrade (as seen in the current example provided).
              -- All this would be in an attempt to confirm the actual behavior of the Array. Is it resetting correctly upon initialization? Is it getting roles added as we would expect in the array and removed as expected?

            We could certainly troubleshoot more in-depth if you had a support contract so please do let us know if this is something you would need (i.e. - if you are running in production at scale). I hope this gives you something more to go on.

            Thanks,
            Josh

            T 1 Reply Last reply Reply Quote 0
            • T
              tl+fa @joshua
              last edited by

              @joshua Thank you very much for your effort. I will try to put some more light on this!

              Thanks again,
              Thomas

              1 Reply Last reply Reply Quote 0
              • robotdanR
                robotdan
                last edited by

                @tl-fa said in Lambda reconcile does not remove role from registration:

                registration.roles

                In your example, are you trying to modify roles for a FusionAuth admin user (roles that apply when logging into the FusionAuth admin UI) or is this for your application?

                For reference, if you are trying to modify roles for the FusionAuth admin UI (FusionAuth registration), the roles are documented here. https://fusionauth.io/docs/v1/tech/core-concepts/roles/#fusionauth-application-roles

                T 1 Reply Last reply Reply Quote 0
                • T
                  tl+fa @robotdan
                  last edited by tl+fa

                  Hi @robotdan
                  Actually these are roles belonging to my application. I have some more debug informations:
                  Downgrade Flow:
                  User on FusionAuth with roles [admin,superuser,viewer]:
                  f410c3a2-65e3-42b9-b69f-04bd56e3cf25-image.png

                  User on Azure:
                  362ed938-503c-46c8-856b-d6d991287ba2-image.png

                  Lambda invocation result.

                  
                  --- jwt ---
                  {
                    "sub": "5SS_....",
                    "amr": "[\"pwd\"]",
                    "ipaddr": "......",
                    "name": "reader",
                    "oid": "2c5cccd....,
                    "rh": "0.ATsA112D...",
                    "tid": "b9835dd7....."
                    "unique_name": "reader@...onmicrosoft.com",
                    "upn": "reader@......onmicrosoft.com",
                    "uti": "LR1UTJ...",
                    "ver": "1.0",
                    "groups": [
                      "[\"8932d06f-eeb0-444f-a8d8-0c7c9972e311\"]"
                    ]
                  }
                  --- registration ---
                  {
                    "applicationId": "9d63587b-e17c-4af0-989f-9b965ba94a60",
                    "tokens": {
                      "7c8a26f1....": "0.ATsA11..."
                    },
                    "verified": false
                  }
                  --- user ---
                  {
                    "active": false,
                    "fullName": "reader",
                    "passwordChangeRequired": false,
                    "twoFactorEnabled": false,
                    "verified": false
                  }
                  --- azure groups  ---
                  8932d06f-eeb0-444f-a8d8-0c7c9972e311
                  mapped group is -> viewer
                  --- registration after assignement ---
                  {
                    "applicationId": "9d63587b-e17c-4af0-989f-9b965ba94a60",
                    "tokens": {
                      "7c8a2..": "0.ATsA.."
                    },
                    "verified": false,
                    "roles": [
                      "viewer"
                    ]
                  }
                  --- user after assignement ---
                  {
                    "active": false,
                    "fullName": "reader",
                    "passwordChangeRequired": false,
                    "twoFactorEnabled": false,
                    "verified": false,
                    "email": "reader@....onmicrosoft.com"
                  }
                  
                  

                  The lambda as follows

                  // Using the JWT returned from UserInfo, reconcile the User and User Registration.
                  function reconcile(user, registration, jwt) {
                   console.info('--- jwt ---');
                     console.info(JSON.stringify(jwt, null, 2));
                   console.info('--- registration ---');
                   console.info(JSON.stringify(registration, null, 2));
                   console.info('--- user ---');
                     console.info(JSON.stringify(user, null, 2));
                  
                   //groupId matching
                     var admin = 'd166c6a0-bdd0-4649-b596-0b5ce2c58b49';
                   var superuser = '738d97af-f058-4eb3-b3d5-ddbf84df20f9';
                   var viewer = '8932d06f-eeb0-444f-a8d8-0c7c9972e311';
                   
                     var groupsAzure = JSON.parse(jwt.groups);
                   console.info('--- azure groups  ---');
                   console.info(groupsAzure);
                   
                   
                   registration.roles = [];
                   
                   user.email = jwt.upn;
                     if(Array.isArray(groupsAzure)){
                     	groupsAzure.every(function(groups){
                       if(groups === admin){
                         console.info('mapped group is -> admin');
                         registration.roles.push('admin', 'superuser', 'viewer');
                         return false;
                       }
                       if(groups === superuser){
                         console.info('mapped group is -> superuser');
                         registration.roles.push('superuser', 'viewer');
                         return false;
                       }
                       if(groups === viewer){
                         console.info('mapped group is -> viewer');
                         registration.roles.push('viewer');
                         return false;
                       }
                  
                     });
                     }
                   console.info('--- registration after assignement ---');
                   console.info(JSON.stringify(registration, null, 2));
                   console.info('--- user after assignement ---');
                     console.info(JSON.stringify(user, null, 2));
                  }
                  

                  the payload of the jwt issued by FushionAuth to the application:

                  {
                    "aud": "9d63587b-e17c-4af0-989f-9b965ba94a60",
                    "exp": 1620055251,
                    "iat": 1620051651,
                    "iss": "https://fusionauth....",
                    "sub": "0b867bd9-ffbd-4dd8-a275-f663143c7a70",
                    "authenticationType": "OPENID_CONNECT",
                    "email": "reader@...onmicrosoft.com",
                    "email_verified": true,
                    "at_hash": "0MKgnKThS_tyAK460tE_Ng",
                    "c_hash": "uSQ7YGhENpZyfTg-iiipWg",
                    "applicationId": "9d63587b-...",
                    "roles": [
                      "admin",
                      "superuser",
                      "viewer"
                    ]
                  }
                  

                  The issued jwt from fusionauth still contains the all three roles as before the "downgrade". So it seems that the lambda assignment

                  registration.roles.push('viewer');
                  

                  does not work as expected..

                  1 Reply Last reply Reply Quote 0
                  • robotdanR
                    robotdan
                    last edited by

                    To confirm, you are doing something like this:

                    registration.roles = [];
                    registration.roles.push('viewer');
                    

                    And then the resulting registration contains the previous roles + viewer? And you are expecting a single role of viewer?

                    T 1 Reply Last reply Reply Quote 0
                    • T
                      tl+fa @robotdan
                      last edited by

                      No, only the previous roles (as they already include the viewer role). Yes, I am expecting a single role of viewer.

                      If I change the previous roles of the user to superuser and developer (on FA) the resulting set of roles after the lambda is superuser, developer and viewer. So there is an additional role of viewer, but the previous two roles remain.

                      1 Reply Last reply Reply Quote 0
                      • robotdanR
                        robotdan
                        last edited by

                        Hmm... this is likely a JSON merge issue. See linked issues below.

                        We Marshall objects back and forth from the JS engine via JSON and I the root issue here is likely that JSON merge does not handle arrays.

                        We could fix this by turning off merge for this field, or we will be updating > Java 14 shortly which means we have to ditch Nashorn, so it is possible this new JS engine will allow us to directly manipulate the registration object and ditch the JSON conversation.

                        Related issues:
                        https://github.com/FusionAuth/fusionauth-issues/issues/441
                        https://github.com/FusionAuth/fusionauth-issues/issues/571
                        https://github.com/FusionAuth/fusionauth-issues/issues/667

                        1 Reply Last reply Reply Quote 1
                        • T
                          tl+fa
                          last edited by

                          Happy to hear that! Any solution is welcome for me, when implemented, I will retest the case. Can you already shout out a date?

                          Cheers,
                          Thomas

                          1 Reply Last reply Reply Quote 0
                          • joshuaJ
                            joshua
                            last edited by

                            Hi @tl-fa,

                            You can view our Roadmap Guidance regarding how features are implemented into FusionAuth. A good snapshot of current development can be found here as well.

                            We will certainly update any related issue cards as development moves forward!

                            Thanks!
                            Josh

                            1 Reply Last reply Reply Quote 0
                            • First post
                              Last post