How to access the API using LTI Launch data

Options
Hi everyone! I'm wondering how to use the data provided in an LTI launch (oauth_nonce, etc...) to make API calls. We are currently using an OAuth 2.0 App to access the API but would like to not have to deal with syncing up access tokens across instances.  Thank you!

Answers

  • Tony.Stecca5
    Tony.Stecca5 Posts: 2
    edited November 2022

    Good question. I'd like to know the answer to this too

  • Mary.MacDonald96
    Mary.MacDonald96 Posts: 63
    edited November 2022

    Friends, I've forwarded your question to our LTI and API teams. As soon as they share anything, I'll respond back into this thread.

    Cheers!

  • Paul.Janzen98
    Paul.Janzen98 Posts: 26
    edited November 2022

    Hi Jake and Tony -- thanks for this question.

     

    In order to perform Brightspace API calls an API App is always required. For the workflow you are referring to I would highly recommend an OAuth 2.0 Brightspace API App.

     

    When the Tool Provider receives an LTI launch the TP knows that an open Brightspace session exists. At this point in time, you will walk through the OAuth 2.0 Auth workflow. Because the session is already open you don't have to worry about having the current user login. If your OAuth 2.0 Brightspace API App has "Prompt for user consent" OFF then you will be able to get an Access and Refresh Token without the end-user being aware. (Note: some customers may insist on this prompt being enabled)

     

    This does mean that you need to manage and store tokens.

     

    If the TP is only performing GET calls, then the current browser session should be sufficient (meaning tokens would not be required).

     

    Note that if you are using LTI 1.3 you should let the LTI Auth handshake fully complete prior to requesting an OAuth 2.0 token.

     

    Also, note that the above workflow assumes the API calls will be performed using the current user context. It is feasible for the TP to use a Service Account approach for performing API calls. But be transparent with your Brightspace Administrator of what you would be using the Service Account for. (Using a Service Account means you only have to maintain a single Access Token and a single Refresh Token).

     

    Paul

  • Tony.Stecca5
    Tony.Stecca5 Posts: 2
    edited November 2022

    Paul, thanks for the detailed reply. That's the information we were looking for. Perhaps you could offer some final comments on our design.  Allow me to briefly describe the app.

     

    It's a Node.js script running on a serverless Docker container that is invoked in response to an API call. We are using a Brightspace API App and the OAuth2.0 workflow as mentioned.  Because the container is transient we store the access token and refresh token in a persistent cloud location and retrieve it when the App launches. We're only making 1 GET request to the API to discover items in the table of contents.

     

    Question 1

    We like using LTI to launch the app allows us to protect our service and verify that the request is coming from a trusted LMS and an authenticated user with the right role. This means that we are using both an LTI launch and a API App. Is this a common or acceptable pattern?

     

    Question 2

    We are using a Service Account as the user in the OAuth 2.0 workflow. We like this approach because we can restrict the permissions of the SA and prevent them from conflicting with the permissions of end-user accounts. We don't really need the user context and it's nice to manage just one set of tokens. However, we are looking for the recommended way to get the initial access token for the service user. We would like to app to do it programmatically and avoid a manual step.

     

    Currently, we use a development tool, https://github.com/neverendingqs/oauth2-client-shell, from this tutorial, to recreate a request to the auth endpoint and retrieve an initial access token. Then we login as the service user and confirm the "Prompt For User Consent" prompt. Finally, we store this token in our persistent cloud storage when the app first runs. Each time our app re-instantiates it uses a stored refresh token to get a new access token and save both. If our app happens to lose state we have to re-do this process. This feels hacky to us. What would you recommend?

     

    We would prefer to authenticate the service user every time the container spins up. This would keep the container stateless. Can we do this without instantiating a server and just do a node.js post request to the auth end-point, https://auth.brightspace.com/oauth2/auth, with the service user's credentials and the other OAuth params like `CLIENT_ID` and `CLIENT_SECRET`, etc.

     

    Thank you very much for your time.