freeradius 3.0.17 rlm_rest parsing json response












0















I'm trying to authenticate RADIUS Requests against a RESTful API (provided by Customer) using rlm_rest.



The problem I am facing is that
response JSON format (of REST API provided by Customer), is different from rlm_rest default format (indicated in etc/raddb/mods-enabled/rest).



My Virtual Server configuration as below:



Default



authorize {
...
...
rest
if (ok) {
update control {
Auth-Type := rest
}
}
}


mods-enabled/rest



authorize {
uri = "https://3rd-party-API/auth"
method = 'post'
body = 'json'
chunk = 0
tls = ${..tls}
data = '{
"code": 1,
"identifier": %I,
"avps": {
"User-Name": ["%{User-Name}"],
"NAS-IP-Address": ["%{NAS-IP-Address}"],
"Called-Station-Id": ["%{Called-Station-Id}"],
"Calling-Station-Id": ["%{Calling-Station-Id}"],
"NAS-Identifier": ["%{NAS-Identifier}"]
}
}'
}


Result



/sbin/radiusd -Xxx



HTTP response code



200


JSON Body



{
"code": "2",
"identifier": "91",
"avps": {
"Customer-Attributes": "Hello"
...
...
"Acct-Interim-Interval": "300"
}
}


The JSON structure is different from the example, and xlat parse
"code"
"identifier"
"avps"



And, of course, xlat finds no attributes match with the dictionary, while it cannot find "avps" and won't dig deeper.



So I was wondering is there anyway to either




  1. Define the response JSON structure for xlat to parsing

  2. Insert a "is_json" or "do_xlat" flag into the JSON ("avps"), and hope xlat will then dig deeper

  3. Save the JSON and parse with exec/rlm_exec (using JQ or any other bash/JSON tools)


Please advise if there is any workaround. Thanks!










