JWT::ExpiredSignature raised when validating token from getUserIdentityTokenAsync - outlook

Our system is authenticating users by following these validation steps on a token generated by the getUserIdentityTokenAsync() method.
These tokens are failing the following check
Current time is between the times specified in the nbf and exp claims. The nbf claim specifies the earliest time that the token is considered valid, and the exp claim specifies the expiration time for the token. It is recommended to allow for some variation in clock settings between servers.
Our logs show these tokens being invalid by several hours
Current Time: 2020-04-10 17:02:11 +0000,
Valid Start: 2020-04-09 14:46:31 +0000,
Valid End: 2020-04-09 23:16:31 +0000,
We are validating these times as such:
def timeframe_valid?
PAYLOAD_WIGGLE_TIME = 900
if #payload.present?
now = Time.now.to_i
payload_valid_start = #payload[:nbf] - PAYLOAD_VALID_WIGGLE_TIME
payload_valid_expire = #payload[:exp] + PAYLOAD_VALID_WIGGLE_TIME
if now < payload_valid_start || now > payload_valid_expire
# handle invalid token...
end
end
end
We are making a unique call to getUserIdentityTokenAsync before each api request. Since we are seeing such a large difference in the time window for a valid token and the time it is validated, my best guess is that users are leaving the add-in open for long periods of time without refreshing. For some reason, when they return, getUserIdentityTokenAsync is not returning a new token, but rather the old one that is already expired.
Is there any way to force getUserIdentityToken to issue a new token after one has long since expired without a hard refresh of the add-in?

Related

Rerun getToken(authorization) requests only on expiry - Jmeter

My testplan is as follows:
get token: requests to get access token
Setting a user defined variable to get the tokenGeneratedTime, let's say tokenGeneratedTime to ${__time(,)}
Check if token is expired(if controller) - {__jexl3((${__time(,)} - ${tokenGenerationTime}) > 3599000)}
if true, goes to get token sampler
if false, goes to subsequent requests
Some https requests
So if I run this test plan for the first time(only 1 iteration), request to get token is fired, the condition would be evaluated as false and the subsequent requests are fired. All is well and good. But as you can see, if I run the test plan again immediately(not iterating) for the second time, the get token(authorization) requests are fired again, which is not needed. I need to call the get token requests, only on expiry.
I'm thinking of setting a variable to false, if the token is not expired and putting the get token requests under an if controller. But how do I set a variable in if controller?
If you have any other ways of achieving this, please do suggest.
TIA
Use a flag to check the token expiry. e.g. isTokenExpired
Define the variable in the User Defiled Variables section and set the value to true. This will ensure token request is fired for the first time.
Add an IF Controller to the token request and check the condition ${tokenExpired}. Set the flag to false when a token is created successfully. vars.put("tokenExpired","false")
Add a JSR223 Postprocessor to the top level and check the response code 401 for the token expiry response. If the token is expired, set the flag isTokenExpired to true and redirect the thread to the next iteration immediately ctx.setTestLogicalAction(org.apache.jmeter.threads.JMeterContext.TestLogicalAction.START_NEXT_ITERATION_OF_THREAD .
String responseCode=prev.getResponseCode()
if (responseCode.equals("401")) {
log.info("Token is expired ")
vars.put("tokenExpired","true")
ctx.setTestLogicalAction(org.apache.jmeter.threads.JMeterContext.TestLogicalAction.START_NEXT_ITERATION_OF_THREAD )
}
if I run the test plan again immediately(not iterating)
If you run the test plan 2nd time it means that your tokenGenerationTime variable gets a new value of the current timestamp equal to the start time of 2nd execution.
If you want to be able to run your test plan 2nd time within 1 hour without firing the token generation request you can consider writing the tokenGenerationTime into a file using i.e. __StringToFile() function and read it from the file on 2nd and other test executions using __FileToString() function or if your logic is more complex you can go for __groovy() function and implement whatever you want there
More information on JMeter Functions concept: Apache JMeter Functions - An Introduction

Outlook REST API 410 Error: SyncStateNotFound

I get a 410 when syncing messages:
{\"code\":\"SyncStateNotFound\",\"message\":\"The sync state
generation is not found; generation=1;[highest=4][4][2][3].\"}
This only occurs when syncing messages for select mailfolders on select accounts. It occurs when making a post-initial sync using the relevant delta token. I can recreate this via making
GET https://outlook.office365.com/api/v2.0/me/MailFolders('{folder_id}')/messages/?$deltaToken={delta_token}
In Microsoft's Outlook Sandbox.
Here are the literal steps it takes to reproduce deterministically:
1) Initial Message Sync:
GET https://outlook.office365.com/api/v2.0/me/MailFolders('{folder_id}')/messages
2) Sync with initial delta token:
GET https://outlook.office365.com/api/v2.0/me/MailFolders('{folder_id}')/messages/?$deltaToken={delta_token}
3) Sync with skip token until delta token:
GET https://outlook.office365.com/api/v2.0/me/MailFolders('{folder_id}')/messages/?$skipToken={skip_token}
4) ERROR OCCURS HERE: Mailfolder receives update, so I re-sync messages with delta token from (3). The call below throws a 410 and I can't sync messages.
GET https://outlook.office365.com/api/v2.0/me/MailFolders('{folder_id}')/messages/?$deltaToken={delta_token}
To reiterate: I've isolated this to just testing in the Outlook sandbox, and it still occurs. Testing as in making the GET call to sync (i.e., make perform (2)) using the deltaToken from (3) and its corresponding folderId as query parameters.
Dumb Mistake: Passed in initial delta token as opposed to current.

