1

I want Access token in sharepoint Hosted addin in order to consume Microsoft Graph Api. When I hit Access Token Api (https://login.microsoftonline.com/dimensiondata2.onmicrosoft.com/oauth2/token) using Postman I am able to get access token, But using code, I am getting 401 unauthorized error. I refer this Documentation

Following is the error:-[ { "SchemaVersion":"15.0.0.0","LibraryVersion":"16.0.8412.1210","ErrorInfo":null,"TraceCorrelationId":"7e4eb29e-c011-0000-1892-c2fb5c7aa49d" },2,{ "_ObjectType_":"SP.WebResponseInfo","Body":"The remote server returned the following error while establishing a connection - 'Unauthorized'.","Headers":null,"StatusCode":401 } ]

This is How i created Request object:-

var context = SP.ClientContext.get_current();
        var request = new SP.WebRequestInfo();
         var body = "client_id=" + client_id + "&client_secret=" + client_secret + "&resource=" + resource + "&grant_type=" + grant;
        request.set_url(
            "https://login.microsoftonline.com/companyname.onmicrosoft.com/oauth2/token"
        );

        // We need the response formatted as JSON.
    request.set_headers({"Content-Type": "application/x-www-form-urlencoded" });

        request.set_method("POST");
        request.set_body(body);
        var response = SP.WebProxy.invoke(context, request);

In my AppManifest.xml I have added following EndPoint:-

<RemoteEndpoints>
<RemoteEndpoint Url="https://login.microsoftonline.com/domainname.onmicrosoft.com/oauth2/token" />
</RemoteEndpoints>

1 Answer 1

1

Disclaimer
In general, from a security perspective, it's a bad idea to store a client secret in javascript (browser), like in SharePoint hosted app scenario. Make sure you understand what you're doing.

Below code works for me (I've modified OOB one generated by VS when you select SharePoint add-in):

'use strict';

ExecuteOrDelayUntilScriptLoaded(initializePage, "sp.js");

function initializePage()
{
    var context = SP.ClientContext.get_current();
    var user = context.get_web().get_currentUser();
    var request = new SP.WebRequestInfo();
    var response;
    // This code runs when the DOM is ready and creates a context object which is needed to use the SharePoint object model
    $(document).ready(function () {
        getUserName();
    });

    // This function prepares, loads, and then executes a SharePoint query to get the current users information
    function getUserName() {
        context.load(user);

        var body = "client_id=" + client_id + "&client_secret=" + encodeURIComponent(client_secret) + "&resource=" + "https://graph.microsoft.com" + "&grant_type=" + "client_credentials";
        request.set_url(
            "https://login.microsoftonline.com/company.onmicrosoft.com/oauth2/token"
        );

        // We need the response formatted as JSON.
        request.set_headers({"Content-Type": "application/x-www-form-urlencoded" });

        request.set_method("POST");
        request.set_body(body);
        response = SP.WebProxy.invoke(context, request);

        context.executeQueryAsync(onGetUserNameSuccess, onGetUserNameFail);
    }

    // This function is executed if the above call is successful
    // It replaces the contents of the 'message' element with the user name
    function onGetUserNameSuccess() {
        console.log(response);
        $('#message').text('Hello ' + user.get_title());
    }

    // This function is executed if the above call fails
    function onGetUserNameFail(sender, args) {
        alert('Failed to get user name. Error:' + args.get_message());
    }
}

Please take a note on a few things:
In your AppManifest.xml add below endpoint:

<RemoteEndpoints>
    <RemoteEndpoint Url="https://login.microsoftonline.com" />
</RemoteEndpoints> 

Also, I guess you missed & sign between body parameters, consider my example:

var body = "client_id=" + client_id + "&client_secret=" + encodeURIComponent(client_secret) + "&resource=" + "https://graph.microsoft.com" + "&grant_type=" + "client_credentials";  

And finally, encode client secret, because it might contain special symbols:

encodeURIComponent(client_secret)
3
  • Sorry, my bad, I have not provided full detail what I was doing, I have Edited my Question...... only missing was encodeURIComponent(client_secret).... & maybe I was adding wrong endpoint, will try by adding endpoints mention in your answer & let you know whether it's working or not Commented Jan 4, 2019 at 5:38
  • all I need to do was, to encode client_secret Commented Jan 4, 2019 at 12:19
  • Hi Sergei, Currently I am using Graph api to Add member into Office groups... I am getting same error.. I have tried by encoding body as well as without encoding... still having same error... I have refer this:- docs.microsoft.com/en-us/graph/api/… Commented Jan 30, 2019 at 13:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.