title: Why does adding "offline_access" invalidate MS Graph scope and how do I otherwise get a refresh token?
body: <p>I'm trying to request an access token and a refresh token from Microsoft Graph, but adding "offline_access" to the scope makes the scope invalid.</p>
  
  <p>This is for a service where a user gives us access to an Outlook Calendar once and after that the service checks their calendar every 20 minutes for events. I have managed to get consent and pull data when requesting access to "User.Read" and "<code>Calendars.Read</code>", but when I add "<code>offline_access</code>" I get the message <code>The provided resource value for the input parameter 'scope' is not valid.</code> </p>
  
  <p>I have an array with the permissions I want</p>
  
  <pre class="lang-java prettyprint-override"><code>private static final String[] ACCESS_PERMISSIONS = {
              "https://graph.microsoft.com/User.Read",
              "https://graph.microsoft.com/Calendars.Read",
              "https://graph.microsoft.com/offline_access",
      };
  
  </code></pre>
  
  <p>and then combine and encode them</p>
  
  <pre class="lang-java prettyprint-override"><code>String encodedScope = URLEncoder.encode(
  Arrays.stream(ACCESS_PERMISSIONS)
  .reduce(
  (a,b) -&gt; a + " " + b)
  .get(), "UTF-8").replace("+","%20");
  </code></pre>
  
  <p>which results in the string <code>https%3A%2F%2Fgraph.microsoft.com%2FUser.Read%20https%3A%2F%2Fgraph.microsoft.com%2FCalendars.Read%20https%3A%2F%2Fgraph.microsoft.com%2Foffline_access</code>
  Then I request the tokens</p>
  
  <pre class="lang-java prettyprint-override"><code>String appId = "client_id=" + clientID;
  String scope = "&amp;scope=" + encodedScope;
  String authCode = "&amp;code=" + code;
  String redirect = "&amp;redirect_uri=" + redirectUri;
  String grantType = "&amp;grant_type=authorization_code";
  String secret = "&amp;client_secret=" + clientSecret;
  
  String data = appId + scope + authCode + redirect + grantType + secret;
  
  // Create POST request
  URL url = new URL(postUrl);
  HttpURLConnection connection = (HttpURLConnection) url.openConnection();
  
  // Configure request
  connection.setRequestMethod("POST");
  connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
  connection.setRequestProperty("Accept", "application/json");
  connection.setDoOutput(true);
  
  // Send data
  OutputStream os = connection.getOutputStream();
  byte[] inputBytes = data.getBytes(ENCODING);
  os.write(inputBytes, 0, inputBytes.length); // Bytes, Offset, Length
  </code></pre>
  
  <p>The final link then looks like</p>
  
  <pre><code>https://login.microsoftonline.com/common/oauth2/v2.0/authorize?
  client_id=[CLIENT ID]
  &amp;response_type=code
  &amp;redirect_uri=http%3A%2F%2Flocalhost%3A8080%2Fsport%2Fauth%2Foutlook
  &amp;response_mode=query
  &amp;scope=https%3A%2F%2Fgraph.microsoft.com%2FUser.Read%20https%3A%2F%2Fgraph.microsoft.com%2FCalendars.Read%20https%3A%2F%2Fgraph.microsoft.com%2Foffline_access
  &amp;state=2737
  </code></pre>
  
  <p>I would expect this to return an access token and a refresh token, but as previously mentioned I get the message that the resource value for the scope is not valid.</p>
  
  <p>It is essential for the service to be able to refresh the tokens as it should run about a year without intervention.</p>