title: MSAL and Azure AD: What scopes should I pass when I just want to get the user ID?
body: <p>I'm using MSAL to get an ID Token which is then used to access an Web API app. I've got a couple of questions and I was wondering if someone could help me understand what's going on.</p>
  
  <p>Let me start with the authentication process in the client side. In this case, I'm building a Windows Forms app that is using the following code in order to authenticate the current user (ie, in order to get an ID Token which will be used to validate the user when he tries to access a Web API app):</p>
  
  <pre><code>//constructor code
  _clientApp = new PublicClientApplication(ClientId, 
                    Authority, //which url here?
                    TokenCacheHelper.GetUserCache());
  _scopes = new []{ "user.read" }; //what to put here?
  
   //inside a helper method
   try {
        return await _clientApp.AcquireTokenSilentAsync(_scopes, _clientApp.Users.FirstOrDefault());
   }
   catch (MsalUiRequiredException ex) {
    try {
              return await _clientApp.AcquireTokenAsync(_scopes);
          }
          catch (MsalException ex) {
              return null;
          }
   }
  </code></pre>
  
  <p>The first thing I'd like to clear is the value that should be used for the authority parameter. In this case, I'm using an URL on the form:</p>
  
  <pre><code>https://login.microsoftonline.com/{Tenant}/oauth2/v2.0/token
  </code></pre>
  
  <p>However, I'm under the impression that I could also get away with something like this:</p>
  
  <p><a href="https://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration" rel="noreferrer">https://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration</a></p>
  
  <p>It seems like one endpoint is specific to my Azure AD while the other looks like a general (catch all) URL...Where can I find more information about these endpoints and on what's the purpose of each...</p>
  
  <p>Another thing that I couldn't quite grasp is the scope. I'm not interested in querying MS Graph (or any other Azure related service for that matter). In previous versions of the MSAL library, it was possible to reference one of the default scopes. However, it seems like that is no longer possible (at least, I tried and got an exception saying that I shouldn't pass the default scopes...).</p>
  
  <p>Passing an empty collection (ex.: <code>new List&lt;string&gt;()</code>) or <code>null</code> will also result in an error. So, in this case, I've ended passing the <code>user.read</code> scope (which, if I'm not mistaken, is used by MS Graph API. This is clearly not necessary, but was the only way I've managed to get the authentication process working. Any clues on how to perform the call when you just need to get an ID Token? Should I be calling a different method?</p>
  
  <p>Moving to the server side, I've got a Web API app whose access is limited to calls that pass an ID token in the authentication header (bearer). According to this <a href="https://github.com/AzureADQuickStarts/AppModelv2-WebAPI-DotNet" rel="noreferrer">sample</a>, I should use something like this:</p>
  
  <pre><code>private void ConfigureAuth(IAppBuilder app) {
     var authority = "https://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration";
     app.UseOAuthBearerAuthentication(
         new OAuthBearerAuthenticationOptions {
            AccessTokenFormat = new JwtFormat(GetTokenValidationParameters(),
                      new OpenIdConnectCachingSecurityTokenProvider(authority)),
                                              Provider = new OAuthBearerAuthenticationProvider {
                                                       OnValidateIdentity = ValidateIdentity
                                              }
                                             });
   }
  </code></pre>
  
  <p>Now, this does work and it will return 401 for all requests which don't have a valid ID Token. There is one question though: is there a way to specify the claim from the Ticket's Identity that should be used for identifying the username (<code>User.Identity.Name</code> of the controller)? In this case, I've ended handling the <code>OnValidateIdentity</code> in order to do that with code that looks like this:</p>
  
  <pre><code>private Task ValidateIdentity(OAuthValidateIdentityContext arg) {
      //username not getting correctly filled
      //so, i'm handling this event in order to set it up 
      //from the preferred_username claim
      if (!arg.HasError &amp;&amp; arg.IsValidated) {
          var identity = arg.Ticket.Identity;
          var username = identity.Claims.FirstOrDefault(c =&gt; c.Type == "preferred_username")?.Value ?? "";
          if (!string.IsNullOrEmpty(username)) {
              identity.AddClaim(new Claim(ClaimTypes.Name, username));
          }
      }
      return Task.CompletedTask;
  }
  </code></pre>
  
  <p>As you can see, I'm searching for the preferred_username claim from the ID Token (which was obtained by the client) and using its value to setup the Name claim. Is there any option that would let me do this automatically? Am I missing something in the configuration of the <code>OAuthBearerAuthenticationMiddleware</code>?</p>