protected HttpAction redirectToOriginallyRequestedUrl(final C context, final String defaultUrl) {
   final String requestedUrl = (String) context.getSessionAttribute(Pac4jConstants.REQUESTED_URL);
   String redirectUrl = defaultUrl;
   if (isNotBlank(requestedUrl)) {
     context.setSessionAttribute(Pac4jConstants.REQUESTED_URL, null);
     redirectUrl = requestedUrl;
   }
   logger.debug("redirectUrl: {}", redirectUrl);
   return HttpAction.redirect("redirect", context, redirectUrl);
 }
  @Override
  public R perform(
      final C context,
      final Config config,
      final HttpActionAdapter<R, C> httpActionAdapter,
      final String inputDefaultUrl,
      final Boolean inputMultiProfile,
      final Boolean inputRenewSession) {

    logger.debug("=== CALLBACK ===");

    // default values
    final String defaultUrl;
    if (inputDefaultUrl == null) {
      defaultUrl = Pac4jConstants.DEFAULT_URL_VALUE;
    } else {
      defaultUrl = inputDefaultUrl;
    }
    final boolean multiProfile;
    if (inputMultiProfile == null) {
      multiProfile = false;
    } else {
      multiProfile = inputMultiProfile;
    }
    final boolean renewSession;
    if (inputRenewSession == null) {
      renewSession = true;
    } else {
      renewSession = inputRenewSession;
    }

    // checks
    assertNotNull("context", context);
    assertNotNull("config", config);
    assertNotNull("httpActionAdapter", httpActionAdapter);
    assertNotBlank(Pac4jConstants.DEFAULT_URL, defaultUrl);
    final Clients clients = config.getClients();
    assertNotNull("clients", clients);

    // logic
    final Client client = clients.findClient(context);
    logger.debug("client: {}", client);
    assertNotNull("client", client);
    assertTrue(
        client instanceof IndirectClient, "only indirect clients are allowed on the callback url");

    HttpAction action;
    try {
      final Credentials credentials = client.getCredentials(context);
      logger.debug("credentials: {}", credentials);

      final CommonProfile profile = client.getUserProfile(credentials, context);
      logger.debug("profile: {}", profile);
      saveUserProfile(context, profile, multiProfile, renewSession);
      action = redirectToOriginallyRequestedUrl(context, defaultUrl);

    } catch (final HttpAction e) {
      logger.debug("extra HTTP action required in callback: {}", e.getCode());
      action = e;
    }

    return httpActionAdapter.adapt(action.getCode(), context);
  }