JWT/Laravel Extend token expiration lifetime

I am usig JWT to manage the user access to our API system. The problem I am facing is that the token is expiring after some few minutes. How can I make the JWT token expires in such a way that it only expires when user manually logs out.
Thanks.
Add 'exp' in an array as a second parameter for the 'attempt' method. This 'exp' is timestamp.
For example:
$token=JWTAuth::attempt(
['email'=>$email,'password'=>$password],
['exp' => Carbon::now()->addweek()->timestamp]
);
In laravel 5.3, i simply comment the line in config/jwt.php ie..,
// ttl => 60
and now the time-to-live not exist and token expiration is lifetime.
and for invalidate the token use this below code in logout() i.e, JWTAuth::invalidate(JWTAuth::getToken());
You need to store the expiration time for a token server side instead of inside the token. This means that you don't set the exp key in the token. You can for example store the jti with an expiration time in the database. When the token is then received for authentication you can validate the token and then check the last seen date of the token based on the jti stored in the database with the expected lifetime and current time. If the token is still valid you reset the last seen date of the jti to the current time.

How to get all message history from Hipchat for a room via the API?

I was using the Hipchat API (v2) a bit today and ran into an odd issue where I was not able to really pull up all of the history for a room. It seemed as though when I queried a specific date, for example, it would only retrieve a fraction of the history for that date given. I had had plans to simply iterate across all of the dates for a Room to extract the history in a format that I could use, but ended up hitting this and am now unsure if it is really possible to pull out the history fully.
I realize that this is a bit clunky. It is pulling the JSON as a string and then I have to form it into a hash so I know I'm not doing this as good as it could be done, but here is roughly what I quickly did just to test out the history method for the API:
api_token = "MY_TOKEN"
client = HipChat::Client.new(api_token, :api_version => 'v2')
history = client['ROOM_NAME'].history
history = JSON.parse(history)
history.each do |key, history|
if history.is_a? Array
history.each do |message|
if message.is_a? Hash
puts "#{message['from']['name']}: #{message['message']}"
end
end
end
end
Obviously then the extension to that was to just curse through the dates in the desired range (using: client['ROOM_NAME'].history(:date => '2010-11-19', :timezone => 'PST')), but again, I was only getting a fraction of the history for the room. Are there some additional parameters that I'm missing for this to make it work as expected?
I got this working but it was a big pain.
Start by sending a query with the current time, in UTC, but without including the time zone, as the start date:
https://internal-hipchat-server/v2/room/2/history?reverse=false&date=2015-06-25T20:42:18.658439&max-results=1000&auth_token=XXX
This is very fiddly:
If you specify just the current date, without a timezone, as documented in the API, it is interpreted as midnight last night and you only get messages from yesterday or older.
If you try specifying tomorrow’s date instead, the response is 400 Bad Request This day has not yet come to pass.
If you specify the time as 2015-06-25T20:42:18.658439+00:00, which is the format that times come in HipChat API responses, HipChat’s parser seems to fail and interpret it as midnight last night.
When you get the response back, take the oldest items.date property, strip the timezone, and resubmit the above URL with an updated date parameter:
https://internal-hipchat-server/v2/room/2/history?reverse=false&date=2015-06-17T19:56:34.533182&max-results=1000&auth_token=XXX
Be sure to include the microseconds, in case a notification posted multiple messages to the same room in the same second.
This will get you the next page of messages. Keep doing this until you get fewer than max-results messages back.
There is a start-index parameter I tried passing before I got the above working, and it will give you a few pages of results, with responses lacking a links.next property, but it won’t give you the full history. On a chatroom with 9166 messages in the history according to statistics.messages_sent, it only returned 3217 messages. So don’t use it. You can use statistics.messages_sent as a sanity check for whether you get all messages.
Oh yeah, and the last_active property in the /v2/room call cannot be trusted because it doesn’t update when notification messages are posted to the room.

Is there a way to view the HttpRuntime.Cache?

I have a webservice that stores an authenticated users token in the HttpRuntime.Cache to be used on all subsequent requests. The cached item has a sliding expiration on it of 24 hours.
Secondly I have a vb.net app that is pinging this webservice every 15 seconds. It gets authenticated once, then uses the cached token for all subsequent requests. My problem is that the application appears to lose authentication at random intervals of time less than the 24 hr sliding expiration. However with it getting pinged every 15 sec the authentication should never expire.
I am looking for a way to view the HttpRuntime.cache to try and determine if the problem is in the webservice security methods or within the vb.net app. Can I view the HttpRuntime.cache somehow?
The webservice is part of a web forms site that was built with asp.net 2.0 on a Windows Server 2008.
The name of my key's were unknown as they were system generated guid values with a username as the value. So in order to view a cache collection that was unknown I used a simple loop as follows.
Dim CacheEnum As IDictionaryEnumerator = Cache.GetEnumerator()
While CacheEnum.MoveNext()
Dim cacheItem As String = Server.HtmlEncode(CacheEnum.Entry.Key.ToString())
Dim cacheItem2 As String = Server.HtmlEncode(CacheEnum.Entry.Value.ToString())
Response.Write(cacheItem & ":" & cacheItem2 & "<br />")
End While
Hope this helps others.
First off, HttpRuntime.Cache would not be the best place to store user authentication information. You should instead use HttpContext.Current.Session to store such data. Technically the cache is allowed to "pop" things in it at its own will (whenever it decides to).
If you actually need to use the cache, you can check if your item is in the cache by simply doing:
HttpRuntime.Cache["Key"] == null

Resources