zWeRz
zWeRz

Reputation: 81

Handle challenge function not called when logging in after logout

I have created angular service, where I'm registering challengeHandler this way:

azureChallengeHandler = WL.Client.createChallengeHandler(realm);

azureChallengeHandler.isCustomResponse = function (response) {
  ...
};

azureChallengeHandler.handleChallenge = function (response) {
  ...
};

So i'm logging in with this function:

WL.Client.login(realm, options)

And the first time it works ok, isCustomResponse gets called, returns "true", then handleChallenge gets called. But after logging out with this function:

WL.Client.logout(realm, options)

When I try to login again, isCustomResponse gets called and still returns "true", but handleChallenge is not firing.

How can I fix that?

After calling WL.Client.reloadApp() or reloading app itself I can login again, but it's not a suitable solution.

UPDATE:

Here is adapter code:

function onAuthRequired(headers) {
  return customLoginResponse(true, false, false);
}

function customLoginResponse(authRequired, azureTokenRequired, wrongTenant) {
  return {
    authRequired: authRequired,
    azureTokenRequired: azureTokenRequired,
    realm: 'AzureAuth',
    wrongTenant: wrongTenant
  };
}

function onLogout(){
  WL.Server.setActiveUser("AzureAuth", null);
  WL.Logger.debug("Logged out");
}

function submitLogout(uuid, orgId, ssogroup){
  WL.Server.invokeProcedure({
    adapter: "AzureTokenSqlAdapter",
    procedure: "removeRefreshToken",
    parameters: [uuid, orgId, ssogroup]
  });
  onLogout();
}

function submitLogin(uuid, orgId, ssogroup, code) {
  var tokenObject = getTokens(code);
  if (tokenObject.id_token) {
    var jwtParsed = parseJWT(tokenObject.id_token);
    var tenantId = jwtParsed.tid;
    var invocationResult = WL.Server.invokeProcedure({
      adapter: "AzureTokenSqlAdapter",
      procedure: "checkTenant",
      parameters: [orgId, tenantId]
    });
    if (!invocationResult.tenantRegistered) {
      return customLoginResponse(true, true, true);
    }
  }
  return authUser(tokenObject, uuid, orgId, ssogroup);
}

And here is the client code:

    function azureAuthService($q, _, $state) {
        var loginPromise;

        azureChallengeHandler = WL.Client.createChallengeHandler(realm);

        //first response after protected call
        azureChallengeHandler.isCustomResponse = function (response) {
          if (!response || !response.responseJSON || response.responseText === null) {
            return false;
          }
          return response.responseJSON.realm == realm;
        };

        //when isCustomResponse returns true
        azureChallengeHandler.handleChallenge = function (response) {
          WL.Logger.debug("challenge handler -- handleChallenge");
          var authRequired = response.responseJSON.authRequired;
          var azureTokenRequired = response.responseJSON.azureTokenRequired;
          var wrongTenant = response.responseJSON.wrongTenant;
          if (wrongTenant) {
            loginPromise.reject('wrong tenant');
          } else if (authRequired && azureTokenRequired) {
            fullLogin();
          } else if (authRequired) {
            fastLogin();
          } else {
            loginPromise.resolve();
          }
        };

        azureChallengeHandler.handleFailure = function (error) {
          console.log('failure');
          console.log(error);
        };

        return {
          init: init,
          login: login,
          logout: logout
        };

        function init(config) {
          ssogroup = config.ssogroup;
          orgId = config.orgId;
        }

        function login() {
          loginPromise = $q.defer();
          WL.Client.login(realm, {
            onSuccess: function(info) {
              loginPromise.resolve();
            },
            onFailure: function(error) {
              loginPromise.reject();
            }
          });
          return loginPromise.promise;
        }

        function logout() {
          var logoutPromise = $q.defer();
          var invocationData = {
            adapter : 'AzureAuth',
            procedure : 'submitLogout',
            parameters : [device.uuid, orgId, ssogroup]
          };
          WL.Client.invokeProcedure(invocationData).then(function () {
            WL.Client.logout(realm, {
              onSuccess: function () {
                logoutPromise.resolve();
              },
              onFailure: function () {
                logoutPromise.reject();
              }
            });
          }, function () {
            logoutPromise.reject();
          });
          return logoutPromise.promise;
        }
   }

fastLogin and fullLogin is functions that perform some work and finally call

var options = {
      parameters: [device.uuid, orgId, ssogroup, transitionAuthObject.requestToken],
      adapter: "AzureAuth",
      procedure: "submitLogin"
    };
    azureChallengeHandler.submitAdapterAuthentication(options);

Upvotes: 0

Views: 354

Answers (1)

Anton
Anton

Reputation: 3166

Can't see your fullLogin() and fastLogin() methods so it's hard to say for sure. Make sure that you're calling challengeHandler's submitSuccess() or submitFailure() methods after successful/failed authentication. The authentication framework keeps a queue of requests/responses that require authentication. After successful/failed authentication you need to invoke submitSuccess/submitFailure on challenge handler in order for authentication framework to remove your requests from queue and process it. In case you're not doing so the request remains in the queue and once you're sending a new request that triggers authentication it is put into queue but not handled since there's another request already waiting for authentication.

Upvotes: 2

Related Questions