title: Identity Server 4 Authorization Code Flow with Client Credentials (allowing one client instance deny another)
body: <p>What I got so far:</p>
  
  <p>In a project I have an authorization server (Identity Server 4), some (let's say two) protected APIs (Api Resource) and some trusted clients (automated, no user interaction) which should access the Identity Server via the backchannel (right?). Imagine the client is a Amazon Fire TV box kind thingy.</p>
  
  <p>According to what I have read so far over the last weeks a suitable flow for this scenario is the <strong>OpenID Connect Authorization Code Flow</strong>.</p>
  
  <ul>
  <li>clients are trusted (and can maintain a secret)</li>
  <li>Authorization Code flow supports refresh tokens (which I want to use)</li>
  <li>the client is actually not the resource owner but requires access to the full api resource</li>
  </ul>
  
  <hr>
  
  <p>What I have in my (theoretical) structure:</p>
  
  <p>I have two API Resources (one resource for each API version)</p>
  
  <ul>
  <li>api.v1</li>
  <li>api.v2</li>
  </ul>
  
  <p>I also have two series of my API clients</p>
  
  <ul>
  <li>client.v1 supports only api v1 &amp; should only have access to api.v1 resource</li>
  <li>client.v2 supports api v1 &amp; v2 and therefore should have access to both api resources</li>
  </ul>
  
  <hr>
  
  <p>Identity Server 4 StartUp.cs configuration (so far)</p>
  
  <pre><code>public void ConfigureServices(IServiceCollection services)
  {
      // configure identity server with in-memory stores, keys, clients and scopes
      services.AddIdentityServer()
          .AddDeveloperSigningCredential()
          .AddInMemoryApiResources
          ( 
              new List&lt;ApiResource&gt;
              {
                  new ApiResource("api.v1", "API v1"),
                  new ApiResource("api.v2", "API v2")
              }
          )
          .AddInMemoryClients
          (
              new List&lt;Client&gt;
              {
                  new Client
                  {
                      ClientId = "client.v1",
                      AllowedGrantTypes = GrantTypes.CodeAndClientCredentials,
                      AllowAccessTokensViaBrowser = false,
                      ClientSecrets = { new Secret("secret1".Sha256()) },
                      AllowedScopes = { "api.v1" }
                  },
                  new Client
                  {
                      ClientId = "client.v2",
                      AllowedGrantTypes = GrantTypes.CodeAndClientCredentials,
                      AllowAccessTokensViaBrowser = false,
                      ClientSecrets = { new Secret("secret2".Sha256()) },
                      AllowedScopes = { "api.v1", "api.v2" }
                  }
              }
          );
  }
  </code></pre>
  
  <hr>
  
  <p>The theory what I am struggling with is the authorization code part.</p>
  
  <p>I want to have each client instance (again imagine it as a small box) a different authorization code allowing one instance access but deny fo another one.</p>
  
  <p>Is the authorization code intended to be used for that?</p>
  
  <p>And one important thing I haven't understood in all the time: CodeAndClientCredentials defines two grant types. Does this mean connecting with that requires both (code <strong>AND</strong> client credentials) or is it an one of them definition (code <strong>OR</strong> client credentials).</p>
  
  <hr>
  
  <p>The Identity Server 4 code I am struggling with is:</p>
  
  <p>In the code defining the client I can only find AuthorizationCodeLifetime but no field to set the authorization code itself.</p>
  
  <p>It seems I can define a list of client secrets.</p>
  
  <pre><code>ClientSecrets = { new Secret("secret1".Sha256()) },
  </code></pre>
  
  <p>Does this mean one client Id can have multiple secrets used? Are different client secrets better suitable for my "allow one deny the other" problem?</p>
  
  <hr>
  
  <h2>Edit</h2>
  
  <p>Ok, I have re-read that and now I got it (at least a bit more): the authorization code is not defined sent by the client but the client receives it.</p>
  
  <blockquote>
    <p>The authorization code flow returns an authorization code (like it says on the tin) that can then be exchanged for an identity token and/or access token. This requires client authentication using a client id and secret to retrieve the tokens from the back end</p>
  </blockquote>
  
  <p>from <a href="https://www.scottbrady91.com/OpenID-Connect/OpenID-Connect-Flows" rel="nofollow noreferrer">this blog here</a></p>
  
  <p>But how would I have to configure my Identity Server to allow one instance and deny another.</p>
  
  <p>By using different client secrets? Using <a href="http://docs.identityserver.io/en/release/topics/extension_grants.html" rel="nofollow noreferrer">extension grants</a>?</p>