title: How to add custom headers to an open id connect authentication request in OWIN middleware
body: <p>I have a system where I have an MVC website calling a web api. I have used OAUTH and OPENID Connect for my authentication/authorization. I have setup an identity server in another web api project using Thinktecture's IdentityServer3. In the MVC project I am doing the redirect to the identity server in the OWIN Startup class. This is all pretty standard stuff and is working fine. </p>
  
  <p>I have now been asked to put the web api and the identity server behind Azure API Management. This also, is fine as all I need to do from my MVC project is add my subscription key from API management as a header ("Ocp-Apim-Subscription-Key") to any request to the web api. So far so good. </p>
  
  <p>The problem is I now need to add this header to any requests to the identity server and I can't work out how, other than writing my own middleware. My Startup class looks like this:</p>
  
  <pre><code>public class Startup
  {
      public void Configuration(IAppBuilder app)
      {
          DependencyResolver.SetResolver(new SimpleInjectorDependencyResolver(IocHelper.GetContainer()));
  
          JwtSecurityTokenHandler.InboundClaimTypeMap = new Dictionary&lt;string, string&gt;();
  
          app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
  
          app.UseCookieAuthentication(new CookieAuthenticationOptions
          {
              AuthenticationType = "Cookies"
          });
  
          app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
          {
              ClientId = ConfigurationHelper.GetClientId(),
              Authority = ConfigurationHelper.GetSecurityTokenServiceUrl(),
              RedirectUri = ConfigurationHelper.GetPortalHomePageUrl(),
              PostLogoutRedirectUri = ConfigurationHelper.GetPortalHomePageUrl(),
              ResponseType = "code id_token",
              Scope = "openid profile public_api",
              TokenValidationParameters = new TokenValidationParameters
              {
                  NameClaimType = "name",
                  RoleClaimType = "role"
              },
  
              SignInAsAuthenticationType = "Cookies",
  
  
              Notifications = new OpenIdConnectAuthenticationNotifications
              {
                  AuthorizationCodeReceived = async n =&gt;
                  {
                      // use the code to get the access and refresh token
                      var tokenClient = new TokenClient(ConfigurationHelper.GetTokenEndpointUrl(), ConfigurationHelper.GetClientId(), ConfigurationHelper.GetClientSecret());
                      var tokenResponse = await tokenClient.RequestAuthorizationCodeAsync(n.Code, n.RedirectUri);
                      if (tokenResponse.IsError)
                      {
                          throw new Exception(tokenResponse.Error);
                      }
  
                      // use the access token to retrieve claims from userinfo
                      var userInfoClient = new UserInfoClient(ConfigurationHelper.GetUserInfoUrl());
                      var userInfoResponse = await userInfoClient.GetAsync(tokenResponse.AccessToken);
                      if (userInfoResponse.IsError)
                      {
                          throw new Exception(userInfoResponse.Error);
                      }
  
                      // create new identity
                      var id = new ClaimsIdentity(n.AuthenticationTicket.Identity.AuthenticationType);
                      foreach (var c in userInfoResponse.Claims)
                      {
                          id.AddClaim(new Claim(c.Type, c.Value));
                      }
  
                      id.AddClaim(new Claim("access_token", tokenResponse.AccessToken));
                      id.AddClaim(new Claim("expires_at", DateTime.Now.AddSeconds(tokenResponse.ExpiresIn * 2).ToLocalTime().ToString(CultureInfo.InvariantCulture)));
                      id.AddClaim(new Claim("id_token", n.ProtocolMessage.IdToken));
                      id.AddClaim(new Claim("sid", n.AuthenticationTicket.Identity.FindFirst("sid").Value));
  
  
                      var claimsIdentity = new ClaimsIdentity(id.Claims, n.AuthenticationTicket.Identity.AuthenticationType, "name", "role");
                      //claimsIdentity.IsAuthenticated = true;
                      n.AuthenticationTicket = new AuthenticationTicket(claimsIdentity, n.AuthenticationTicket.Properties);
                  },
                  RedirectToIdentityProvider = n =&gt;
                  {
                      // if signing out, add the id_token_hint
                      if (n.ProtocolMessage.RequestType != OpenIdConnectRequestType.LogoutRequest)
                      {
                          return Task.FromResult(0);
                      }
  
                      var idTokenHint = n.OwinContext.Authentication.User.FindFirst("id_token");
  
                      if (idTokenHint != null)
                      {
                          n.ProtocolMessage.IdTokenHint = idTokenHint.Value;
                      }
  
                      // DOESN'T WORK
                      n.OwinContext.Request.Headers.Append("Ocp-Apim-Subscription-Key", "MY KEY GOES HERE");
  
                      // ALSO DOESN'T WORK
                      n.Request.Headers.Append("Ocp-Apim-Subscription-Key", "MY KEY GOES HERE");
  
                      return Task.FromResult(0);
                  }
              }
          });
      }
  }
  </code></pre>
  
  <p>Is there a way to hi-jack the request to the identity server and add my own header in there?</p>