title: IdentityServer4 claims are not part of the token on hybrid flow
body: <p>I'm trying to build a hybrid flow, and have claims on the returned access token with IdentityServer4. I'm using the <a href="https://github.com/IdentityServer/IdentityServer4.Quickstart.UI" rel="nofollow noreferrer">QuickStart UI</a> controlles.</p>
  
  <p>In my <code>AccountController</code> after the user was authenticated successfully, I have the following code which signs him in:</p>
  
  <pre><code>await HttpContext.SignInAsync("anon@nymous.com", "anon@nymous.com", null, new Claim("MyName", "Ophir"));
  </code></pre>
  
  <p>In the MVC website that is causing this flow, on the page I want to "protect" I have the following code:</p>
  
  <pre><code>[Authorize]
  public IActionResult RestrictedMvcResource()
  {
         var token = _httpContext.HttpContext.GetTokenAsync("access_token").Result;
         var identity = User.Identity;
         return View();
  }
  </code></pre>
  
  <p>After a successful login, the debugger hits this code fine and I'm getting the access token.</p>
  
  <p>The problem is that if I decode my access token (I'm using <a href="https://jwt.io/" rel="nofollow noreferrer">https://jwt.io/</a>) I see the name and subject, but I do not see the <code>MyName</code> claim that I have defined.</p>
  
  <p>(I have another flow in my system for <code>client_credentials</code> which does return the claims on the token - but it uses a different code flow).</p>
  
  <p>How do I return the claims on the token for the hybrid flow?</p>
  
  <p><strong>EDIT:</strong></p>
  
  <p>Solving this problem was a combination of 2 things:</p>
  
  <ol>
  <li>Implementing <code>IProfileService</code> as suggested in (selected) answer. here's my implementation:</li>
  </ol>
  
  <pre><code>public class ProfileService : IProfileService
  {
      public Task GetProfileDataAsync(ProfileDataRequestContext context)
      {
          context.AddRequestedClaims(context.Subject.Claims);
  
          foreach (Claim claim in context.Subject.Claims)
          {
              if (context.IssuedClaims.Contains(claim))
                  continue;
  
              context.IssuedClaims.Add(claim);
          }
  
          return Task.FromResult(0);
      }
  
      public Task IsActiveAsync(IsActiveContext context)
      {
          context.IsActive = true;
          return Task.FromResult(0);
      }
  }
  </code></pre>
  
  <p>This will add any claim that isn't already on the token.</p>
  
  <ol start="2">
  <li>When calling <code>HttpContext.SignInAsync</code> you must pass the list of claims, otherwise no additional claims will be in the <code>context.Subject.Claims</code> collection.</li>
  </ol>