public OAuthJSONAccessTokenResponse getAccessToken(HttpServletRequest request)
      throws FcConnectException {

    try {
      OAuthAuthzResponse oar = OAuthAuthzResponse.oauthCodeAuthzResponse(request);

      log.debug("autorization code" + oar.getCode());

      // vérification a rajouter par rapport au state pour éviter le man in the middle
      //			if (StringUtils.isBlank(stateResponse) ||
      //					!stateResponse.equals(stateFromSession)) {
      //
      //				res = Response.ok("<p>Erreur de verif state response !!</p>",TEXT_HTML);
      //				addCORSOrigin(servletContext,res, headers);
      //		    	return res.build();
      ////				return new RedirectView("/login");
      //			}

      // récupération de l'access token
      OAuthClientRequest authClientRequest =
          OAuthClientRequest.tokenLocation(configuration.getTokenUri())
              .setGrantType(GrantType.AUTHORIZATION_CODE)
              .setClientId(configuration.getClientId())
              .setClientSecret(configuration.getClientSecret())
              .setRedirectURI(configuration.getRedirectUri())
              .setCode(oar.getCode())
              .buildBodyMessage();

      OAuthClient oAuthClient = new OAuthClient(new URLConnectionClient());

      return oAuthClient.accessToken(authClientRequest);

    } catch (OAuthSystemException e) {
      throw new FcConnectException("Error during request for accessToken : ", e);
    } catch (OAuthProblemException e) {
      throw new FcConnectException("Error during accessToken retrieving : ", e);
    }
  }
  @Override
  protected void processAuthenticationResponse(
      HttpServletRequest request, HttpServletResponse response, AuthenticationContext context)
      throws AuthenticationFailedException {

    try {

      Map<String, String> authenticatorProperties = context.getAuthenticatorProperties();

      String clientId = authenticatorProperties.get(OIDCAuthenticatorConstants.CLIENT_ID);
      String clientSecret = authenticatorProperties.get(OIDCAuthenticatorConstants.CLIENT_SECRET);
      String tokenEndPoint = getTokenEndpoint(authenticatorProperties);

      if (tokenEndPoint == null) {
        tokenEndPoint = authenticatorProperties.get(OIDCAuthenticatorConstants.OAUTH2_TOKEN_URL);
      }

      String callbackUrl = getCallbackUrl(authenticatorProperties);

      if (StringUtils.isBlank(callbackUrl)) {
        callbackUrl = IdentityUtil.getServerURL(FrameworkConstants.COMMONAUTH, true, true);
      }

      @SuppressWarnings({"unchecked"})
      Map<String, String> paramValueMap =
          (Map<String, String>) context.getProperty("oidc:param.map");

      if (paramValueMap != null && paramValueMap.containsKey("redirect_uri")) {
        callbackUrl = paramValueMap.get("redirect_uri");
      }

      OAuthAuthzResponse authzResponse = OAuthAuthzResponse.oauthCodeAuthzResponse(request);
      String code = authzResponse.getCode();

      OAuthClientRequest accessRequest =
          getaccessRequest(tokenEndPoint, clientId, code, clientSecret, callbackUrl);

      // Create OAuth client that uses custom http client under the hood
      OAuthClient oAuthClient = new OAuthClient(new URLConnectionClient());
      OAuthClientResponse oAuthResponse = getOauthResponse(oAuthClient, accessRequest);

      // TODO : return access token and id token to framework
      String accessToken = oAuthResponse.getParam(OIDCAuthenticatorConstants.ACCESS_TOKEN);

      if (StringUtils.isBlank(accessToken)) {
        throw new AuthenticationFailedException("Access token is empty or null");
      }

      String idToken = oAuthResponse.getParam(OIDCAuthenticatorConstants.ID_TOKEN);

      if (StringUtils.isBlank(idToken) && requiredIDToken(authenticatorProperties)) {
        throw new AuthenticationFailedException("Id token is required and is missing");
      }

      context.setProperty(OIDCAuthenticatorConstants.ACCESS_TOKEN, accessToken);

      AuthenticatedUser authenticatedUserObj;
      Map<ClaimMapping, String> claims = new HashMap<>();
      Map<String, Object> jsonObject = new HashMap<>();

      if (StringUtils.isNotBlank(idToken)) {

        context.setProperty(OIDCAuthenticatorConstants.ID_TOKEN, idToken);

        String base64Body = idToken.split("\\.")[1];
        byte[] decoded = Base64.decodeBase64(base64Body.getBytes());
        String json = new String(decoded);

        jsonObject = JSONUtils.parseJSON(json);

        if (jsonObject == null) {

          if (log.isDebugEnabled()) {
            log.debug("Decoded json object is null");
          }

          throw new AuthenticationFailedException("Decoded json object is null");
        }

        if (log.isDebugEnabled()
            && IdentityUtil.isTokenLoggable(IdentityConstants.IdentityTokens.USER_ID_TOKEN)) {
          log.debug("Retrieved the User Information:" + jsonObject);
        }

        String authenticatedUser = null;
        String isSubjectInClaimsProp =
            context
                .getAuthenticatorProperties()
                .get(IdentityApplicationConstants.Authenticator.SAML2SSO.IS_USER_ID_IN_CLAIMS);

        if (StringUtils.equalsIgnoreCase("true", isSubjectInClaimsProp)) {

          authenticatedUser = getSubjectFromUserIDClaimURI(context);

          if (authenticatedUser == null && log.isDebugEnabled()) {
            log.debug(
                "Subject claim could not be found amongst subject attributes. "
                    + "Defaulting to the sub attribute in IDToken.");
          }
        }

        if (authenticatedUser == null) {

          authenticatedUser = getAuthenticateUser(context, jsonObject, oAuthResponse);

          if (authenticatedUser == null) {
            throw new AuthenticationFailedException("Cannot find federated User Identifier");
          }
        }

        String attributeSeparator = null;

        try {

          String tenantDomain = context.getTenantDomain();

          if (StringUtils.isBlank(tenantDomain)) {
            tenantDomain = MultitenantConstants.SUPER_TENANT_DOMAIN_NAME;
          }

          int tenantId =
              OpenIDConnectAuthenticatorServiceComponent.getRealmService()
                  .getTenantManager()
                  .getTenantId(tenantDomain);
          UserRealm userRealm =
              OpenIDConnectAuthenticatorServiceComponent.getRealmService()
                  .getTenantUserRealm(tenantId);

          if (userRealm != null) {
            UserStoreManager userStore = (UserStoreManager) userRealm.getUserStoreManager();
            attributeSeparator =
                userStore
                    .getRealmConfiguration()
                    .getUserStoreProperty(IdentityCoreConstants.MULTI_ATTRIBUTE_SEPARATOR);
            if (log.isDebugEnabled()) {
              log.debug(
                  "For the claim mapping: "
                      + attributeSeparator
                      + " is used as the attributeSeparator in tenant: "
                      + tenantDomain);
            }
          }

        } catch (UserStoreException e) {
          throw new AuthenticationFailedException(
              "Error while retrieving multi attribute " + "separator", e);
        }

        for (Map.Entry<String, Object> entry : jsonObject.entrySet()) {
          buildClaimMappings(claims, entry, attributeSeparator);
        }

        authenticatedUserObj =
            AuthenticatedUser.createFederateAuthenticatedUserFromSubjectIdentifier(
                authenticatedUser);
      } else {

        if (log.isDebugEnabled()) {
          log.debug("The IdToken is null");
        }

        authenticatedUserObj =
            AuthenticatedUser.createFederateAuthenticatedUserFromSubjectIdentifier(
                getAuthenticateUser(context, jsonObject, oAuthResponse));
      }

      claims.putAll(getSubjectAttributes(oAuthResponse, authenticatorProperties));
      authenticatedUserObj.setUserAttributes(claims);

      context.setSubject(authenticatedUserObj);

    } catch (OAuthProblemException e) {
      throw new AuthenticationFailedException("Authentication process failed", e);
    }
  }