title: GET https://graph.microsoft.com/v1.0/me returns 401 (Unauthorized) given a valid access token with User.Read permission
body: <p>I generate an access token using 'simple-oauth2' that looks like this</p>
  <pre><code>import { AuthorizationCode } from 'simple-oauth2';
  
  scopes = ['offline_access', 'https://outlook.office.com/IMAP.AccessAsUser.All',
            'https://outlook.office.com/SMTP.Send','User.Read'];
  
  async getCredentials(code: string) {
      const client = new AuthorizationCode(this.oauthConfig);
  
      let tokenParams = {
          code,
          redirect_uri: config.MICROSOFT_CREDENTIALS.REDIRECT_URIS[0],
          scope: this.scopes.join(' ')
      }
  
      return await client.getToken(tokenParams)
  };
  
  // Result from getCredentials
  AccessToken {
    token: {
      token_type: 'Bearer',
      scope: 'https://outlook.office.com/IMAP.AccessAsUser.All https://outlook.office.com/SMTP.Send https://outlook.office.com/User.Read',
      expires_in: 3599,
      ext_expires_in: 3599,
      access_token: 'eyJ0eXAiOiJKV1QiLCJub25jZSI6I...',
      refresh_token: '0.ATUAd-LjmxfEgkWp0wIFCKwhpRA-z-...',     
      expires_at: 2020-09-25T01:13:08.970Z
    }
  }
  </code></pre>
  <p>Following this <a href="https://docs.microsoft.com/en-us/graph/auth-v2-user" rel="nofollow noreferrer">guide</a>, I then pass the access_token field to a GET request to <a href="https://graph.microsoft.com/v1.0/me" rel="nofollow noreferrer">https://graph.microsoft.com/v1.0/me</a></p>
  <pre><code>getUserProfile(accessToken: string) {
       return axios.get(&quot;https://graph.microsoft.com/v1.0/me&quot;, {
           headers: {
              Authorization: 'Bearer ' + accessToken,
              'Content-Type': 'application/json'
          }
       })
       .then((res) =&gt; {
           return res.data;
       })
       .catch((reason) =&gt; {
           console.log(&quot;getUserProfile failed&quot;);
           console.log(reason);
       })
  };
  </code></pre>
  <p>This fails with the following error</p>
  <pre><code>getUserProfile failed
  Error: Request failed with status code 401
      at createError (C:\Users\me\Desktop\projects\proj\node_modules\axios\lib\core\createError.js:16:15)
      at settle (C:\Users\me\Desktop\projects\proj\node_modules\axios\lib\core\settle.js:17:12)
      at IncomingMessage.handleStreamEnd (C:\Users\me\Desktop\projects\proj\node_modules\axios\lib\adapters\http.js:236:11)
      at IncomingMessage.emit (events.js:323:22)
      at IncomingMessage.EventEmitter.emit (domain.js:482:12)
      at endReadableNT (_stream_readable.js:1204:12)
      at processTicksAndRejections (internal/process/task_queues.js:84:21) {
    config: {
      url: 'https://graph.microsoft.com/v1.0/me',
      method: 'get',
      headers: {
        Accept: 'application/json, text/plain, */*',
        Authorization: 'Bearer eyJ0eXAiOiJKV1QiLCJub25jZSI6IjByZ0t3MFRLOEF...',
        'Content-Type': 'application/json',
        'User-Agent': 'axios/0.19.2'
      },
      transformRequest: [ [Function: transformRequest] ],
      transformResponse: [ [Function: transformResponse] ],
      timeout: 0,
      adapter: [Function: httpAdapter],
      xsrfCookieName: 'XSRF-TOKEN',
      xsrfHeaderName: 'X-XSRF-TOKEN',
      maxContentLength: -1,
      validateStatus: [Function: validateStatus],
      data: undefined
    },
    request: ClientRequest {
      _events: [Object: null prototype] {
        socket: [Function],
        abort: [Function],
        aborted: [Function],
        error: [Function],
        timeout: [Function],
        prefinish: [Function: requestOnPrefinish]
      },
      _eventsCount: 6,
      _maxListeners: undefined,
      outputData: [],
      outputSize: 0,
      writable: true,
      _last: true,
      chunkedEncoding: false,
      shouldKeepAlive: false,
      useChunkedEncodingByDefault: false,
      sendDate: false,
      _removedConnection: false,
      _removedContLen: false,
      _removedTE: false,
      _contentLength: 0,
      _hasBody: true,
      _trailer: '',
      finished: true,
      _headerSent: true,
      socket: TLSSocket {
        _tlsOptions: [Object],
        _secureEstablished: true,
        _securePending: false,
        _newSessionPending: false,
        _controlReleased: true,
        _SNICallback: null,
        servername: 'graph.microsoft.com',
        alpnProtocol: false,
        authorized: true,
        authorizationError: null,
        encrypted: true,
        _events: [Object: null prototype],
        _eventsCount: 9,
        connecting: false,
        _hadError: false,
        _parent: null,
        _host: 'graph.microsoft.com',
        _readableState: [ReadableState],
        readable: true,
        _maxListeners: undefined,
        _writableState: [WritableState],
        writable: false,
        allowHalfOpen: false,
        _sockname: null,
        _pendingData: null,
        _pendingEncoding: '',
        server: undefined,
        _server: null,
        ssl: [TLSWrap],
        _requestCert: true,
        _rejectUnauthorized: true,
        parser: null,
        _httpMessage: [Circular],
        [Symbol(res)]: [TLSWrap],
        [Symbol(asyncId)]: 1233,
        [Symbol(kHandle)]: [TLSWrap],
        [Symbol(lastWriteQueueSize)]: 0,
        [Symbol(timeout)]: null,
        [Symbol(kBuffer)]: null,
        [Symbol(kBufferCb)]: null,
        [Symbol(kBufferGen)]: null,
        [Symbol(kCapture)]: false,
        [Symbol(kBytesRead)]: 0,
        [Symbol(kBytesWritten)]: 0,
        [Symbol(connect-options)]: [Object]
      },
      connection: TLSSocket {
        _tlsOptions: [Object],
        _secureEstablished: true,
        _securePending: false,
        _newSessionPending: false,
        _controlReleased: true,
        _SNICallback: null,
        servername: 'graph.microsoft.com',
        alpnProtocol: false,
        authorized: true,
        authorizationError: null,
        encrypted: true,
        _events: [Object: null prototype],
        _eventsCount: 9,
        connecting: false,
        _hadError: false,
        _parent: null,
        _host: 'graph.microsoft.com',
        _readableState: [ReadableState],
        readable: true,
        _maxListeners: undefined,
        _writableState: [WritableState],
        writable: false,
        allowHalfOpen: false,
        _sockname: null,
        _pendingData: null,
        _pendingEncoding: '',
        server: undefined,
        _server: null,
        ssl: [TLSWrap],
        _requestCert: true,
        _rejectUnauthorized: true,
        parser: null,
        _httpMessage: [Circular],
        [Symbol(res)]: [TLSWrap],
        [Symbol(asyncId)]: 1233,
        [Symbol(kHandle)]: [TLSWrap],
        [Symbol(lastWriteQueueSize)]: 0,
        [Symbol(timeout)]: null,
        [Symbol(kBuffer)]: null,
        [Symbol(kBufferCb)]: null,
        [Symbol(kBufferGen)]: null,
        [Symbol(kCapture)]: false,
        [Symbol(kBytesRead)]: 0,
        [Symbol(kBytesWritten)]: 0,
        [Symbol(connect-options)]: [Object]
      },
      _header: 'GET /v1.0/me HTTP/1.1\r\n' +
        'Accept: application/json, text/plain, */*\r\n' +
        'Authorization: Bearer eyJ0eXAiOiJKV1QiLCJub25jZSI6IjByZ0t...\r\n' +
        'Content-Type: application/json\r\n' +
        'User-Agent: axios/0.19.2\r\n' +
        'Host: graph.microsoft.com\r\n' +
        'Connection: close\r\n' +
        '\r\n',
      _onPendingData: [Function: noopPendingOutput],
      agent: Agent {
        _events: [Object: null prototype],
        _eventsCount: 2,
        _maxListeners: undefined,
        defaultPort: 443,
        protocol: 'https:',
        options: [Object],
        requests: {},
        sockets: [Object],
        freeSockets: {},
        keepAliveMsecs: 1000,
        keepAlive: false,
        maxSockets: Infinity,
        maxFreeSockets: 256,
        maxCachedSessions: 100,
        _sessionCache: [Object],
        [Symbol(kCapture)]: false
      },
      socketPath: undefined,
      method: 'GET',
      insecureHTTPParser: undefined,
      path: '/v1.0/me',
      _ended: true,
      res: IncomingMessage {
        _readableState: [ReadableState],
        readable: false,
        _events: [Object: null prototype],
        _eventsCount: 3,
        _maxListeners: undefined,
        socket: [TLSSocket],
        connection: [TLSSocket],
        httpVersionMajor: 1,
        httpVersionMinor: 1,
        httpVersion: '1.1',
        complete: true,
        headers: [Object],
        rawHeaders: [Array],
        trailers: {},
        rawTrailers: [],
        aborted: false,
        upgrade: false,
        url: '',
        method: null,
        statusCode: 401,
        statusMessage: 'Unauthorized',
        client: [TLSSocket],
        _consuming: false,
        _dumped: false,
        req: [Circular],
        responseUrl: 'https://graph.microsoft.com/v1.0/me',
        redirects: [],
        [Symbol(kCapture)]: false
      },
      aborted: false,
      timeoutCb: null,
      upgradeOrConnect: false,
      parser: null,
      maxHeadersCount: null,
      reusedSocket: false,
      _redirectable: Writable {
        _writableState: [WritableState],
        writable: true,
        _events: [Object: null prototype],
        _eventsCount: 2,
        _maxListeners: undefined,
        _options: [Object],
        _redirectCount: 0,
        _redirects: [],
        _requestBodyLength: 0,
        _requestBodyBuffers: [],
        _onNativeResponse: [Function],
        _currentRequest: [Circular],
        _currentUrl: 'https://graph.microsoft.com/v1.0/me',
        [Symbol(kCapture)]: false
      },
      [Symbol(kCapture)]: false,
      [Symbol(kNeedDrain)]: false,
      [Symbol(corked)]: 0,
      [Symbol(kOutHeaders)]: [Object: null prototype] {
        accept: [Array],
        authorization: [Array],
        'content-type': [Array],
        'user-agent': [Array],
        host: [Array]
      }
    },
    response: {
      status: 401,
      statusText: 'Unauthorized',
      headers: {
        'cache-control': 'private',
        'content-type': 'application/json',
        'request-id': '6026815f-6c31-48c3-9b70-a6eb3cda8e44',
        'client-request-id': '6026815f-6c31-48c3-9b70-a6eb3cda8e44',
        'x-ms-ags-diagnostic': '{&quot;ServerInfo&quot;:{&quot;DataCenter&quot;:&quot;West US&quot;,&quot;Slice&quot;:&quot;SliceC&quot;,&quot;Ring&quot;:&quot;5&quot;,&quot;ScaleUnit&quot;:&quot;002&quot;,&quot;RoleInstance&quot;:&quot;AGSFE_IN_13&quot;}}',
        'www-authenticate': 'Bearer realm=&quot;&quot;, authorization_uri=&quot;https://login.microsoftonline.com/common/oauth2/authorize&quot;, client_id=&quot;00000003-0000-0000-c000-000000000000&quot;',
        'strict-transport-security': 'max-age=31536000',
        date: 'Fri, 25 Sep 2020 00:13:11 GMT',
        connection: 'close',
        'content-length': '330'
      },
      config: {
        url: 'https://graph.microsoft.com/v1.0/me',
        method: 'get',
        headers: [Object],
        transformRequest: [Array],
        transformResponse: [Array],
        timeout: 0,
        adapter: [Function: httpAdapter],
        xsrfCookieName: 'XSRF-TOKEN',
        xsrfHeaderName: 'X-XSRF-TOKEN',
        maxContentLength: -1,
        validateStatus: [Function: validateStatus],
        data: undefined
      },
      request: ClientRequest {
        _events: [Object: null prototype],
        _eventsCount: 6,
        _maxListeners: undefined,
        outputData: [],
        outputSize: 0,
        writable: true,
        _last: true,
        chunkedEncoding: false,
        shouldKeepAlive: false,
        useChunkedEncodingByDefault: false,
        sendDate: false,
        _removedConnection: false,
        _removedContLen: false,
        _removedTE: false,
        _contentLength: 0,
        _hasBody: true,
        _trailer: '',
        finished: true,
        _headerSent: true,
        socket: [TLSSocket],
        connection: [TLSSocket],
        _header: 'GET /v1.0/me HTTP/1.1\r\n' +
          'Accept: application/json, text/plain, */*\r\n' +
          'Authorization: Bearer eyJ0eXAiOiJKV1QiLCJub25jZSI6IjByZ0...\r\n' +
          'Content-Type: application/json\r\n' +
          'User-Agent: axios/0.19.2\r\n' +
          'Host: graph.microsoft.com\r\n' +
          'Connection: close\r\n' +
          '\r\n',
        _onPendingData: [Function: noopPendingOutput],
        agent: [Agent],
        socketPath: undefined,
        method: 'GET',
        insecureHTTPParser: undefined,
        path: '/v1.0/me',
        _ended: true,
        res: [IncomingMessage],
        aborted: false,
        timeoutCb: null,
        upgradeOrConnect: false,
        parser: null,
        maxHeadersCount: null,
        reusedSocket: false,
        _redirectable: [Writable],
        [Symbol(kCapture)]: false,
        [Symbol(kNeedDrain)]: false,
        [Symbol(corked)]: 0,
        [Symbol(kOutHeaders)]: [Object: null prototype]
      },
      data: { error: [Object] }
    },
    isAxiosError: true,
    toJSON: [Function]
  </code></pre>
  <p><a href="https://docs.microsoft.com/en-us/graph/api/user-get?view=graph-rest-1.0&amp;tabs=javascript" rel="nofollow noreferrer">Documentation</a> for /me and the <a href="https://docs.microsoft.com/en-us/graph/auth-v2-user" rel="nofollow noreferrer">guide</a> states I just need <code>User.Read</code> for my permissions and that my <code>headers</code> are correct so I do not know why it is failing. The Microsoft account I am using for testing is a Work Account.</p>
  <p>I have briefly tried using the Graph SDK but I feel like this approach is 99% of the way there.</p>
  <p>Big picture wise I am trying to save the user's email address so I can use the OAuth2 token to connect to O365 through IMAP and SMTP. If I hardcode what I know the email address to be everything works so automating the retrieval of the user's email address through Graphs is the last thing I need.</p>