0
votes

I´m following a tutorial about microservices. I got to the point of using bearer tokens for a basic authorization model. I create the token and set all the properties but when I try to use the token it gives me the error: Bearer error="invalid_token", error_description="The token expired at '04/03/2020 21:47:31'" even tho its currently 21:42 so its not actually expired.

Im just checking to this url: https://localhost:5001/api/Activities/GetActivity

Could it be a problem with postman, I already trying changing the issuer, adding more than 5 minutes, adding more headers to postman and no luck.

This is my function to create the token:

 public CustomJsonWebToken Create(Guid userId)
        {
            var nowUtc = DateTime.UtcNow;
            var expiration = nowUtc.AddMinutes(jwtOptions.ExpiryMinutes);
            var centuryBegin = new DateTime(1970, 1, 1).ToUniversalTime();
            var exp = (long)(new TimeSpan(expiration.Ticks - centuryBegin.Ticks).TotalSeconds);
            var now = (long)(new TimeSpan(nowUtc.Ticks - centuryBegin.Ticks).TotalSeconds);
            var payload = new JwtPayload
            {
                {"sub", userId},
                {"iss", jwtOptions.Issuer},
                {"iat", now},
                {"exp", exp},
                {"unique_name", userId}
            };
            var jwt = new JwtSecurityToken(jwtHeader, payload);
            var token = jwtSecurityTokenHandler.WriteToken(jwt);

            return new CustomJsonWebToken
            {
                Token = token,
                Expire = exp
            };
        }
1

1 Answers

1
votes

The likely problem is that the centuryBegin you used is not the UTC Epoch - the DateTime constructor by default assumes its Kind to be DateTimeKind.Unspecified, and calling ToUniversalTime() won't change that fact that .NET assumes it to represent the instance of time at 1 Jan 1970 in your local timezone.

So for it to represent the Epoch correctly you should probably use:

var centuryBegin = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);

Alternatively, you can use the DateTimeOffset class instead because it is more suited for representation of an absolute time, and it also has the convenient method DateTimeOffset.ToUnixTimeSeconds():

var nowUtc = DateTimeOffset.UtcNow;
var expiration = nowUtc.AddMinutes(jwtOptions.ExpiryMinutes);
var exp = expiration.ToUnixTimeSeconds();
var now = nowUtc.ToUnixTimeSeconds();