Search code examples
office365single-sign-onoutlook-addinoutlook-web-addinsmicrosoft-graph-api

SSO from Outlook-Add-In via Backend API to MS Graph - AADSTS65001: The user or administrator has not consented to use the application with ID …


I am trying to document the sending of emails in a backend database. So I created an Outlook Add-In that uses the ItemSend event to call a backend API. The backend API then should call Microdoft Graph to get the email and store it in the database.

After some confusion in the docs about SSO (Add-In → MS Graph) vs. SSO (Add-In → Backend API → MS Graph) I ended up with the following approach following the On-Behalf-Of OAuth flow:

  1. to register the Add-In and the backend API I followed the sample walkthrough in the MS Dos: Office Add-in that uses single sign-on (strangely the Node sample was much more readable than the ASP.NET sample) API permissions

  2. in the Outlook Add-In, get the user access token to pass to the backend

    // now get a different access token to pass to backend, so it can call MS graph
    // see: https://docs.microsoft.com/en-us/office/dev/add-ins/develop/use-sso-to-get-office-signed-in-user-token?tabs=vs2019
    return Office.auth.getAccessToken({
        //TODO: what options are actually required here and what do they do?
        allowSignInPrompt: true,
        allowConsentPrompt: true,
        forMSGraphAccess: true,
    }).catch((error) => {
        console.log('%c T2 |', 'color:lightred', 'onItemSend - ssoError', { error });
        let fallback = handleSSOErrors(error);
        if(fallback) {
            // …
        }
    });
    
  3. in the backend API (.NET Framework, but that shouldn't matter) get an API access token using the user access token

        private static string msAuthenticationBaseUrl = "https://login.microsoftonline.com/{tenantId}";
        private static string graphBaseUrl = "https://graph.microsoft.com/v1.0";
    
        using (var h = new System.Net.Http.HttpClient()) { //todo: transform to Request/Response instead of using HttpClient
    
            // get api access token
            // https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-on-behalf-of-flow
            var tokenUrl = $"{msAuthenticationBaseUrl}/oauth2/v2.0/token";
            h.DefaultRequestHeaders.Clear();
            var tokenResponse = await h.PostAsync(tokenUrl, new System.Net.Http.FormUrlEncodedContent(new Dictionary<string, string> {
                { "grant_type", "urn:ietf:params:oauth:grant-type:jwt-bearer" },    //TODO: ist that correct?
                { "client_id", clientId },
                { "client_secret", clientSecret },
                { "assertion", userAccessInfo.Token.RawData },
                { "requested_token_use", "on_behalf_of" },
                { "scope", "https://graph.microsoft.com/Mail.Read+offline_access" },
            }), cancellationToken);
            if(tokenResponse.StatusCode == HttpStatusCode.OK) {
                var content = await tokenResponse.Content.ReadAsStringAsync();
                Log.Debug(" ==> got api access token - success! \n{content}", content);
    
            }
            else {
                //----------------------------
                // ALWAYS LANDING HERE
                //----------------------------
                Log.Debug(" ==> getting api access token - failed {status} {statusMessage} {@data}", tokenResponse.StatusCode, tokenResponse.ReasonPhrase, await tokenResponse.Content.ReadAsStringAsync());
                return BadRequest("Error getting getting api access token");
            }
    
            //----------------------------
            // NEVER GETTING HERE … now we should have the token required to call the MS Graph API
            //----------------------------
    
        }
    

Either I understood nothing in the chapter Enable single sign-on (SSO) in an Office Add-in or there is just a permission missing in the Azure configuration. But I couldn't find any hint on what's missing. I hope I could pinpoint all the relevant information to idicate my versin of the problem. Any hint would be highly appreciated.

But the call to get the API access token always returns

AADSTS65001: The user or administrator has not consented to use the application with ID '[app id here]' named '[app name here]'. Send an interactive authorization request for this user and resource.

Solution

  • From the error message, it appears that you haven't granted consent to the add-in, either as an administrator or a user.

    Try deploying this add-in as an administrator, which will result a request for consent UI that you can use to handle consent.

    Afterwards, you have to wait for about 72 hours for the add-in deployment to reflect in user mailboxes, and then you can proceed with validating your business logic.