Skip to content
Permalink
Browse files

OAuth2: avoid constant token refreshing if the expiration delay is < …

…2 minutes

Currently we refresh the token 2 minutes befores its theoretical expiration.
But if using default Keycloack configuration, the refresh delay is 60 seconds.
Which means we refresh the token for every network request. So for such short
delays, only refresh when the remaining validity time is below 10% of the
initial expiration delay.
  • Loading branch information
rouault committed Nov 16, 2020
1 parent b86cc93 commit a8af06ff2024a253cf5c43b354f74e35662a1021
Showing with 27 additions and 1 deletion.
  1. +10 −1 src/auth/oauth2/qgsauthoauth2method.cpp
  2. +6 −0 src/auth/oauth2/qgso2.cpp
  3. +11 −0 src/auth/oauth2/qgso2.h
@@ -28,6 +28,8 @@
#include "qgsmessagelog.h"
#include "qgssettings.h"

#include <algorithm>

#include <QDateTime>
#include <QInputDialog>
#include <QDesktopServices>
@@ -139,7 +141,10 @@ bool QgsAuthOAuth2Method::updateNetworkRequest( QNetworkRequest &request, const
if ( o2->expires() > 0 ) // QStringLiteral("").toInt() result for tokens with no expiration
{
int cursecs = static_cast<int>( QDateTime::currentDateTime().toMSecsSinceEpoch() / 1000 );
expired = ( ( o2->expires() - cursecs ) < 120 ); // try refresh with expired or two minutes to go
const int lExpirationDelay = o2->expirationDelay();
// try refresh with expired or two minutes to go (or a fraction of the initial expiration delay if it is short)
const int refreshThreshold = lExpirationDelay > 0 ? std::min( 120, std::max( 2, lExpirationDelay / 10 ) ) : 120;
expired = ( ( o2->expires() - cursecs ) < refreshThreshold );
}

if ( expired )
@@ -160,6 +165,8 @@ bool QgsAuthOAuth2Method::updateNetworkRequest( QNetworkRequest &request, const
o2->refreshSynchronous();

// refresh result should set o2 to (un)linked
if ( o2->linked() )
o2->computeExpirationDelay();
}
}
}
@@ -226,6 +233,8 @@ bool QgsAuthOAuth2Method::updateNetworkRequest( QNetworkRequest &request, const
QgsMessageLog::logMessage( msg, AUTH_METHOD_KEY, Qgis::MessageLevel::Warning );
return false;
}

o2->computeExpirationDelay();
}

if ( o2->token().isEmpty() )
@@ -431,3 +431,9 @@ void QgsO2::refreshSynchronous()
emit refreshFinished( blockingRequest.reply().error() );
}
}

void QgsO2::computeExpirationDelay()
{
const int lExpires = expires();
mExpirationDelay = lExpires > 0 ? lExpires - static_cast<int>( QDateTime::currentMSecsSinceEpoch() / 1000 ) : 0;
}
@@ -61,6 +61,16 @@ class QgsO2: public O2
//! Refresh token in a synchronous way
void refreshSynchronous();

/**
* Compute expiration delay from current timestamp and expires()
* Should only be called just after a refresh / link event. */
void computeExpirationDelay();

/** Returns expiration delay.
* May be 0 if it is unknown
*/
int expirationDelay() const { return mExpirationDelay; }

public slots:

//! Clear all properties
@@ -104,6 +114,7 @@ class QgsO2: public O2
QString state_;
QgsAuthOAuth2Config *mOAuth2Config;
bool mIsLocalHost = false;
int mExpirationDelay = 0;

static QString O2_OAUTH2_STATE;
};

0 comments on commit a8af06f

Please sign in to comment.
You can’t perform that action at this time.