NX Cloud Relay API changes? Digest no longer working

Answered

Comments

30 comments

  • Avatar
    Norman - Nx Support

    Hi Luke McFadden,

    My apologies for the delay.

    When I connect to https://nxvms.com/cdb/system/get and use my cloud credentials (email + password) I receive the full JSON output for all cloud connected systems. But I'll check with our cloud team for more details and get back to you about this. 

    Regarding the change in default authentication in 5.0. You're right we changed the default method from Digest to Bearer. That being said, for applications that require Digest Authentication, you can create a separate local user account to execute these requests.

    This local user account, can also be used when you route API Calls via Nx Cloud.

    0
    Comment actions Permalink
  • Avatar
    Luke McFadden

    Norman-Nx-Support  Can you link the current Bearer auth docs that would work for establishing a connection for a cloud relay connection?   

    I'm wanting to replace my previous digest auth automations, but I'm struggling to find the specific documentation.  

    My end goal is to use a set of cloud credentials and be able to relay API calls to a system that the user has access to.

    0
    Comment actions Permalink
  • Avatar
    Norman - Nx Support

    Hi Luke McFadden,

    When you navigate tot the API Documentation >>> API Information, and scroll down, you will find a section about Authentication and there everything is described about Bearer authentication.

    I suppose you'll find it worth looking at the code examples in our Github repo.

    Ps. I noticed that the link Knowledgebase is currently a dead link and spelled incorrectly, I have reported it. I assume THIS is the correct link.

    JIRA-VMS-36086

    0
    Comment actions Permalink
  • Avatar
    Luke McFadden

    Thanks for the replies Norman-Nx-Support and Andrey Terentyev


    I am wanting to utilize the cloud relay.  I have the cloud Oauth2 processing working, and I've verified the bearer token locally:

    However, this document only mentions that digest auth is available? (It also has some technical formatting issues)  https://support.networkoptix.com/hc/en-us/articles/360016266074-Cloud-API-Route-API-Calls-via-Nx-Meta-Developer-Portal

    Am I unable to use the cloud user Oauth2 bearer token for relay calls?  When I am testing this, it doesn't seem to work?   

    However, if I load that URL, it prompts for username/password, and then it returns the JSON normally.

    So, questions:

    1. Does the vmsrelay support cloud user Oauth2 tokens?
    2. Am I able to create a bearer token with the scope for multiple systems?  The docs only show an example of a single cloudSystemId.  Can we pass a comma-separated list or a collection of cloudSystemIds?
    3. Is it possible to create a cloud user that only has API access?  We want to force MFA for all cloud users, but I didn't see a method for utilizing MFA when using the Oauth2 token endpoint.   If not, what is the recommended alternative?

    Thanks for the help.

    Luke

     

    0
    Comment actions Permalink
  • Avatar
    Andrey Terentyev

    Hi,

    Am I unable to use the cloud user Oauth2 bearer token for relay calls?  When I am testing this, it doesn't seem to work?   

    Please, use the local_bearer.py code example in our repo.

    https://github.com/networkoptix/nx_open_integrations/blob/master/python/examples/authentication/local_bearer.py

    Assign

    LOCAL_URL = '<you system id>.relay.vmsproxy.com'

    Assign USERNAME, PASSWORD of your local account (not the cloud account).

    Does the vmsrelay support cloud user Oauth2 tokens?

    Yes, it does.

    Am I able to create a bearer token with the scope for multiple systems?  The docs only show an example of a single cloudSystemId.  Can we pass a comma-separated list or a collection of cloudSystemIds?

    You don't need cloudSystemIds. See an example mentioned above.

    Is it possible to create a cloud user that only has API access?  We want to force MFA for all cloud users, but I didn't see a method for utilizing MFA when using the Oauth2 token endpoint.   If not, what is the recommended alternative?

    No, it's not possible. Each account can invoke API calls. The response depends on the account permissions. You could look at the "x-permissions" in the documentation for each API.

    0
    Comment actions Permalink
  • Avatar
    Luke McFadden

    I had typed up a long response, but it doesn't appear to have posted Andrey Terentyev

    I'm still unable to get this working.  I am receiving the token successfully:

    • I can use it to retrieve a list of all cloud systems:

     

    But, I am unable to use it to retrieve a list of cameras from a specific system via relay.  I can access this relay endpoint directly in browser a local username / password.

    But, why can't I use this token to access the devices directly?

    0
    Comment actions Permalink
  • Avatar
    Andrey Terentyev

    Hello Luke,

    We have a way weird conversation here, unfortunately.

    By providing links to ready tools and code examples, we not only give you a ready-to-use solutions accompanied by corrections to be made and customized to your particular case, you could learn from, but also a code base to be on the same page to facilitate diagnostics.

    That being said, in this context have you tried the recommendations given? Have you looked at the code, API functions used? If yes, what is the result? Was it successful? If not, what is going wrong? What is the error message?

    Please, use the local_bearer.py code example in our repo.

    https://github.com/networkoptix/nx_open_integrations/blob/master/python/examples/authentication/local_bearer.py

    Assign

    LOCAL_URL = '<you system id>.relay.vmsproxy.com'

    Assign USERNAME, PASSWORD of your local account (not the cloud account).

    0
    Comment actions Permalink
  • Avatar
    Luke McFadden

    Greetings.  

    Yes, I have read through the docs that you've attached and referenced.  We are not building this in Python, so we are doing our best to extract the appropriate API calls and test the overall flow in Postman before building it in our final API tool.  

    You had stated in a previous reply:  

    "

    Does the vmsrelay support cloud user Oauth2 tokens?

    Yes, it does."

     

    The local_bearer.py doesn't really apply in this situation, so I've been pulling from the cloud_bearer.py and the API Information from the local server in the developer section:

    I assumed your response to this question to mean that I can use a Cloud Bearer Token with the VMS relay.  So that's what I provided screenshots for inside of Postman to help be as clear as I could.  Apologies if it wasn't clear.  

    For some reason, I cannot use other endpoints with the bearer session:

    The bearer token shows that it is valid when I test it via the cloud relay, but I cannot use that bearer token to make other API calls:

     

    Thanks for your continued help, I've spent a large amount of time on this, and I can't determine why it is not working.  We had this working fine when using Basic auth via relay.

     

    0
    Comment actions Permalink
  • Avatar
    Andrey Terentyev

    Hi Luke,

    Here what I've figured out from your messages.

    I've had the cloud relay working in the past

    I am wanting to utilize the cloud relay

    Am I unable to use the cloud user Oauth2 bearer token for relay calls?  When I am testing this, it doesn't seem to work?   

    If I understood you right, you want to authenticate with cloud account with bearer token, and afterwards to send API requests via cloud relay.

    Here is the solution.

    1. You authenticate with a cloud account and get a token.


    The raw body:

    {
        "grant_type": "password",
        "response_type": "token",
        "client_id": "3rdParty",
        "username": "{{username}}",
        "password": "{{password}}",
        "scope":"cloudSystemId={{cloud_system_id}}"
    }

    {{username}}, {{password}}, {{cloud_system_id}} are postman custom global variables.

    The access_token value from the response is stored in the {{bearer_token}} postman global variable.

    2. Send a request to your system via the cloud relay <cloud system id>.relay.vmsproxy.com

    Make sure you have defined a proper authorization header with the token received.

    0
    Comment actions Permalink
  • Avatar
    Luke McFadden

    Andrey Terentyev

    Yes, as shown in the steps above, this is *not working*.  I'm following these steps, but as I mentioned, the token that is being returned isn't working:

    {
        "error": "12",
        "errorId": "unauthorized",
        "errorString": "Auth_Forbidden"
    }
     
    Can we please escalate this to a ticket or arrange a time for testing so we can avoid going back and forth?  I feel I am providing adequate screenshots and following the provided information. 
     
    I can validate the bearer token against the server via the relay as I mentioned in my previous post.  But the token is not working for actual endpoint calls. Verifying the session does not require a session token for authing.
    0
    Comment actions Permalink
  • Avatar
    Andrey Terentyev

    Luke McFadden,

    Please don't set "Bearer Token" authorization on the "Auth" tab. It should stay default (i.e. Inherit auth from parent) for all request you invoke. In my case, in both requests it's set to default.

     

     

    0
    Comment actions Permalink
  • Avatar
    Andrey Terentyev

    If you want, I could export my working request to a code snippet of any type Postman supports.

    0
    Comment actions Permalink
  • Avatar
    Luke McFadden

    I’m happy to try out your request examples.

    Manually setting the bearer token should be fine? I’m updating it each time I make my OAuth request.

    I really don’t feel like I’m missing anything, this feels more like an error or issue?

    Also, I notice that the server response from the relay is showing server version 4.3, and including digest information? You can see that in the above screenshot with the postman console output. Both servers in this system are on 5.0.

    0
    Comment actions Permalink
  • Avatar
    Andrey Terentyev

    Hello Luke,

    Manually setting the bearer token should be fine?

    I wouldn't recommend doing that. That's why I use variables in my request. Just for avoiding so-called "user error": typos, copy/paste error etc.

    I really don’t feel like I’m missing anything, this feels more like an error or issue?

    Luke, obviously you're missing something, and it's fine. Otherwise, you wouldn't have asked for help. You've been given the recommendations and examples. Working. Verified.
    At the moment, the objective is not about finding an issue or an error, it's about calming down, mastering the Postman and doing attentively by following the guidelines.

    1. Open the Postman

    2. Create a new empty Collection.

    It's crucial. Make a fresh start. Avoid using or copy/pasting existing requests of collections.

    3. Define global variables

    username, password, cloud_system_id, bearer_token

    as shown on the screenshot. Here is the guide https://learning.postman.com/docs/sending-requests/variables/

    Assign your according values to username, password, cloud_system_id. The bearer_token variable will be assigned automatically. See further.

    4. Click the "Save" button.

    5. In the Collection created, Create a POST request

    URL: https://nxvms.com/cdb/oauth2/token

    Add one custom header:

    Add the Body, type raw:

    {
        "grant_type": "password",
        "response_type": "token",
        "client_id": "3rdParty",
        "username": "{{username}}",
        "password": "{{password}}",
        "scope":"cloudSystemId={{cloud_system_id}}"
    }

    Don't do any other changes.

    6. Click the "Save" button.

    7. Click the "Send" button.

    8. In the response body, select the "access_token" value

    Right-click on the selection. Choose Set:Globals->bearer_token.

    9. In the Collection created, create a GET request.

    URL: https://{{cloud_system_id}}.relay.vmsproxy.com/rest/v1/devices

    Add two headers as shown on the screenshot.

    10. Click the "Save" button.

    11. Do sequentially: Send the POST request created - Step 7, Send the GET request created.

     

    0
    Comment actions Permalink
  • Avatar
    Andrey Terentyev

    Here are code snippets.

    POST for getting a token.

    curl --location --request POST 'https://nxvms.com/cdb/oauth2/token' \
    --header 'Content-Type: application/json' \
    --data-raw '{
        "grant_type": "password",
        "response_type": "token",
        "client_id": "3rdParty",
      "username": "your user name",
      "password": "your password",
      "scope":"cloudSystemId=your system id"
    }'

    GET for getting a device list.

    curl --location --request GET 'https://<you system id>.relay.vmsproxy.com/rest/v1/devices' \
    --header 'Authorization: Bearer nxcdb-68bc269e-XXXX-XXXX-XXXX-XXXXXXXXXXXX' \
    --header 'Accept: application/json'
    0
    Comment actions Permalink
  • Avatar
    Luke McFadden

    Andrey Terentyev

    Luke, obviously you're missing something, and it's fine. Otherwise, you wouldn't have asked for help. You've been given the recommendations and examples. Working. Verified.
    At the moment, the objective is not about finding an issue or an error, it's about calming down, mastering the Postman and doing attentively by following the guidelines.

    I'm pretty calm, just growing a bit frustrated at the length of time it is taking to work on this.  I requested escalation in that I perceive that I am not making mistakes, but rather that there is something else.   I work daily with 20+ API's for automation work, so I'm quite familiar.

    I've followed your steps, and I've ended up again with the same issue.  I'm trying multiple credentials and multiple cloudSystemIds. 

    0
    Comment actions Permalink
  • Avatar
    Andrey Terentyev

    Hello Luke,

    What is the build number of the version you're using?

    Could you please share a screencast of you configuring and sending the requests?

    I’m happy to try out your request examples.

    Have you tried code snippets provided? Just to make sure it's working. What's the result?

    Yes, I have read through the docs that you've attached and referenced. 

    The local_bearer.py doesn't really apply in this situation, so I've been pulling from the cloud_bearer.py and the API Information from the local server in the developer section:

    Have you tried to launch python examples, the cloud_bearer.py in your case? Just to make sure it's working.  What's the result?

     

    0
    Comment actions Permalink
  • Avatar
    Norman - Nx Support

    Luke McFadden,

    Regarding:

    Could you please share a screencast of you configuring and sending the requests?

    You can share a link privately through Discord, and I'll make sure Andrey Terentyev will get it.

    0
    Comment actions Permalink
  • Avatar
    Andrey Terentyev

    Luke,

    Which Postman version are you using: web or desktop?

    0
    Comment actions Permalink
  • Avatar
    Andrey Terentyev

    Here is what I've found with my colleague.

    All the requests and recommendation were created and tested in the desktop version of Postman, meanwhile in the web versions we got the similar errors you have.

    In short, requests provided work only in the desktop version of Postman.

    0
    Comment actions Permalink
  • Avatar
    Luke McFadden

    Norman-Nx-Support and Andrey Terentyev

    I've sent share links to Norman via Discord.  I've tested the cloud_bearer.py script and it is also returning the same results as Postman.

    0
    Comment actions Permalink
  • Avatar
    Luke McFadden

    Update:

    I have confirmed this is working now, but updating this Postman field:

    It is disabled by default.  Since the *.relay.vmsrelay.com always redirects to *.relay-something.vmsrelay.com, it wasn't passing the auth on redirect.

    I've tested and this is working now in my automation platform.

    One final question regarding scope:

    The documentation isn't clear on the difference with a bearer token that has the following scopes:

    Request body parameter:

        "scope": "nxvms.com cloudSystemId=*"
        "scope": "cloudSystemId=16f08478-1485-4704-8a7c-29ca994e#####"
     
    I'm receiving an auth error (Auth_WrongSessionToken) when using a bearer token with the "scope": "nxvms.com cloudSystemId=*" for any endpoint on relay requests.
     
    But if I use a bearer token with "scope":"cloudSystemId={{cloud_system_id}}", then I can successfully make the request.
     
    So to clarify, my question:  Should "scope": "nxvms.com cloudSystemId=*" allow me to make requests to all cloud systems that my user has access to?
     
     
     
     
    0
    Comment actions Permalink
  • Avatar
    Andrey Terentyev

    Luke,

    Congratulations!

    Thank you for sharing your solution.

    0
    Comment actions Permalink
  • Avatar
    Luke McFadden

    Thanks Andrey Terentyev

    Do you mind providing feedback on my final question listed in my last reply?

     

    One final question regarding scope:

    The documentation isn't clear on the difference with a bearer token that has the following scopes:

    Request body parameter:

        "scope": "nxvms.com cloudSystemId=*"
        "scope": "cloudSystemId=16f08478-1485-4704-8a7c-29ca994e#####"
     
    I'm receiving an auth error (Auth_WrongSessionToken) when using a bearer token with the "scope": "nxvms.com cloudSystemId=*" for any endpoint on relay requests.
     
    But if I use a bearer token with "scope":"cloudSystemId={{cloud_system_id}}", then I can successfully make the request.
     
    So to clarify, my question:  Should "scope": "nxvms.com cloudSystemId=*" allow me to make requests to all cloud systems that my user has access to?
    0
    Comment actions Permalink
  • Avatar
    Andrey Terentyev

    Luke,

    I'll definitely answer your question, but please allow me some time.

    I've watched your videos. Thank you. You've found an issue in our python examples. It appears, from my location, from your location and from the location Postman is hosted, HTTPS requests are directed differently.

    From my location, both in Postman desktop version and in python requests are not redirected and the URL remains intact. From your location, as I've seen, requests are redirected and URL changes. That is why the "Follow Authorization header" has to be set.

    We'll have to update our article and code examples in the repo.

    0
    Comment actions Permalink
  • Avatar
    Luke McFadden

    Andrey Terentyev

    I removed my refresh token question, as I've got it working now.

    Do you have an estimated response time for my scope related question?  If cloudSystemId=* doesn't allow a single bearer token to access multiple systems... then there really isn't any specific benefit of trying to utilize a cloud user vs. a local user, since I need to receive a token for each system, vs one token that will work across all systems the cloud user has permission too.

    Clarity:  I'd *much* prefer a single cloud user, with a single bearer token with the scope of nxvms.com cloudSystemId=* to be able to access all systems that they have permissions to do so.

    I'm asking with a bit of urgency, as this will impact how we build out our processes.

    0
    Comment actions Permalink
  • Avatar
    Andrey Terentyev

    Hi,

     Should "scope": "nxvms.com cloudSystemId=*" allow me to make requests to all cloud systems that my user has access to?

    No.

    cloudSystemId = (some_id | ”*”).
    This scope token is required for tokens that will be used to access the mediaserver. This MUST be specified if access to a system is desired. mediaserver API requests that use unrestricted access tokens are rejected.
    cloudSystemId=* scope makes the token valid for any VMS system of the Cloud account. Note that such scope should only be used to obtain a refresh_token that can be used to obtain an access token with a cloudSystemId=specific-id scope.

    0
    Comment actions Permalink
  • Avatar
    Luke McFadden

    Greetings Andrey Terentyev

    Sorry, I'm a bit confused by your response. 

    Firstly, is it possible to receive access to this document linking in the NX Cloud API docs for NX Oauth:  <LINK_REMOVED>

    A few questions to clarify:

    cloudSystemId = (some_id | ”*”).

    So, you are stating that the only options are:

    1. some_id
    2. *

    But that * will not allow requests against the media server via relay, only requests that explicitly have the ID in the scope?


    This scope token is required for tokens that will be used to access the mediaserver. This MUST be specified if access to a system is desired. mediaserver API requests that use unrestricted access tokens are rejected.

    cloudSystemId=* scope makes the token valid for any VMS system of the Cloud account. Note that such scope should only be used to obtain a refresh_token that can be used to obtain an access token with a cloudSystemId=specific-id scope.

    I'm trying to map the overall flow out, from beginning auth, to being able to make requests against any system (media server) via relay.

    Here are two diagrams:

    Are you saying that *only* method #1 is possible?  And that I should be using the refresh token for each call to a server via relay, specifying to scope to that specific system?

    And that, Method #2 is no possible?  To have a single token that can access multiple servers?

    0
    Comment actions Permalink
  • Avatar
    Andrey Terentyev

    Hi,

    Are you saying that *only* method #1 is possible?  And that I should be using the refresh token for each call to a server via relay, specifying to scope to that specific system?

    Yes, I am. I've checked with our cloud team and verified with a code. I'd recommend assigning the scope "https://nxvms.com/ cloudSystemId=*". It's given this way in the spec.
    You don't need to refresh a token each call unless the token is expired.

    And that, Method #2 is no possible?  To have a single token that can access multiple servers?

    No, it's not possible.

    0
    Comment actions Permalink
  • Avatar
    Norman - Nx Support

    Hi  Luke McFadden,

    Regarding:

    Firstly, is it possible to receive access to this document linking in the NX Cloud API docs for NX Oauth:  <LINK_REMOVED>

    The link you referred to, is internal only and can't be shared outside our organization.

    0
    Comment actions Permalink

Please sign in to leave a comment.