0

I am trying to develop an authentication that can sync up two github repos using a GitHub App Authentication. I am using this documentation as reference. Below is the code that I have:

String PEMString = "xxxxx";
JsonWebTokenHandler JWTHandler = new JsonWebTokenHandler();
DateTime Now = DateTime.UtcNow;
PemReader Reader = new PemReader(new MemoryStream(Encoding.UTF8.GetBytes(PEMString)));
RsaSecurityKey RSAKey = new RsaSecurityKey(Reader.ReadRsaKey());
SigningCredentials Credentials = new SigningCredentials(RSAKey, SecurityAlgorithms.RsaSsaPssSha256);
JObject Payload = new JObject();
Payload.Add("iat", Now.TimeOfDay.Ticks);
Payload.Add("exp", Now.AddHours(1).TimeOfDay.Ticks);
Payload.Add("iss", <my app id>);
String JWTToken = JWTHandler.CreateToken(Payload.ToString(), Credentials);
HttpClient Client = new HttpClient();
Client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", JWTToken);
Client.DefaultRequestHeaders.Add("Accept", "application/vnd.github+json");
Client.GetAsync(new Uri("https://api.github.com/app/installations"));

When I execute it I got a 403 (Forbidden) error.
If I try to make a REST API call with Postman using the same JWTToken generated by the code, I got the following message:

{
    "message": "'Issued at' claim ('iat') must be an Integer representing the time that the assertion was issued",
    "documentation_url": "https://docs.github.com/rest"
}

The payload

enter image description here

As you can see both iat and exp are long, not int. How should I make the conversion to make it fit with an int?

Even when I am using "https://api.github.com/app/installations" as the url, this is just for making my code work with the documentation example, my final goal is to can use all the urls such as: https://api.github.com/repos/OWNER/REPO/contents/PATH

James Z
  • 12,209
  • 10
  • 24
  • 44
delucaezequiel
  • 483
  • 2
  • 9
  • 26
  • 1
    As a side-note, I'd strongly encourage you to start following normal naming conventions in C#, where local variables start with lower-case letters. Even if you want to use other conventions in your private code, when you're sharing code in public, it's better to follow the conventions to make it easier for others to follow that code. – Jon Skeet Feb 24 '23 at 18:18
  • Does this answer your question? [JWT Validation fails](https://stackoverflow.com/questions/43593074/jwt-validation-fails) – jps Feb 24 '23 at 18:23

1 Answers1

0

Using this code to calculate the iat and exp is wrong.

Payload.Add("iat", Now.TimeOfDay.Ticks);
Payload.Add("exp", Now.AddHours(1).TimeOfDay.Ticks);

Ticks does not represent the UINX time, instead ticks are as defined here:

The value of this property represents the number of 100-nanosecond intervals that have elapsed since 12:00:00 midnight, January 1, 0001 in the Gregorian calendar

You need to use something like:

long seconds = (long)DateTime.UtcNow.Subtract(DateTime.UnixEpoch).TotalSeconds;

See How to get the unix timestamp in C#

Tore Nestenius
  • 16,431
  • 5
  • 30
  • 40