Merge pull request #3251 from stianst/master

KEYCLOAK-3586
This commit is contained in:
Stian Thorgersen 2016-09-21 10:55:46 +02:00 committed by GitHub
commit a9a759c4dc

View file

@ -155,7 +155,6 @@
} else if (initOptions) { } else if (initOptions) {
if (initOptions.token || initOptions.refreshToken) { if (initOptions.token || initOptions.refreshToken) {
setToken(initOptions.token, initOptions.refreshToken, initOptions.idToken); setToken(initOptions.token, initOptions.refreshToken, initOptions.idToken);
kc.timeSkew = initOptions.timeSkew || 0;
if (loginIframe.enable) { if (loginIframe.enable) {
setupCheckLoginIframe().success(function() { setupCheckLoginIframe().success(function() {
@ -363,11 +362,10 @@
throw 'Not authenticated'; throw 'Not authenticated';
} }
var expiresIn = kc.tokenParsed['exp'] - (new Date().getTime() / 1000) + kc.timeSkew; var expiresIn = kc.tokenParsed['exp'] - Math.ceil(new Date().getTime() / 1000) + kc.timeSkew;
if (minValidity) { if (minValidity) {
expiresIn -= minValidity; expiresIn -= minValidity;
} }
return expiresIn < 0; return expiresIn < 0;
} }
@ -382,7 +380,20 @@
minValidity = minValidity || 5; minValidity = minValidity || 5;
var exec = function() { var exec = function() {
if (minValidity >= 0 && !kc.isTokenExpired(minValidity)) { var refreshToken = false;
if (kc.timeSkew == -1) {
console.info('Skew ' + kc.timeSkew);
refreshToken = true;
console.info('[KEYCLOAK] Refreshing token: time skew not set');
} else if (minValidity == -1) {
refreshToken = true;
console.info('[KEYCLOAK] Refreshing token: forced refresh');
} else if (kc.isTokenExpired(minValidity)) {
refreshToken = true;
console.info('[KEYCLOAK] Refreshing token: token expired');
}
if (!refreshToken) {
promise.setSuccess(false); promise.setSuccess(false);
} else { } else {
var params = 'grant_type=refresh_token&' + 'refresh_token=' + kc.refreshToken; var params = 'grant_type=refresh_token&' + 'refresh_token=' + kc.refreshToken;
@ -407,18 +418,21 @@
req.onreadystatechange = function () { req.onreadystatechange = function () {
if (req.readyState == 4) { if (req.readyState == 4) {
if (req.status == 200) { if (req.status == 200) {
console.info('[KEYCLOAK] Token refreshed');
timeLocal = (timeLocal + new Date().getTime()) / 2; timeLocal = (timeLocal + new Date().getTime()) / 2;
var tokenResponse = JSON.parse(req.responseText); var tokenResponse = JSON.parse(req.responseText);
kc.timeSkew = Math.floor(timeLocal / 1000) - kc.tokenParsed.iat;
setToken(tokenResponse['access_token'], tokenResponse['refresh_token'], tokenResponse['id_token']); setToken(tokenResponse['access_token'], tokenResponse['refresh_token'], tokenResponse['id_token'], timeLocal);
kc.onAuthRefreshSuccess && kc.onAuthRefreshSuccess(); kc.onAuthRefreshSuccess && kc.onAuthRefreshSuccess();
for (var p = refreshQueue.pop(); p != null; p = refreshQueue.pop()) { for (var p = refreshQueue.pop(); p != null; p = refreshQueue.pop()) {
p.setSuccess(true); p.setSuccess(true);
} }
} else { } else {
console.warn('[KEYCLOAK] Failed to refresh token');
kc.onAuthRefreshError && kc.onAuthRefreshError(); kc.onAuthRefreshError && kc.onAuthRefreshError();
for (var p = refreshQueue.pop(); p != null; p = refreshQueue.pop()) { for (var p = refreshQueue.pop(); p != null; p = refreshQueue.pop()) {
p.setError(true); p.setError(true);
@ -529,18 +543,16 @@
function authSuccess(accessToken, refreshToken, idToken, fulfillPromise) { function authSuccess(accessToken, refreshToken, idToken, fulfillPromise) {
timeLocal = (timeLocal + new Date().getTime()) / 2; timeLocal = (timeLocal + new Date().getTime()) / 2;
setToken(accessToken, refreshToken, idToken); setToken(accessToken, refreshToken, idToken, timeLocal);
if ((kc.tokenParsed && kc.tokenParsed.nonce != oauth.storedNonce) || if ((kc.tokenParsed && kc.tokenParsed.nonce != oauth.storedNonce) ||
(kc.refreshTokenParsed && kc.refreshTokenParsed.nonce != oauth.storedNonce) || (kc.refreshTokenParsed && kc.refreshTokenParsed.nonce != oauth.storedNonce) ||
(kc.idTokenParsed && kc.idTokenParsed.nonce != oauth.storedNonce)) { (kc.idTokenParsed && kc.idTokenParsed.nonce != oauth.storedNonce)) {
console.log('invalid nonce!'); console.info('[KEYCLOAK] Invalid nonce, clearing token');
kc.clearToken(); kc.clearToken();
promise && promise.setError(); promise && promise.setError();
} else { } else {
kc.timeSkew = Math.floor(timeLocal / 1000) - kc.tokenParsed.iat;
if (fulfillPromise) { if (fulfillPromise) {
kc.onAuthSuccess && kc.onAuthSuccess(); kc.onAuthSuccess && kc.onAuthSuccess();
promise && promise.setSuccess(); promise && promise.setSuccess();
@ -613,7 +625,7 @@
return promise.promise; return promise.promise;
} }
function setToken(token, refreshToken, idToken) { function setToken(token, refreshToken, idToken, timeLocal) {
if (kc.tokenTimeoutHandle) { if (kc.tokenTimeoutHandle) {
clearTimeout(kc.tokenTimeoutHandle); clearTimeout(kc.tokenTimeoutHandle);
kc.tokenTimeoutHandle = null; kc.tokenTimeoutHandle = null;
@ -632,12 +644,23 @@
kc.realmAccess = kc.tokenParsed.realm_access; kc.realmAccess = kc.tokenParsed.realm_access;
kc.resourceAccess = kc.tokenParsed.resource_access; kc.resourceAccess = kc.tokenParsed.resource_access;
if (timeLocal) {
kc.timeSkew = Math.floor(timeLocal / 1000) - kc.tokenParsed.iat;
console.info('[KEYCLOAK] Estimated time difference between browser and server is ' + kc.timeSkew + ' seconds');
} else {
kc.timeSkew = -1;
}
if (kc.onTokenExpired) { if (kc.onTokenExpired) {
var expiresIn = (kc.tokenParsed['exp'] - (new Date().getTime() / 1000) + kc.timeSkew) * 1000; if (kc.timeSkew == -1) {
if (expiresIn <= 0) {
kc.onTokenExpired(); kc.onTokenExpired();
} else { } else {
kc.tokenTimeoutHandle = setTimeout(kc.onTokenExpired, expiresIn); var expiresIn = (kc.tokenParsed['exp'] - (new Date().getTime() / 1000) + kc.timeSkew) * 1000;
if (expiresIn <= 0) {
kc.onTokenExpired();
} else {
kc.tokenTimeoutHandle = setTimeout(kc.onTokenExpired, expiresIn);
}
} }
} }