Outlook Integration error

I am using connected system with Oauth2.0 to connect to office365 and get the calendars i m able to authorize using connected system however when testing the base url I get the below error

Invalid credentials

Appian was not able to authenticate with the access token you provided. This request requires Bearer authentication. HTTP/1.1 401 Unauthorized Next Steps

  • This integration is using a connected system with OAuth 2.0 authentication configured. You may need to authorize access to the external system and retry the request.
  • Make sure that you are using the correct OAuth 2.0 configuration for this external system
  • Make sure that the OAuth 2.0 configuration provides the required scope to make this request
  • Check the request and response for more details
  • Review the external systems documentation for information on what may have caused the problem

When i run the authorization its executes successfully.  Has any one seen this issue before or can someone share the Oauth2.0 configuration related to outlook ( For outlook defining a scope is mandatory)

  Discussion posts and replies are publicly visible

Parents
  • I have integrated Appian with Office 365 before using the OAuth 2.0 client credentials grant type. A few questions before I can give proper advice:

    What is the use case here?
    What APIs are you attempting to use?
    Do you want to call them as the user who is logged into Appian or do you want to use a service account?
    Do you have an app set up in Azure AD for this and if so how is it set up?

    All of these answers will help determine how to set this up in Appian. Also in speaking with Microsoft consultants, Microsoft Graph APIs should be used going forward instead of Office 365 APIs.
  • Use Case: Using appian to get users calendar from Outlook for OOO, busy schedule etc
    What APIs are you attempting to use? --- We are making a regular Web connection with implicit flow and a redirect url to appian
    Do you want to call them as the user who is logged into Appian or do you want to use a service account? -- For testing we would use user but for production deploy it would be a service account.
    Do you have an app set up in Azure AD for this and if so how is it set up? --- App is setup in Azure with client ID secret and required permission to read users calendars.
  • You mention wanting to use the implicit grant flow, but Appian Connected System OAuth 2.0 in 18.3 supports authorization code grant flow. This could explain your issue.

    If you are planning on treating this integration like a service account, I recommend the client credentials grant type, which is designed for these scenarios. To do this in Appian 18.3 you can create two Appian Integration objects: one that requests the token and one that uses the token for the actual request. As announced during the 18.4 webinar, Appian will have a specific feature for client credentials grant type configuration in 18.4 as well.

    Also, I recommend moving towards Microsoft Graph REST APIs rather than Office 365 REST APIs. This is because when using the client credentials grant type with Office 365 REST APIs, Microsoft requires you to register an x509 cert with the application and sign API calls with it via a JWT. This is a pain to set up in Azure and requires a plugin in Appian. Meanwhile, Microsoft Graph APIs require none of that and are much easier to set up.

    The only reason my implementation had to do all this for Office 365 is because the "Find Meeting Times" API in Graph has a bug that has gone unfixed for years, while the "Find Meeting Times" API in Office 365 works fine. If you don't need that service, go with Graph!

  • Do i create Appian Integration objects one that requests the token and one that uses the token for the actual request as a expression rule i don't see a way to do this via integration option in the connected system.
  • You have to build the details (url, parameters, body) of the 2 requests yourself. Integrations can be created outside connected systems so I recommend starting with that. For both of them you will select "None" for authentication since you will be configuring the token exchange yourself. This method below requests a new bearer token every call. You could also cache the token in the database for re-use, but we decided against that method in favor of this one to limit the exposure of where the token is accessible.

     

    Integration 1 - Getting the bearer token

    URL: https://login.microsoftonline.com/<INSERT_ORG_SPECIFIC_URL>/oauth2/v2.0/token

    Parameters: None

    Headers: None

    Body:

    "grant_type=client_credentials&
    scope=https%3A%2F%2Fgraph.microsoft.com%2F.default&
    client_id="&cons!YOUR_CLIENT_ID&"&
    client_secret="&cons!YOUR_CLIENT_SECRET

    make sure to lock down the security on these constants to admins only

     

    Integration 2 - Making a request using this token

    URL/parameters/body: This is whatever Graph REST API you are trying to use

    Headers: Authorization - "Bearer "&rule!MG_ws_getGraphBearerTokenQ().result.body.access_token

     

    In this case, rule!MG_ws_getGraphBearerTokenQ() is what we configured in "Integration 1"

  • Thanks will give this a try i hope this would work for SharePoint in 365 as well.
  • I am able to get to the Integration 1 can you share the expression rule example to achieve the Integration 2?
  • The Integration details for #2 are completely dependent on what Graph REST API you are trying to call and the format that API expects. You will have to read the Graph API documentation. I showed you the headers section which is important because that is how you pass the token.

    But here is an example:

     

  • Hi Steve. Great info here. We are implementing this in Appian 19.2 using a connected system but it seems that we need to use an authorization link to obtain the token. This is an extra step for our users and needs to be repeated after each time the token expires. Is there any other approach that will not require the users to authorize every time? Do we just need to increase the token expiration value? 

  • My write-up above is for the OAuth 2.0 Client Credentials grant type (which Appian now has a feature to handle OOTB rather than doing the 2 calls by hand: https://docs.appian.com/suite/help/19.2/oauth_client_credentials.html). This is for system to system (service account) type interactions. The system takes care of token retrieval and refresh; the user never knows). Also, Appian has access to all the data in the external system and decides who to show it to on Appian interfaces based on their Appian groups.

    You seem to be talking about something different. Per-user authorization using authorization links is called OAuth 2.0 Auth Code grant type (which Appian also has features for: https://docs.appian.com/suite/help/19.2/Oauth_connected_system.html). This is what you are describing. If you go with this option, you HAVE to have the user manually authorize Appian to act on their behalf the first time and each time the token expires. That is how OAuth is designed and with good reason.

  • I know that this is quite an old topic at this point, but since this appears to be the best source I can find on it (and we are trying to do as you describe, call the Office 365 REST APIs to be able to do some things that the Graph API cannot), I figured I would ask.

    When you mentioned 'using a plugin for the JWT', was that perhaps the createjwttokenwithrs256 plugin available on the App Market? I have not been able to get the plugin to accept any pkcs8 file I give it, but I have kept trying.

    Additionally, I have tried uploading my self-signed certificate into Appian in the 'Client Certificates' admin console settings page, but I cannot find any documentation on how to reference this uploaded certificate within a Integration object or Connected System object (is it by the 'thumbprint'? Is there an example somewhere I could use?).

    Thank you for your time.

Reply
  • I know that this is quite an old topic at this point, but since this appears to be the best source I can find on it (and we are trying to do as you describe, call the Office 365 REST APIs to be able to do some things that the Graph API cannot), I figured I would ask.

    When you mentioned 'using a plugin for the JWT', was that perhaps the createjwttokenwithrs256 plugin available on the App Market? I have not been able to get the plugin to accept any pkcs8 file I give it, but I have kept trying.

    Additionally, I have tried uploading my self-signed certificate into Appian in the 'Client Certificates' admin console settings page, but I cannot find any documentation on how to reference this uploaded certificate within a Integration object or Connected System object (is it by the 'thumbprint'? Is there an example somewhere I could use?).

    Thank you for your time.

Children
  • The plugin we used was created for the project and is not available on the AppMarket. If that plugin allows for creation of JWT with the details Azure requires, then it might be a suitable solution, but I am not sure if Azure accepts pkcs8.

    Client certificates in the Admin Console are for mutual authentication and Appian presents a certificate that matches the root of the server requesting mutual auth. This only happens when making a supported call in Appian (integration object or web service query). This is different than the JWT authentication that Office 365 REST APIs require.