share|improve this question



























    0















    I'm trying to authenticate RADIUS Requests against a RESTful API (provided by Customer) using rlm_rest.



    The problem I am facing is that
    response JSON format (of REST API provided by Customer), is different from rlm_rest default format (indicated in etc/raddb/mods-enabled/rest).



    My Virtual Server configuration as below:



    Default



    authorize {
    ...
    ...
    rest
    if (ok) {
    update control {
    Auth-Type := rest
    }
    }
    }


    mods-enabled/rest



    authorize {
    uri = "https://3rd-party-API/auth"
    method = 'post'
    body = 'json'
    chunk = 0
    tls = ${..tls}
    data = '{
    "code": 1,
    "identifier": %I,
    "avps": {
    "User-Name": ["%{User-Name}"],
    "NAS-IP-Address": ["%{NAS-IP-Address}"],
    "Called-Station-Id": ["%{Called-Station-Id}"],
    "Calling-Station-Id": ["%{Calling-Station-Id}"],
    "NAS-Identifier": ["%{NAS-Identifier}"]
    }
    }'
    }


    Result



    /sbin/radiusd -Xxx



    HTTP response code



    200


    JSON Body



    {
    "code": "2",
    "identifier": "91",
    "avps": {
    "Customer-Attributes": "Hello"
    ...
    ...
    "Acct-Interim-Interval": "300"
    }
    }


    The JSON structure is different from the example, and xlat parse
    "code"
    "identifier"
    "avps"



    And, of course, xlat finds no attributes match with the dictionary, while it cannot find "avps" and won't dig deeper.



    So I was wondering is there anyway to either




    1. Define the response JSON structure for xlat to parsing

    2. Insert a "is_json" or "do_xlat" flag into the JSON ("avps"), and hope xlat will then dig deeper

    3. Save the JSON and parse with exec/rlm_exec (using JQ or any other bash/JSON tools)


    Please advise if there is any workaround. Thanks!










    share|improve this question

























      0












      0








      0








      I'm trying to authenticate RADIUS Requests against a RESTful API (provided by Customer) using rlm_rest.



      The problem I am facing is that
      response JSON format (of REST API provided by Customer), is different from rlm_rest default format (indicated in etc/raddb/mods-enabled/rest).



      My Virtual Server configuration as below:



      Default



      authorize {
      ...
      ...
      rest
      if (ok) {
      update control {
      Auth-Type := rest
      }
      }
      }


      mods-enabled/rest



      authorize {
      uri = "https://3rd-party-API/auth"
      method = 'post'
      body = 'json'
      chunk = 0
      tls = ${..tls}
      data = '{
      "code": 1,
      "identifier": %I,
      "avps": {
      "User-Name": ["%{User-Name}"],
      "NAS-IP-Address": ["%{NAS-IP-Address}"],
      "Called-Station-Id": ["%{Called-Station-Id}"],
      "Calling-Station-Id": ["%{Calling-Station-Id}"],
      "NAS-Identifier": ["%{NAS-Identifier}"]
      }
      }'
      }


      Result



      /sbin/radiusd -Xxx



      HTTP response code



      200


      JSON Body



      {
      "code": "2",
      "identifier": "91",
      "avps": {
      "Customer-Attributes": "Hello"
      ...
      ...
      "Acct-Interim-Interval": "300"
      }
      }


      The JSON structure is different from the example, and xlat parse
      "code"
      "identifier"
      "avps"



      And, of course, xlat finds no attributes match with the dictionary, while it cannot find "avps" and won't dig deeper.



      So I was wondering is there anyway to either




      1. Define the response JSON structure for xlat to parsing

      2. Insert a "is_json" or "do_xlat" flag into the JSON ("avps"), and hope xlat will then dig deeper

      3. Save the JSON and parse with exec/rlm_exec (using JQ or any other bash/JSON tools)


      Please advise if there is any workaround. Thanks!










      share|improve this question














      I'm trying to authenticate RADIUS Requests against a RESTful API (provided by Customer) using rlm_rest.



      The problem I am facing is that
      response JSON format (of REST API provided by Customer), is different from rlm_rest default format (indicated in etc/raddb/mods-enabled/rest).



      My Virtual Server configuration as below:



      Default



      authorize {
      ...
      ...
      rest
      if (ok) {
      update control {
      Auth-Type := rest
      }
      }
      }


      mods-enabled/rest



      authorize {
      uri = "https://3rd-party-API/auth"
      method = 'post'
      body = 'json'
      chunk = 0
      tls = ${..tls}
      data = '{
      "code": 1,
      "identifier": %I,
      "avps": {
      "User-Name": ["%{User-Name}"],
      "NAS-IP-Address": ["%{NAS-IP-Address}"],
      "Called-Station-Id": ["%{Called-Station-Id}"],
      "Calling-Station-Id": ["%{Calling-Station-Id}"],
      "NAS-Identifier": ["%{NAS-Identifier}"]
      }
      }'
      }


      Result



      /sbin/radiusd -Xxx



      HTTP response code



      200


      JSON Body



      {
      "code": "2",
      "identifier": "91",
      "avps": {
      "Customer-Attributes": "Hello"
      ...
      ...
      "Acct-Interim-Interval": "300"
      }
      }


      The JSON structure is different from the example, and xlat parse
      "code"
      "identifier"
      "avps"



      And, of course, xlat finds no attributes match with the dictionary, while it cannot find "avps" and won't dig deeper.



      So I was wondering is there anyway to either




      1. Define the response JSON structure for xlat to parsing

      2. Insert a "is_json" or "do_xlat" flag into the JSON ("avps"), and hope xlat will then dig deeper

      3. Save the JSON and parse with exec/rlm_exec (using JQ or any other bash/JSON tools)


      Please advise if there is any workaround. Thanks!







      json rest api restful-authentication freeradius






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Nov 21 '18 at 13:59









      peteeelolpeteeelol

      32




      32
























          1 Answer
          1






          active

          oldest

          votes


















          0














          In FreeRADIUS version 4, there's a rlm_json module, which implements a custom node query language based on xpath (jpath), it is extremely limited and only supports some very basic queries (feel free to enhance it via PR :) ).



          Below is an example I pulled out of my library of customer configurations. You can see here it's pulling out two keys (externalID and macAddress) from the root level of the JSON doc and assigning them to a couple of custom attributes (Subscriber-ID and Provisioned-MAC).



          map json "%{rest_api:https://${modules.rest[rest_api].server}/admin/api/${modules.rest[rest_api].api_key}/external/getDeviceBySerialNumber?certificateSerialNumber=%{lpad:&TLS-Client-Cert-Serial 40 0}}" {
          &Subscriber-ID := '$.externalId'
          &Provisioned-MAC := '$.macAddress'
          }


          The xlat expansion can also be modified to send HTTP body data. Just put a space after the URL and pass your custom JSON blob.






          share|improve this answer


























          • This looks great :) However, our team is now using on rlm_rest. The main reason is we had implement curl multi-interface to support HTTP/2 multiplexing in this case. So I guess json must be the output of rlm_rest. Is there a way to pass the result of rlm_rest to rlm_json?

            – peteeelol
            Nov 22 '18 at 2:43











          • rest_api is just an instance of rlm_rest. The expansion used there is the expansion from the rlm_rest module. I think rlm_rest will support HTTP/2 fine. Might need an extra option passed to libcurl to enable pipelining but that's about it.

            – Arran Cudbard-Bell
            Nov 22 '18 at 10:04











          • Yeah I just checked this. In v4.0.x at least we can add pipelining relatively easily. Just need to set some options on the multi handle and we're good to go.

            – Arran Cudbard-Bell
            Nov 22 '18 at 15:32











          • Thanks... I now noticed the implement of rlm_rest change from curl_easy to curl_multi_interface at FreeRADIUS 4.0.x. This does make HTTP/2 multiplexing relatively easy!

            – peteeelol
            Nov 23 '18 at 3:48











          • Anothor qeestion, how do i specify the HTTP method if I was gonna use "%{rest_api:REST_URI JSON_BODY"? I notice there is uri and body but no HTTP method.

            – peteeelol
            Nov 23 '18 at 3:56











          Your Answer






          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "1"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53413728%2ffreeradius-3-0-17-rlm-rest-parsing-json-response%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          1 Answer
          1






          active

          oldest

          votes








          1 Answer
          1






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          0














          In FreeRADIUS version 4, there's a rlm_json module, which implements a custom node query language based on xpath (jpath), it is extremely limited and only supports some very basic queries (feel free to enhance it via PR :) ).



          Below is an example I pulled out of my library of customer configurations. You can see here it's pulling out two keys (externalID and macAddress) from the root level of the JSON doc and assigning them to a couple of custom attributes (Subscriber-ID and Provisioned-MAC).



          map json "%{rest_api:https://${modules.rest[rest_api].server}/admin/api/${modules.rest[rest_api].api_key}/external/getDeviceBySerialNumber?certificateSerialNumber=%{lpad:&TLS-Client-Cert-Serial 40 0}}" {
          &Subscriber-ID := '$.externalId'
          &Provisioned-MAC := '$.macAddress'
          }


          The xlat expansion can also be modified to send HTTP body data. Just put a space after the URL and pass your custom JSON blob.






          share|improve this answer


























          • This looks great :) However, our team is now using on rlm_rest. The main reason is we had implement curl multi-interface to support HTTP/2 multiplexing in this case. So I guess json must be the output of rlm_rest. Is there a way to pass the result of rlm_rest to rlm_json?

            – peteeelol
            Nov 22 '18 at 2:43











          • rest_api is just an instance of rlm_rest. The expansion used there is the expansion from the rlm_rest module. I think rlm_rest will support HTTP/2 fine. Might need an extra option passed to libcurl to enable pipelining but that's about it.

            – Arran Cudbard-Bell
            Nov 22 '18 at 10:04











          • Yeah I just checked this. In v4.0.x at least we can add pipelining relatively easily. Just need to set some options on the multi handle and we're good to go.

            – Arran Cudbard-Bell
            Nov 22 '18 at 15:32











          • Thanks... I now noticed the implement of rlm_rest change from curl_easy to curl_multi_interface at FreeRADIUS 4.0.x. This does make HTTP/2 multiplexing relatively easy!

            – peteeelol
            Nov 23 '18 at 3:48











          • Anothor qeestion, how do i specify the HTTP method if I was gonna use "%{rest_api:REST_URI JSON_BODY"? I notice there is uri and body but no HTTP method.

            – peteeelol
            Nov 23 '18 at 3:56
















          0














          In FreeRADIUS version 4, there's a rlm_json module, which implements a custom node query language based on xpath (jpath), it is extremely limited and only supports some very basic queries (feel free to enhance it via PR :) ).



          Below is an example I pulled out of my library of customer configurations. You can see here it's pulling out two keys (externalID and macAddress) from the root level of the JSON doc and assigning them to a couple of custom attributes (Subscriber-ID and Provisioned-MAC).



          map json "%{rest_api:https://${modules.rest[rest_api].server}/admin/api/${modules.rest[rest_api].api_key}/external/getDeviceBySerialNumber?certificateSerialNumber=%{lpad:&TLS-Client-Cert-Serial 40 0}}" {
          &Subscriber-ID := '$.externalId'
          &Provisioned-MAC := '$.macAddress'
          }


          The xlat expansion can also be modified to send HTTP body data. Just put a space after the URL and pass your custom JSON blob.






          share|improve this answer


























          • This looks great :) However, our team is now using on rlm_rest. The main reason is we had implement curl multi-interface to support HTTP/2 multiplexing in this case. So I guess json must be the output of rlm_rest. Is there a way to pass the result of rlm_rest to rlm_json?

            – peteeelol
            Nov 22 '18 at 2:43











          • rest_api is just an instance of rlm_rest. The expansion used there is the expansion from the rlm_rest module. I think rlm_rest will support HTTP/2 fine. Might need an extra option passed to libcurl to enable pipelining but that's about it.

            – Arran Cudbard-Bell
            Nov 22 '18 at 10:04











          • Yeah I just checked this. In v4.0.x at least we can add pipelining relatively easily. Just need to set some options on the multi handle and we're good to go.

            – Arran Cudbard-Bell
            Nov 22 '18 at 15:32











          • Thanks... I now noticed the implement of rlm_rest change from curl_easy to curl_multi_interface at FreeRADIUS 4.0.x. This does make HTTP/2 multiplexing relatively easy!

            – peteeelol
            Nov 23 '18 at 3:48











          • Anothor qeestion, how do i specify the HTTP method if I was gonna use "%{rest_api:REST_URI JSON_BODY"? I notice there is uri and body but no HTTP method.

            – peteeelol
            Nov 23 '18 at 3:56














          0












          0








          0







          In FreeRADIUS version 4, there's a rlm_json module, which implements a custom node query language based on xpath (jpath), it is extremely limited and only supports some very basic queries (feel free to enhance it via PR :) ).



          Below is an example I pulled out of my library of customer configurations. You can see here it's pulling out two keys (externalID and macAddress) from the root level of the JSON doc and assigning them to a couple of custom attributes (Subscriber-ID and Provisioned-MAC).



          map json "%{rest_api:https://${modules.rest[rest_api].server}/admin/api/${modules.rest[rest_api].api_key}/external/getDeviceBySerialNumber?certificateSerialNumber=%{lpad:&TLS-Client-Cert-Serial 40 0}}" {
          &Subscriber-ID := '$.externalId'
          &Provisioned-MAC := '$.macAddress'
          }


          The xlat expansion can also be modified to send HTTP body data. Just put a space after the URL and pass your custom JSON blob.






          share|improve this answer















          In FreeRADIUS version 4, there's a rlm_json module, which implements a custom node query language based on xpath (jpath), it is extremely limited and only supports some very basic queries (feel free to enhance it via PR :) ).



          Below is an example I pulled out of my library of customer configurations. You can see here it's pulling out two keys (externalID and macAddress) from the root level of the JSON doc and assigning them to a couple of custom attributes (Subscriber-ID and Provisioned-MAC).



          map json "%{rest_api:https://${modules.rest[rest_api].server}/admin/api/${modules.rest[rest_api].api_key}/external/getDeviceBySerialNumber?certificateSerialNumber=%{lpad:&TLS-Client-Cert-Serial 40 0}}" {
          &Subscriber-ID := '$.externalId'
          &Provisioned-MAC := '$.macAddress'
          }


          The xlat expansion can also be modified to send HTTP body data. Just put a space after the URL and pass your custom JSON blob.







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Nov 24 '18 at 21:35

























          answered Nov 21 '18 at 16:33









          Arran Cudbard-BellArran Cudbard-Bell

          3,61911433




          3,61911433













          • This looks great :) However, our team is now using on rlm_rest. The main reason is we had implement curl multi-interface to support HTTP/2 multiplexing in this case. So I guess json must be the output of rlm_rest. Is there a way to pass the result of rlm_rest to rlm_json?

            – peteeelol
            Nov 22 '18 at 2:43











          • rest_api is just an instance of rlm_rest. The expansion used there is the expansion from the rlm_rest module. I think rlm_rest will support HTTP/2 fine. Might need an extra option passed to libcurl to enable pipelining but that's about it.

            – Arran Cudbard-Bell
            Nov 22 '18 at 10:04











          • Yeah I just checked this. In v4.0.x at least we can add pipelining relatively easily. Just need to set some options on the multi handle and we're good to go.

            – Arran Cudbard-Bell
            Nov 22 '18 at 15:32











          • Thanks... I now noticed the implement of rlm_rest change from curl_easy to curl_multi_interface at FreeRADIUS 4.0.x. This does make HTTP/2 multiplexing relatively easy!

            – peteeelol
            Nov 23 '18 at 3:48











          • Anothor qeestion, how do i specify the HTTP method if I was gonna use "%{rest_api:REST_URI JSON_BODY"? I notice there is uri and body but no HTTP method.

            – peteeelol
            Nov 23 '18 at 3:56



















          • This looks great :) However, our team is now using on rlm_rest. The main reason is we had implement curl multi-interface to support HTTP/2 multiplexing in this case. So I guess json must be the output of rlm_rest. Is there a way to pass the result of rlm_rest to rlm_json?

            – peteeelol
            Nov 22 '18 at 2:43











          • rest_api is just an instance of rlm_rest. The expansion used there is the expansion from the rlm_rest module. I think rlm_rest will support HTTP/2 fine. Might need an extra option passed to libcurl to enable pipelining but that's about it.

            – Arran Cudbard-Bell
            Nov 22 '18 at 10:04











          • Yeah I just checked this. In v4.0.x at least we can add pipelining relatively easily. Just need to set some options on the multi handle and we're good to go.

            – Arran Cudbard-Bell
            Nov 22 '18 at 15:32











          • Thanks... I now noticed the implement of rlm_rest change from curl_easy to curl_multi_interface at FreeRADIUS 4.0.x. This does make HTTP/2 multiplexing relatively easy!

            – peteeelol
            Nov 23 '18 at 3:48











          • Anothor qeestion, how do i specify the HTTP method if I was gonna use "%{rest_api:REST_URI JSON_BODY"? I notice there is uri and body but no HTTP method.

            – peteeelol
            Nov 23 '18 at 3:56

















          This looks great :) However, our team is now using on rlm_rest. The main reason is we had implement curl multi-interface to support HTTP/2 multiplexing in this case. So I guess json must be the output of rlm_rest. Is there a way to pass the result of rlm_rest to rlm_json?

          – peteeelol
          Nov 22 '18 at 2:43





          This looks great :) However, our team is now using on rlm_rest. The main reason is we had implement curl multi-interface to support HTTP/2 multiplexing in this case. So I guess json must be the output of rlm_rest. Is there a way to pass the result of rlm_rest to rlm_json?

          – peteeelol
          Nov 22 '18 at 2:43













          rest_api is just an instance of rlm_rest. The expansion used there is the expansion from the rlm_rest module. I think rlm_rest will support HTTP/2 fine. Might need an extra option passed to libcurl to enable pipelining but that's about it.

          – Arran Cudbard-Bell
          Nov 22 '18 at 10:04





          rest_api is just an instance of rlm_rest. The expansion used there is the expansion from the rlm_rest module. I think rlm_rest will support HTTP/2 fine. Might need an extra option passed to libcurl to enable pipelining but that's about it.

          – Arran Cudbard-Bell
          Nov 22 '18 at 10:04













          Yeah I just checked this. In v4.0.x at least we can add pipelining relatively easily. Just need to set some options on the multi handle and we're good to go.

          – Arran Cudbard-Bell
          Nov 22 '18 at 15:32





          Yeah I just checked this. In v4.0.x at least we can add pipelining relatively easily. Just need to set some options on the multi handle and we're good to go.

          – Arran Cudbard-Bell
          Nov 22 '18 at 15:32













          Thanks... I now noticed the implement of rlm_rest change from curl_easy to curl_multi_interface at FreeRADIUS 4.0.x. This does make HTTP/2 multiplexing relatively easy!

          – peteeelol
          Nov 23 '18 at 3:48





          Thanks... I now noticed the implement of rlm_rest change from curl_easy to curl_multi_interface at FreeRADIUS 4.0.x. This does make HTTP/2 multiplexing relatively easy!

          – peteeelol
          Nov 23 '18 at 3:48













          Anothor qeestion, how do i specify the HTTP method if I was gonna use "%{rest_api:REST_URI JSON_BODY"? I notice there is uri and body but no HTTP method.

          – peteeelol
          Nov 23 '18 at 3:56





          Anothor qeestion, how do i specify the HTTP method if I was gonna use "%{rest_api:REST_URI JSON_BODY"? I notice there is uri and body but no HTTP method.

          – peteeelol
          Nov 23 '18 at 3:56


















          draft saved

          draft discarded




















































          Thanks for contributing an answer to Stack Overflow!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53413728%2ffreeradius-3-0-17-rlm-rest-parsing-json-response%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          "Incorrect syntax near the keyword 'ON'. (on update cascade, on delete cascade,)

          Alcedinidae

          Origin of the phrase “under your belt”?