-
Notifications
You must be signed in to change notification settings - Fork 48
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Unauthorized status code on CloudRecordings.DownloadFileAsync invocation. #348
Comments
Are you able to capture the response from Zoom (using a tool such as Fiddler for example)? This would allow us to validate your theory rather than just guessing. |
I wrote a unit test to simulate the scenario in your theory and I am not able to reproduce the problem, the unit test completes successfully. This seems to indicate that the problem you are experiencing is not related to an expired token (or that my unit test does not reflect your scenario accurately). /// <summary>
/// This unit test simulates a scenario where we attempt to download a file but our oAuth token has expired.
/// In this situation, we expect the token to be refreshed and the download request to be reissued.
/// </summary>
/// <returns></returns>
[Fact]
public async Task DownloadFileAsync_with_expired_token()
{
// Arrange
var downloadUrl = "http://dummywebsite.com/dummyfile.txt";
var mockTokenHttp = new MockHttpMessageHandler();
mockTokenHttp // Issue a new token
.When(HttpMethod.Post, "https://api.zoom.us/oauth/token")
.Respond(HttpStatusCode.OK, "application/json", "{\"refresh_token\":\"new refresh token\",\"access_token\":\"new access token\"}");
var mockHttp = new MockHttpMessageHandler();
mockHttp // The first time the file is requested, we return "401 Unauthorized" to simulate an expired token.
.Expect(HttpMethod.Get, downloadUrl)
.Respond(HttpStatusCode.Unauthorized, new StringContent("{\"message\":\"access token is expired\"}"));
mockHttp // The second time the file is requested, we return "200 OK" with the file content.
.Expect(HttpMethod.Get, downloadUrl)
.Respond(HttpStatusCode.OK, new StringContent("This is the content of the file"));
var client = Utils.GetFluentClient(mockHttp, mockTokenHttp);
var recordings = new CloudRecordings(client);
// Act
var result = await recordings.DownloadFileAsync(downloadUrl, CancellationToken.None).ConfigureAwait(true);
// Assert
mockHttp.VerifyNoOutstandingExpectation();
mockHttp.VerifyNoOutstandingRequest();
result.ShouldNotBeNull();
} Is it possible that the
ZoomNet currently does not support this alternate token and always uses the token that was obtained when initiating your OAuth session. Maybe this is the scenario you are facing? Maybe your access token is not sufficient to download this file? I'm just speculating. |
@pvgritsenko-ansible are you still interested in researching this problem? In case I wasn't clear, let me reiterate that I was not able to reproduce and therefore I need more information from you to continue researching. Capturing the payload you receive from Zoom would be a great first step. Also, I shared with you some hypothesis. Do they make sense? Do you have any feedback? |
Hi, @Jericho yes, I still try to find the source of problem. Sorry to don't keep you up to date. It's hard to capture the Zoom response since the issue for some reasone does't reproduce on dev machines (only in PROD env where we can't setup any additional apps). But I'm going to test another way to simulate this problem. I'll write to you this week and report results. About your hypothesis. It is possible, but we've downloaded files before using a general access token. It is also strange that in this case the issue occurs only with some files, and not with all. |
Is this problem consistent with a given file? What I mean is: do you get this error consistently when you attempt to download a certain file or does this problem go away after a certain amount of time? If the problem goes away, maybe it gives credence to your original hypothesis this it's related to an expired token. However, if the problem is consistent, maybe it points to the fact that there's some additional security around this file and it prevents you from downloading it. And if this is the case, maybe we need to invest time and effort to support the |
We try do download some transcript file periodically. And usually we don't have such exception. But sometimes it occurs.
And sometimes at the step 4 we receive Unauthorized exception. |
There is an update. And unfortunately it looks like the source of issue on the Zoom side. |
The
And in a subsequent comment I said:
Let me know if your testing with this download_access_token is conclusive. If so, we can look into enhancing ZoomNet to support it. |
Yes, I've read your comments before. That's one of the reason why we'll try to use download_access_token. |
I've prepared a beta NuGet package for you with two improvements:
This package is called 'ZoomNet 0.80.0-download-access-0018' and it's available on my personal NuGet feed (instructions). Let me know if this helps. |
Thanks a lot! |
I have tested 'ZoomNet 0.80.0-download-access-0018'. But it seems that something is wrong with DownloadFileAsync. I created a ZoomClient with an expired token using the constructor. Then, using Postman, I got a valid access_token and passed it as an argument to the 'DownloadFileAsync' method. But the method returned me an 'Unauthorized' exception. Maybe I missed something? |
Can you please provide code snippet to help me reproduce |
I'm guessing you're using an expired token because you want to see if ZoomNet will refresh this expired token.
You have previously established that Zoom is rejecting your OAuth token when you attempt to download a file. If your OAuth token is not valid to download a file, I highly doubt that the tool you use to get a refreshed token will change anything. I don't think Zoom cares that use used Postman or any other tool to renew your token. You token is not valid, period. Therefore, I'm not surprised that Zoom is rejecting this OAuth token.
The improvement I made to your code should look something like this: // The Id of the meeting
var meetingId = 123;
// Use a ttl that seems reasonable to you. In this example, I'm using 5 minutes.
const int ttl = 60 * 5;
// Get recording information for the meeting. This includes the download_access_token
var recordingInfo = await client.CloudRecordings.GetRecordingInformationAsync(meetingId, ttl, cancellationToken).ConfigureAwait(false);
// This is the new property added in the beta NuGet package
var downloadToken = recordingInfo.DownloadAccessToken;
// Download all files for the meeting. Don't forget to specify the download token when invoking the DownloadFileAsync method
foreach (var recordingFile in recordingInfo.RecordingFiles)
{
var stream = await client.CloudRecordings.DownloadFileAsync(recordingFile.DownloadUrl, downloadToken, cancellationToken).ConfigureAwait(false);
} Having said that, if you are still getting the 'Unauthorized' exception, I think it demonstrate that the token is probably not the source of this problem. I think it's time for you to escalate this problem to Zoom support and get guidance from them. |
I just wanted to check that when I use the 'DownloadFileAsync' method with a download token, this token will be used even if the access token has expired. My workflow:
If I create new ZoomClient without token argument and call ZoomClient.CloudRecordings.DownloadFileAsync(download_url, download_token), it will work as expected and files will be downloaded. No metter how I retrieved download_url and download_token, by Postman or ZoomClient.CloudRecordings.GetRecordingInformationAsynce.
And actually we already on the way to start the Zoom support thread. |
I didn't think about the fact that the OAuth handler in our library (here) overrides the custom token. Let me fix that and I'll publish a new beta package.
Yes, it's always helpful. Thank you for providing this. |
Beta package |
Thanks, it works as expected. I will integrate this version of ZoomNet into my project and monitor for "unauthorized" exceptions. |
🎉 This issue has been resolved in version 0.80.0 🎉 The release is available on: Your GitReleaseManager bot 📦🚀 |
Sometimes when we try to download Zoom recording file we encounter following Pathoschild.Http.Client.ApiException with status code 'Unauthorized'. The only idea is access token expired and for some reasone it was not successfuly updated by OAuthTokenHandler.
And may it be possible that the source of issue is ZoomRetryCoordinator.ExecuteAsync method where we check the responseContent.message contains "access token is expired" string. I've simulated the exception and noted that actually message is empty. Can it be empty just because we cannot read stream content?
Full stack-trace:
The text was updated successfully, but these errors were encountered: