public async Task ReceiveAsync(AuthenticationTokenReceiveContext context)
    {

      var allowedOrigin = context.OwinContext.Get<string>("as:clientAllowedOrigin");
      context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { allowedOrigin });

      string hashedTokenId = Helper.GetHash(context.Token);

      using (AuthRepository _repo = new AuthRepository())
      {
        var refreshToken = await _repo.FindRefreshToken(hashedTokenId);

        if (refreshToken != null)
        {
          //Get protectedTicket from refreshToken class
          context.DeserializeTicket(refreshToken.ProtectedTicket);
          var result = await _repo.RemoveRefreshToken(hashedTokenId);
        }
      }
    }
    public async Task CreateAsync(AuthenticationTokenCreateContext context)
    {
      var clientid = context.Ticket.Properties.Dictionary["as:client_id"];
      var email = context.Ticket.Properties.Dictionary["email"];

      if (string.IsNullOrEmpty(clientid))
      {
        return;
      }

      var refreshTokenId = Guid.NewGuid().ToString("n");

      using (AuthRepository _repo = new AuthRepository())
      {
        var refreshTokenLifeTime = context.OwinContext.Get<string>("as:clientRefreshTokenLifeTime");

        var token = new RefreshToken()
        {
          Id = Helper.GetHash(refreshTokenId),
          ClientId = clientid,
          Subject = email,
          IssuedUtc = DateTime.UtcNow,
          ExpiresUtc = DateTime.UtcNow.AddMinutes(Convert.ToDouble(refreshTokenLifeTime))
        };

        context.Ticket.Properties.IssuedUtc = token.IssuedUtc;
        context.Ticket.Properties.ExpiresUtc = token.ExpiresUtc;

        token.ProtectedTicket = context.SerializeTicket();

        var result = await _repo.AddRefreshToken(token);

        if (result)
        {
          context.SetToken(refreshTokenId);
        }

      }
    }
    public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
    {
      IdentityUser user;

      var data = await context.Request.ReadFormAsync();

      var allowedOrigin = context.OwinContext.Get<string>("as:clientAllowedOrigin");

      if (allowedOrigin == null) allowedOrigin = "*";

      context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { allowedOrigin });

      using (AuthRepository _repo = new AuthRepository())
      {
        user = await _repo.FindUser(data["email"], context.Password);

        if (user == null)
        {
          context.SetError("invalid_grant", "The user email or password is incorrect.");
          return;
        }
      }

      var identity = new ClaimsIdentity(context.Options.AuthenticationType);
      identity.AddClaim(new Claim(ClaimTypes.Email, data["email"]));
      identity.AddClaim(new Claim(ClaimTypes.Role, "user"));
      identity.AddClaim(new Claim("sub", context.UserName));

      var props = new AuthenticationProperties(new Dictionary<string, string>
      {
          { 
              "as:client_id", (context.ClientId == null) ? string.Empty : context.ClientId
          },
          { 
              "userName", user.UserName
          },
          {
            "email", user.Email
          },
          {
            "id", user.Id
          }
      });

      var ticket = new AuthenticationTicket(identity, props);
      context.Validated(ticket);
    }
    public override Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
    {

      string clientId;
      string clientSecret;
      Client client = null;

      if (!context.TryGetBasicCredentials(out clientId, out clientSecret))
      {
        context.TryGetFormCredentials(out clientId, out clientSecret);
      }

      if (context.ClientId == null)
      {
        //Remove the comments from the below line context.SetError, and invalidate context 
        //if you want to force sending clientId/secrects once obtain access tokens. 
        context.Validated();
        //context.SetError("invalid_clientId", "ClientId should be sent.");
        return Task.FromResult<object>(null);
      }

      using (AuthRepository _repo = new AuthRepository())
      {
        client = _repo.FindClient(context.ClientId);
      }

      if (client == null)
      {
        context.SetError("invalid_clientId", string.Format("Client '{0}' is not registered in the system.", context.ClientId));
        return Task.FromResult<object>(null);
      }

      if (client.ApplicationType == ApplicationTypes.NativeConfidential)
      {
        if (string.IsNullOrWhiteSpace(clientSecret))
        {
          context.SetError("invalid_clientId", "Client secret should be sent.");
          return Task.FromResult<object>(null);
        }
        else
        {
          if (client.Secret != Helper.GetHash(clientSecret))
          {
            context.SetError("invalid_clientId", "Client secret is invalid.");
            return Task.FromResult<object>(null);
          }
        }
      }

      if (!client.Active)
      {
        context.SetError("invalid_clientId", "Client is inactive.");
        return Task.FromResult<object>(null);
      }

      context.OwinContext.Set<string>("as:clientAllowedOrigin", client.AllowedOrigin);
      context.OwinContext.Set<string>("as:clientRefreshTokenLifeTime", client.RefreshTokenLifeTime.ToString());

      context.Validated();
      return Task.FromResult<object>(null);
    }
 public AccountController()
 {
   _repo = new AuthRepository();
 }