title: Web API 2 identity. /Token Always return 404 error
body: <p>I have some problems with adopt Web API 2 Identity. In project. </p>
  
  <p>I add StartUp.cs</p>
  
  <p>Like this:</p>
  
  <pre><code>using Microsoft.Owin;
  using Owin;
  
  [assembly: OwinStartup(typeof(MyNamespace.Startup))]
  namespace MyNamespace
  {
      public partial class Startup
          {
              public void Configuration(IAppBuilder app)
              {
                  ConfigureAuth(app);
              }
          }
  }
  </code></pre>
  
  <p></p>
  
  <p>After that I add partial class for enable Token authorization:</p>
  
  <pre><code>namespace MyNamespace
  {
      public partial class Startup
      {
          public static OAuthAuthorizationServerOptions OAuthOptions { get; private set; }
          public static string PublicClientId { get; private set; }
          public void ConfigureAuth(IAppBuilder app)
          {
              app.UseCookieAuthentication(new CookieAuthenticationOptions());
              app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
  
              PublicClientId = "self";
              OAuthOptions = new OAuthAuthorizationServerOptions
              {
                  TokenEndpointPath = new PathString("/Token"),
                  Provider = new ApplicationOAuthProvider(PublicClientId),
                  AuthorizeEndpointPath = new PathString("/api/Account/ExternalLogin"),
                  AccessTokenExpireTimeSpan = TimeSpan.FromDays(14)
              };
  
              app.UseOAuthBearerTokens(OAuthOptions);
          }
      }
  }
  </code></pre>
  
  <p>Likewise I implement User functional(like UserStore, UserManager).</p>
  
  <p>I take "ExternalLogin" method from example and change. </p>
  
  <pre><code>    // GET api/Account/ExternalLogin
      [OverrideAuthentication]
      [HostAuthentication(DefaultAuthenticationTypes.ExternalCookie)]
      [AllowAnonymous]
      [Route("ExternalLogin", Name = "ExternalLogin")]
      public async Task&lt;IHttpActionResult&gt; GetExternalLogin(string provider, string error = null)
      {
          if (error != null)
          {
              return Redirect(Url.Content("~/") + "#error=" + Uri.EscapeDataString(error));
          }
  
          if (!User.Identity.IsAuthenticated)
          {
              return new ChallengeResult(provider, this);
          }
  
          ExternalLoginData externalLogin = ExternalLoginData.FromIdentity(User.Identity as ClaimsIdentity);
  
          if (externalLogin == null)
          {
              return InternalServerError();
          }
  
          if (externalLogin.LoginProvider != provider)
          {
              Authentication.SignOut(DefaultAuthenticationTypes.ExternalCookie);
              return new ChallengeResult(provider, this);
          }
  
          User user = await UserManager.FindAsync(new UserLoginInfo(externalLogin.LoginProvider,
              externalLogin.ProviderKey));
  
          bool hasRegistered = user != null;
  
          if (hasRegistered)
          {
              Authentication.SignOut(DefaultAuthenticationTypes.ExternalCookie);
  
  
  
              ClaimsIdentity oAuthIdentity = await UserManager.CreateIdentityAsync(user, 
                                  OAuthDefaults.AuthenticationType);
  
              ClaimsIdentity cookieIdentity = await UserManager.CreateIdentityAsync(user, 
                                  CookieAuthenticationDefaults.AuthenticationType);
  
              AuthenticationProperties properties = ApplicationOAuthProvider.CreateProperties(user.UserName);
              Authentication.SignIn(properties, oAuthIdentity, cookieIdentity);
          }
          else
          {
              IEnumerable&lt;Claim&gt; claims = externalLogin.GetClaims();
              ClaimsIdentity identity = new ClaimsIdentity(claims, OAuthDefaults.AuthenticationType);
              Authentication.SignIn(identity);
          }
  
          return Ok();
      }
  </code></pre>
  
  <p>After that I run my application and tried login to the app like this:</p>
  
  <pre><code> var loginData = {
              grant_type: 'password',
              username: "test",
              password: "test"
          }; 
  
   $.ajax({
           type: 'POST',
           url: '/Token',
           data: loginData
          }).done(function (data) {
              alert(data.username);
              sessionStorage.setItem(tokenKey, data.access_token);
          }).fail(function (data) {
              alert(data);
          });
  </code></pre>
  
  <p>I got the 404 error. I try sent custom request to /Token via fiddler and this take the same result. Then i check that my api/Account/ExternalLogin action is  available, this response 401 status code. I check references Owin, Microsoft.Owin all correct. What's the problem? Where I have problems?</p>
  
  <p>UPD: </p>
  
  <pre><code>public class ApplicationOAuthProvider : OAuthAuthorizationServerProvider
   {
      private readonly string _publicClientId;
  
      [Dependency]
      public ICustomUserManager UserManager
      {
          get;set;
      }
  
      public ApplicationOAuthProvider(string publicClientId)
      {
          if (publicClientId == null)
          {
              throw new ArgumentNullException("publicClientId");
          }
  
          _publicClientId = publicClientId;
      }
  
      public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
      {
          var userManager = context.OwinContext.GetUserManager&lt;ICustomUserManager&gt;();
  
          User user = await userManager.FindAsync(context.UserName, context.Password);
  
          if (user == null)
          {
              context.SetError("invalid_grant", "The user name or password is incorrect.");
              return;
          }
  
          ClaimsIdentity oAuthIdentity = await UserManager.CreateIdentityAsync(user, 
                                  OAuthDefaults.AuthenticationType);
  
          ClaimsIdentity cookieIdentity = await UserManager.CreateIdentityAsync(user, 
                                  CookieAuthenticationDefaults.AuthenticationType);
  
          AuthenticationProperties properties = CreateProperties(user.UserName);
          AuthenticationTicket ticket = new AuthenticationTicket(oAuthIdentity, properties);
  
          var val = context.Validated(ticket);
          context.Request.Context.Authentication.SignIn(cookieIdentity);
      }
  
      public override Task TokenEndpoint(OAuthTokenEndpointContext context)
      {
          foreach (KeyValuePair&lt;string, string&gt; property in context.Properties.Dictionary)
          {
              context.AdditionalResponseParameters.Add(property.Key, property.Value);
          }
  
          return Task.FromResult&lt;object&gt;(null);
      }
  
      public override Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
      {
          // Resource owner password credentials does not provide a client ID.
          if (context.ClientId == null)
          {
              context.Validated();
          }
  
          return Task.FromResult&lt;object&gt;(null);
      }
  
      public override Task ValidateClientRedirectUri(OAuthValidateClientRedirectUriContext context)
      {
          if (context.ClientId == _publicClientId)
          {
              Uri expectedRootUri = new Uri(context.Request.Uri, "/");
  
              if (expectedRootUri.AbsoluteUri == context.RedirectUri)
              {
                  context.Validated();
              }
          }
  
          return Task.FromResult&lt;object&gt;(null);
      }
  
      public static AuthenticationProperties CreateProperties(string userName)
      {
          IDictionary&lt;string, string&gt; data = new Dictionary&lt;string, string&gt;
          {
              { "userName", userName }
          };
          return new AuthenticationProperties(data);
      }
  }
  </code></pre>