Exemple #1
0
  /**
   * Get offline sessions for client
   *
   * <p>Returns a list of offline user sessions associated with this client
   *
   * @param firstResult Paging offset
   * @param maxResults Maximum results size (defaults to 100)
   * @return
   */
  @Path("offline-sessions")
  @GET
  @NoCache
  @Produces(MediaType.APPLICATION_JSON)
  public List<UserSessionRepresentation> getOfflineUserSessions(
      @QueryParam("first") Integer firstResult, @QueryParam("max") Integer maxResults) {
    auth.requireView();

    if (client == null) {
      throw new NotFoundException("Could not find client");
    }

    firstResult = firstResult != null ? firstResult : -1;
    maxResults = maxResults != null ? maxResults : Constants.DEFAULT_MAX_RESULTS;
    List<UserSessionRepresentation> sessions = new ArrayList<UserSessionRepresentation>();
    List<UserSessionModel> userSessions =
        session
            .sessions()
            .getOfflineUserSessions(client.getRealm(), client, firstResult, maxResults);
    for (UserSessionModel userSession : userSessions) {
      UserSessionRepresentation rep = ModelToRepresentation.toRepresentation(userSession);

      // Update lastSessionRefresh with the timestamp from clientSession
      for (ClientSessionModel clientSession : userSession.getClientSessions()) {
        if (client.getId().equals(clientSession.getClient().getId())) {
          rep.setLastAccess(Time.toMillis(clientSession.getTimestamp()));
          break;
        }
      }

      sessions.add(rep);
    }
    return sessions;
  }
Exemple #2
0
  protected boolean isLogoutPostBindingForClient(ClientSessionModel clientSession) {
    ClientModel client = clientSession.getClient();
    SamlClient samlClient = new SamlClient(client);
    String logoutPostUrl = client.getAttribute(SAML_SINGLE_LOGOUT_SERVICE_URL_POST_ATTRIBUTE);
    String logoutRedirectUrl =
        client.getAttribute(SAML_SINGLE_LOGOUT_SERVICE_URL_REDIRECT_ATTRIBUTE);

    if (logoutPostUrl == null) {
      // if we don't have a redirect uri either, return true and default to the admin url + POST
      // binding
      if (logoutRedirectUrl == null) return true;
      return false;
    }

    if (samlClient.forcePostBinding()) {
      return true; // configured to force a post binding and post binding logout url is not null
    }

    String bindingType = clientSession.getNote(SAML_BINDING);

    // if the login binding was POST, return true
    if (SAML_POST_BINDING.equals(bindingType)) return true;

    if (logoutRedirectUrl == null)
      return true; // we don't have a redirect binding url, so use post binding

    return false; // redirect binding
  }
Exemple #3
0
 protected AccessToken initToken(
     RealmModel realm,
     ClientModel client,
     UserModel user,
     UserSessionModel session,
     ClientSessionModel clientSession) {
   AccessToken token = new AccessToken();
   if (clientSession != null) token.clientSession(clientSession.getId());
   token.id(KeycloakModelUtils.generateId());
   token.subject(user.getId());
   token.audience(client.getClientId());
   token.issuedNow();
   token.issuedFor(client.getClientId());
   token.issuer(clientSession.getNote(OIDCLoginProtocol.ISSUER));
   if (session != null) {
     token.setSessionState(session.getId());
   }
   if (realm.getAccessTokenLifespan() > 0) {
     token.expiration(Time.currentTime() + realm.getAccessTokenLifespan());
   }
   Set<String> allowedOrigins = client.getWebOrigins();
   if (allowedOrigins != null) {
     token.setAllowedOrigins(allowedOrigins);
   }
   return token;
 }
    private ClientSessionCode parseClientSessionCode(String code) {
      ClientSessionCode clientCode = ClientSessionCode.parse(code, this.session, this.realm);

      if (clientCode != null
          && clientCode.isValid(AUTHENTICATE.name(), ClientSessionCode.ActionType.LOGIN)) {
        ClientSessionModel clientSession = clientCode.getClientSession();

        if (clientSession != null) {
          ClientModel client = clientSession.getClient();

          if (client == null) {
            throw new IdentityBrokerException("Invalid client");
          }

          logger.debugf("Got authorization code from client [%s].", client.getClientId());
        }

        logger.debugf("Authorization code is valid.");

        return clientCode;
      }

      throw new IdentityBrokerException(
          "Invalid code, please login again through your application.");
    }
  /**
   * Get offline sessions associated with the user and client
   *
   * @param id User id
   * @return
   */
  @Path("{id}/offline-sessions/{clientId}")
  @GET
  @NoCache
  @Produces(MediaType.APPLICATION_JSON)
  public List<UserSessionRepresentation> getSessions(
      final @PathParam("id") String id, final @PathParam("clientId") String clientId) {
    auth.requireView();
    UserModel user = session.users().getUserById(id, realm);
    if (user == null) {
      throw new NotFoundException("User not found");
    }
    ClientModel client = realm.getClientById(clientId);
    if (client == null) {
      throw new NotFoundException("Client not found");
    }
    List<UserSessionModel> sessions =
        new UserSessionManager(session).findOfflineSessions(realm, client, user);
    List<UserSessionRepresentation> reps = new ArrayList<UserSessionRepresentation>();
    for (UserSessionModel session : sessions) {
      UserSessionRepresentation rep = ModelToRepresentation.toRepresentation(session);

      // Update lastSessionRefresh with the timestamp from clientSession
      for (ClientSessionModel clientSession : session.getClientSessions()) {
        if (clientId.equals(clientSession.getClient().getId())) {
          rep.setLastAccess(Time.toMillis(clientSession.getTimestamp()));
          break;
        }
      }

      reps.add(rep);
    }
    return reps;
  }
  private static String createAdminToken(String username, String realm) {
    KeycloakSession session = keycloakRule.startSession();
    try {
      RealmManager manager = new RealmManager(session);

      RealmModel adminRealm = manager.getRealm(realm);
      ClientModel adminConsole = adminRealm.getClientByClientId(Constants.ADMIN_CLI_CLIENT_ID);
      TokenManager tm = new TokenManager();
      UserModel admin = session.users().getUserByUsername(username, adminRealm);
      ClientSessionModel clientSession =
          session.sessions().createClientSession(adminRealm, adminConsole);
      clientSession.setNote(OIDCLoginProtocol.ISSUER, "http://localhost:8081/auth/realms/" + realm);
      UserSessionModel userSession =
          session
              .sessions()
              .createUserSession(adminRealm, admin, "admin", null, "form", false, null, null);
      AccessToken token =
          tm.createClientAccessToken(
              session,
              tm.getAccess(null, true, adminConsole, admin),
              adminRealm,
              adminConsole,
              admin,
              userSession,
              clientSession);
      return tm.encodeToken(adminRealm, token);
    } finally {
      keycloakRule.stopSession(session, true);
    }
  }
 /**
  * Initiated by admin, not the user on login
  *
  * @param key
  * @return
  */
 @Path("execute-actions")
 @GET
 public Response executeActions(@QueryParam("key") String key) {
   event.event(EventType.EXECUTE_ACTIONS);
   if (key != null) {
     Checks checks = new Checks();
     if (!checks.verifyCode(key, ClientSessionModel.Action.EXECUTE_ACTIONS.name())) {
       return checks.response;
     }
     ClientSessionModel clientSession = checks.clientCode.getClientSession();
     clientSession.setNote(AuthenticationManager.END_AFTER_REQUIRED_ACTIONS, "true");
     clientSession.setNote(ClientSessionModel.Action.EXECUTE_ACTIONS.name(), "true");
     return AuthenticationManager.nextActionAfterAuthentication(
         session,
         clientSession.getUserSession(),
         clientSession,
         clientConnection,
         request,
         uriInfo,
         event);
   } else {
     event.error(Errors.INVALID_CODE);
     return ErrorPage.error(session, Messages.INVALID_CODE);
   }
 }
 /**
  * Endpoint for executing reset credentials flow. If code is null, a client session is created
  * with the account service as the client. Successful reset sends you to the account page. Note,
  * account service must be enabled.
  *
  * @param code
  * @param execution
  * @return
  */
 @Path(RESET_CREDENTIALS_PATH)
 @GET
 public Response resetCredentialsGET(
     @QueryParam("code") String code, @QueryParam("execution") String execution) {
   // we allow applications to link to reset credentials without going through OAuth or SAML
   // handshakes
   //
   if (code == null) {
     if (!realm.isResetPasswordAllowed()) {
       event.event(EventType.RESET_PASSWORD);
       event.error(Errors.NOT_ALLOWED);
       return ErrorPage.error(session, Messages.RESET_CREDENTIAL_NOT_ALLOWED);
     }
     // set up the account service as the endpoint to call.
     ClientModel client = realm.getClientByClientId(Constants.ACCOUNT_MANAGEMENT_CLIENT_ID);
     ClientSessionModel clientSession = session.sessions().createClientSession(realm, client);
     clientSession.setAction(ClientSessionModel.Action.AUTHENTICATE.name());
     clientSession.setNote(ClientSessionCode.ACTION_KEY, KeycloakModelUtils.generateCodeSecret());
     // clientSession.setNote(AuthenticationManager.END_AFTER_REQUIRED_ACTIONS, "true");
     clientSession.setAuthMethod(OIDCLoginProtocol.LOGIN_PROTOCOL);
     String redirectUri =
         Urls.accountBase(uriInfo.getBaseUri()).path("/").build(realm.getName()).toString();
     clientSession.setRedirectUri(redirectUri);
     clientSession.setAction(ClientSessionModel.Action.AUTHENTICATE.name());
     clientSession.setNote(ClientSessionCode.ACTION_KEY, KeycloakModelUtils.generateCodeSecret());
     clientSession.setNote(OIDCLoginProtocol.RESPONSE_TYPE_PARAM, OAuth2Constants.CODE);
     clientSession.setNote(OIDCLoginProtocol.REDIRECT_URI_PARAM, redirectUri);
     clientSession.setNote(
         OIDCLoginProtocol.ISSUER, Urls.realmIssuer(uriInfo.getBaseUri(), realm.getName()));
     return processResetCredentials(null, clientSession, null);
   }
   return resetCredentials(code, execution);
 }
Exemple #9
0
 protected Response buildErrorResponse(
     ClientSessionModel clientSession, JaxrsSAML2BindingBuilder binding, Document document)
     throws ConfigurationException, ProcessingException, IOException {
   if (isPostBinding(clientSession)) {
     return binding.postBinding(document).response(clientSession.getRedirectUri());
   } else {
     return binding.redirectBinding(document).response(clientSession.getRedirectUri());
   }
 }
  private ClientSessionModel createClientSession(
      UserModel user, String redirectUri, String clientId) {

    if (!user.isEnabled()) {
      throw new WebApplicationException(
          ErrorResponse.error("User is disabled", Response.Status.BAD_REQUEST));
    }

    if (redirectUri != null && clientId == null) {
      throw new WebApplicationException(
          ErrorResponse.error("Client id missing", Response.Status.BAD_REQUEST));
    }

    if (clientId == null) {
      clientId = Constants.ACCOUNT_MANAGEMENT_CLIENT_ID;
    }

    ClientModel client = realm.getClientByClientId(clientId);
    if (client == null || !client.isEnabled()) {
      throw new WebApplicationException(
          ErrorResponse.error(clientId + " not enabled", Response.Status.BAD_REQUEST));
    }

    String redirect;
    if (redirectUri != null) {
      redirect = RedirectUtils.verifyRedirectUri(uriInfo, redirectUri, realm, client);
      if (redirect == null) {
        throw new WebApplicationException(
            ErrorResponse.error("Invalid redirect uri.", Response.Status.BAD_REQUEST));
      }
    } else {
      redirect = Urls.accountBase(uriInfo.getBaseUri()).path("/").build(realm.getName()).toString();
    }

    UserSessionModel userSession =
        session
            .sessions()
            .createUserSession(
                realm,
                user,
                user.getUsername(),
                clientConnection.getRemoteAddr(),
                "form",
                false,
                null,
                null);
    // audit.session(userSession);
    ClientSessionModel clientSession = session.sessions().createClientSession(realm, client);
    clientSession.setAuthMethod(OIDCLoginProtocol.LOGIN_PROTOCOL);
    clientSession.setRedirectUri(redirect);
    clientSession.setUserSession(userSession);

    return clientSession;
  }
  @Path("email-verification")
  @GET
  public Response emailVerification(
      @QueryParam("code") String code, @QueryParam("key") String key) {
    event.event(EventType.VERIFY_EMAIL);
    if (key != null) {
      Checks checks = new Checks();
      if (!checks.verifyCode(key, ClientSessionModel.Action.VERIFY_EMAIL.name())) {
        return checks.response;
      }
      ClientSessionCode accessCode = checks.clientCode;
      ClientSessionModel clientSession = accessCode.getClientSession();
      UserSessionModel userSession = clientSession.getUserSession();
      UserModel user = userSession.getUser();
      initEvent(clientSession);
      user.setEmailVerified(true);

      user.removeRequiredAction(RequiredAction.VERIFY_EMAIL);

      event.event(EventType.VERIFY_EMAIL).detail(Details.EMAIL, user.getEmail()).success();

      String actionCookieValue = getActionCookie();
      if (actionCookieValue == null || !actionCookieValue.equals(userSession.getId())) {
        session.sessions().removeClientSession(realm, clientSession);
        return session
            .getProvider(LoginFormsProvider.class)
            .setSuccess(Messages.EMAIL_VERIFIED)
            .createInfoPage();
      }

      event = event.clone().removeDetail(Details.EMAIL).event(EventType.LOGIN);

      return AuthenticationManager.nextActionAfterAuthentication(
          session, userSession, clientSession, clientConnection, request, uriInfo, event);
    } else {
      Checks checks = new Checks();
      if (!checks.verifyCode(code, ClientSessionModel.Action.VERIFY_EMAIL.name())) {
        return checks.response;
      }
      ClientSessionCode accessCode = checks.clientCode;
      ClientSessionModel clientSession = accessCode.getClientSession();
      UserSessionModel userSession = clientSession.getUserSession();
      initEvent(clientSession);

      createActionCookie(realm, uriInfo, clientConnection, userSession.getId());

      return session
          .getProvider(LoginFormsProvider.class)
          .setClientSessionCode(accessCode.getCode())
          .setUser(userSession.getUser())
          .createResponse(RequiredAction.VERIFY_EMAIL);
    }
  }
Exemple #12
0
 protected SAML2LogoutRequestBuilder createLogoutRequest(
     String logoutUrl, ClientSessionModel clientSession, ClientModel client) {
   // build userPrincipal with subject used at login
   SAML2LogoutRequestBuilder logoutBuilder =
       new SAML2LogoutRequestBuilder()
           .assertionExpiration(realm.getAccessCodeLifespan())
           .issuer(getResponseIssuer(realm))
           .sessionIndex(clientSession.getId())
           .userPrincipal(
               clientSession.getNote(SAML_NAME_ID), clientSession.getNote(SAML_NAME_ID_FORMAT))
           .destination(logoutUrl);
   return logoutBuilder;
 }
  /**
   * Send a update account email to the user
   *
   * <p>An email contains a link the user can click to perform a set of required actions. The
   * redirectUri and clientId parameters are optional. The default for the redirect is the account
   * client.
   *
   * @param id User is
   * @param redirectUri Redirect uri
   * @param clientId Client id
   * @param actions required actions the user needs to complete
   * @return
   */
  @Path("{id}/execute-actions-email")
  @PUT
  @Consumes(MediaType.APPLICATION_JSON)
  public Response executeActionsEmail(
      @PathParam("id") String id,
      @QueryParam(OIDCLoginProtocol.REDIRECT_URI_PARAM) String redirectUri,
      @QueryParam(OIDCLoginProtocol.CLIENT_ID_PARAM) String clientId,
      List<String> actions) {
    auth.requireManage();

    UserModel user = session.users().getUserById(id, realm);
    if (user == null) {
      return ErrorResponse.error("User not found", Response.Status.NOT_FOUND);
    }

    if (user.getEmail() == null) {
      return ErrorResponse.error("User email missing", Response.Status.BAD_REQUEST);
    }

    ClientSessionModel clientSession = createClientSession(user, redirectUri, clientId);
    for (String action : actions) {
      clientSession.addRequiredAction(action);
    }
    ClientSessionCode accessCode = new ClientSessionCode(realm, clientSession);
    accessCode.setAction(ClientSessionModel.Action.EXECUTE_ACTIONS.name());

    try {
      UriBuilder builder = Urls.executeActionsBuilder(uriInfo.getBaseUri());
      builder.queryParam("key", accessCode.getCode());

      String link = builder.build(realm.getName()).toString();
      long expiration = TimeUnit.SECONDS.toMinutes(realm.getAccessCodeLifespanUserAction());

      this.session
          .getProvider(EmailTemplateProvider.class)
          .setRealm(realm)
          .setUser(user)
          .sendExecuteActions(link, expiration);

      // audit.user(user).detail(Details.EMAIL, user.getEmail()).detail(Details.CODE_ID,
      // accessCode.getCodeId()).success();

      adminEvent.operation(OperationType.ACTION).resourcePath(uriInfo).success();

      return Response.ok().build();
    } catch (EmailException e) {
      logger.failedToSendActionsEmail(e);
      return ErrorResponse.error(
          "Failed to send execute actions email", Response.Status.INTERNAL_SERVER_ERROR);
    }
  }
Exemple #14
0
  public static void attachClientSession(
      UserSessionModel session, ClientSessionModel clientSession) {
    if (clientSession.getUserSession() != null) {
      return;
    }

    UserModel user = session.getUser();
    clientSession.setUserSession(session);
    Set<String> requestedRoles = new HashSet<String>();
    // todo scope param protocol independent
    for (RoleModel r : TokenManager.getAccess(null, clientSession.getClient(), user)) {
      requestedRoles.add(r.getId());
    }
    clientSession.setRoles(requestedRoles);

    Set<String> requestedProtocolMappers = new HashSet<String>();
    for (ProtocolMapperModel protocolMapper : clientSession.getClient().getProtocolMappers()) {
      if (protocolMapper.getProtocol().equals(clientSession.getAuthMethod())) {
        requestedProtocolMappers.add(protocolMapper.getId());
      }
    }
    clientSession.setProtocolMappers(requestedProtocolMappers);

    Map<String, String> transferredNotes = clientSession.getUserSessionNotes();
    for (Map.Entry<String, String> entry : transferredNotes.entrySet()) {
      session.setNote(entry.getKey(), entry.getValue());
    }
  }
  @Override
  public Response sendError(ClientSessionModel clientSession, Error error) {
    setupResponseTypeAndMode(clientSession);

    String redirect = clientSession.getRedirectUri();
    String state = clientSession.getNote(OIDCLoginProtocol.STATE_PARAM);
    OIDCRedirectUriBuilder redirectUri =
        OIDCRedirectUriBuilder.fromUri(redirect, responseMode)
            .addParam(OAuth2Constants.ERROR, translateError(error));
    if (state != null) redirectUri.addParam(OAuth2Constants.STATE, state);
    session.sessions().removeClientSession(realm, clientSession);
    RestartLoginCookie.expireRestartCookie(realm, session.getContext().getConnection(), uriInfo);
    return redirectUri.build();
  }
Exemple #16
0
  public static void dettachClientSession(
      UserSessionProvider sessions, RealmModel realm, ClientSessionModel clientSession) {
    UserSessionModel userSession = clientSession.getUserSession();
    if (userSession == null) {
      return;
    }

    clientSession.setUserSession(null);
    clientSession.setRoles(null);
    clientSession.setProtocolMappers(null);

    if (userSession.getClientSessions().isEmpty()) {
      sessions.removeUserSession(realm, userSession);
    }
  }
Exemple #17
0
 @Override
 public Response frontchannelLogout(
     UserSessionModel userSession, ClientSessionModel clientSession) {
   ClientModel client = clientSession.getClient();
   SamlClient samlClient = new SamlClient(client);
   if (!(client instanceof ClientModel)) return null;
   try {
     if (isLogoutPostBindingForClient(clientSession)) {
       String bindingUri = getLogoutServiceUrl(uriInfo, client, SAML_POST_BINDING);
       SAML2LogoutRequestBuilder logoutBuilder =
           createLogoutRequest(bindingUri, clientSession, client);
       JaxrsSAML2BindingBuilder binding = createBindingBuilder(samlClient);
       return binding.postBinding(logoutBuilder.buildDocument()).request(bindingUri);
     } else {
       logger.debug("frontchannel redirect binding");
       String bindingUri = getLogoutServiceUrl(uriInfo, client, SAML_REDIRECT_BINDING);
       SAML2LogoutRequestBuilder logoutBuilder =
           createLogoutRequest(bindingUri, clientSession, client);
       JaxrsSAML2BindingBuilder binding = createBindingBuilder(samlClient);
       return binding.redirectBinding(logoutBuilder.buildDocument()).request(bindingUri);
     }
   } catch (ConfigurationException e) {
     throw new RuntimeException(e);
   } catch (ProcessingException e) {
     throw new RuntimeException(e);
   } catch (IOException e) {
     throw new RuntimeException(e);
   } catch (ParsingException e) {
     throw new RuntimeException(e);
   }
 }
Exemple #18
0
  @Override
  public void backchannelLogout(UserSessionModel userSession, ClientSessionModel clientSession) {
    ClientModel client = clientSession.getClient();
    SamlClient samlClient = new SamlClient(client);
    String logoutUrl = getLogoutServiceUrl(uriInfo, client, SAML_POST_BINDING);
    if (logoutUrl == null) {
      logger.warnv(
          "Can't do backchannel logout. No SingleLogoutService POST Binding registered for client: {1}",
          client.getClientId());
      return;
    }
    SAML2LogoutRequestBuilder logoutBuilder = createLogoutRequest(logoutUrl, clientSession, client);

    String logoutRequestString = null;
    try {
      JaxrsSAML2BindingBuilder binding = createBindingBuilder(samlClient);
      logoutRequestString = binding.postBinding(logoutBuilder.buildDocument()).encoded();
    } catch (Exception e) {
      logger.warn("failed to send saml logout", e);
      return;
    }

    HttpClient httpClient = session.getProvider(HttpClientProvider.class).getHttpClient();
    for (int i = 0; i < 2; i++) { // follow redirects once
      try {
        List<NameValuePair> formparams = new ArrayList<NameValuePair>();
        formparams.add(
            new BasicNameValuePair(GeneralConstants.SAML_REQUEST_KEY, logoutRequestString));
        formparams.add(
            new BasicNameValuePair("BACK_CHANNEL_LOGOUT", "BACK_CHANNEL_LOGOUT")); // for Picketlink
        // todo remove
        // this
        UrlEncodedFormEntity form = new UrlEncodedFormEntity(formparams, "UTF-8");
        HttpPost post = new HttpPost(logoutUrl);
        post.setEntity(form);
        HttpResponse response = httpClient.execute(post);
        try {
          int status = response.getStatusLine().getStatusCode();
          if (status == 302 && !logoutUrl.endsWith("/")) {
            String redirect = response.getFirstHeader(HttpHeaders.LOCATION).getValue();
            String withSlash = logoutUrl + "/";
            if (withSlash.equals(redirect)) {
              logoutUrl = withSlash;
              continue;
            }
          }
        } finally {
          HttpEntity entity = response.getEntity();
          if (entity != null) {
            InputStream is = entity.getContent();
            if (is != null) is.close();
          }
        }
      } catch (IOException e) {
        logger.warn("failed to send saml logout", e);
      }
      break;
    }
  }
 private void setupResponseTypeAndMode(ClientSessionModel clientSession) {
   String responseType = clientSession.getNote(OIDCLoginProtocol.RESPONSE_TYPE_PARAM);
   String responseMode = clientSession.getNote(OIDCLoginProtocol.RESPONSE_MODE_PARAM);
   this.responseType = OIDCResponseType.parse(responseType);
   this.responseMode = OIDCResponseMode.parse(responseMode, this.responseType);
   this.event.detail(Details.RESPONSE_TYPE, responseType);
   this.event.detail(Details.RESPONSE_MODE, this.responseMode.toString().toLowerCase());
 }
  @Override
  public Response authenticated(UserSessionModel userSession, ClientSessionCode accessCode) {
    ClientSessionModel clientSession = accessCode.getClientSession();
    setupResponseTypeAndMode(clientSession);

    String redirect = clientSession.getRedirectUri();
    OIDCRedirectUriBuilder redirectUri = OIDCRedirectUriBuilder.fromUri(redirect, responseMode);
    String state = clientSession.getNote(OIDCLoginProtocol.STATE_PARAM);
    logger.debugv("redirectAccessCode: state: {0}", state);
    if (state != null) redirectUri.addParam(OAuth2Constants.STATE, state);

    // Standard or hybrid flow
    if (responseType.hasResponseType(OIDCResponseType.CODE)) {
      accessCode.setAction(ClientSessionModel.Action.CODE_TO_TOKEN.name());
      redirectUri.addParam(OAuth2Constants.CODE, accessCode.getCode());
    }

    // Implicit or hybrid flow
    if (responseType.isImplicitOrHybridFlow()) {
      TokenManager tokenManager = new TokenManager();
      AccessTokenResponse res =
          tokenManager
              .responseBuilder(
                  realm, clientSession.getClient(), event, session, userSession, clientSession)
              .generateAccessToken()
              .generateIDToken()
              .build();

      if (responseType.hasResponseType(OIDCResponseType.ID_TOKEN)) {
        redirectUri.addParam("id_token", res.getIdToken());
      }

      if (responseType.hasResponseType(OIDCResponseType.TOKEN)) {
        redirectUri.addParam("access_token", res.getToken());
        redirectUri.addParam("token_type", res.getTokenType());
        redirectUri.addParam("session-state", res.getSessionState());
        redirectUri.addParam("expires_in", String.valueOf(res.getExpiresIn()));
      }

      redirectUri.addParam("not-before-policy", String.valueOf(res.getNotBeforePolicy()));
    }

    return redirectUri.build();
  }
Exemple #21
0
  protected String getNameIdFormat(SamlClient samlClient, ClientSessionModel clientSession) {
    String nameIdFormat = clientSession.getNote(GeneralConstants.NAMEID_FORMAT);

    boolean forceFormat = samlClient.forceNameIDFormat();
    String configuredNameIdFormat = samlClient.getNameIDFormat();
    if ((nameIdFormat == null || forceFormat) && configuredNameIdFormat != null) {
      nameIdFormat = configuredNameIdFormat;
    }
    if (nameIdFormat == null) return SAML_DEFAULT_NAMEID_FORMAT;
    return nameIdFormat;
  }
  @Override
  public Response performLogin(AuthenticationRequest request) {
    try {
      Twitter twitter = new TwitterFactory().getInstance();
      twitter.setOAuthConsumer(getConfig().getClientId(), getConfig().getClientSecret());

      URI uri = new URI(request.getRedirectUri() + "?state=" + request.getState());

      RequestToken requestToken = twitter.getOAuthRequestToken(uri.toString());
      ClientSessionModel clientSession = request.getClientSession();

      clientSession.setNote("twitter_token", requestToken.getToken());
      clientSession.setNote("twitter_tokenSecret", requestToken.getTokenSecret());

      URI authenticationUrl = URI.create(requestToken.getAuthenticationURL());

      return Response.temporaryRedirect(authenticationUrl).build();
    } catch (Exception e) {
      throw new IdentityBrokerException("Could send authentication request to twitter.", e);
    }
  }
Exemple #23
0
 @Override
 public Response sendError(ClientSessionModel clientSession, Error error) {
   try {
     if ("true".equals(clientSession.getClient().getAttribute(SAML_IDP_INITIATED_LOGIN))) {
       if (error == Error.CANCELLED_BY_USER) {
         UriBuilder builder =
             RealmsResource.protocolUrl(uriInfo).path(SamlService.class, "idpInitiatedSSO");
         Map<String, String> params = new HashMap<>();
         params.put("realm", realm.getName());
         params.put("protocol", LOGIN_PROTOCOL);
         params.put(
             "client", clientSession.getClient().getAttribute(SAML_IDP_INITIATED_SSO_URL_NAME));
         URI redirect = builder.buildFromMap(params);
         return Response.status(302).location(redirect).build();
       } else {
         return ErrorPage.error(session, translateErrorToIdpInitiatedErrorMessage(error));
       }
     } else {
       SAML2ErrorResponseBuilder builder =
           new SAML2ErrorResponseBuilder()
               .destination(clientSession.getRedirectUri())
               .issuer(getResponseIssuer(realm))
               .status(translateErrorToSAMLStatus(error).get());
       try {
         JaxrsSAML2BindingBuilder binding =
             new JaxrsSAML2BindingBuilder()
                 .relayState(clientSession.getNote(GeneralConstants.RELAY_STATE));
         Document document = builder.buildDocument();
         return buildErrorResponse(clientSession, binding, document);
       } catch (Exception e) {
         return ErrorPage.error(session, Messages.FAILED_TO_PROCESS_RESPONSE);
       }
     }
   } finally {
     RestartLoginCookie.expireRestartCookie(realm, session.getContext().getConnection(), uriInfo);
     session.sessions().removeClientSession(realm, clientSession);
   }
 }
Exemple #24
0
  /**
   * Attempts to retrieve the persistent type NameId as follows:
   *
   * <ol>
   *   <li>saml.persistent.name.id.for.$clientId user attribute
   *   <li>saml.persistent.name.id.for.* user attribute
   *   <li>G-$randomUuid
   * </ol>
   *
   * If a randomUuid is generated, an attribute for the given saml.persistent.name.id.for.$clientId
   * will be generated, otherwise no state change will occur with respect to the user's attributes.
   *
   * @return the user's persistent NameId
   */
  protected String getPersistentNameId(
      final ClientSessionModel clientSession, final UserSessionModel userSession) {
    // attempt to retrieve the UserID for the client-specific attribute
    final UserModel user = userSession.getUser();
    final String clientNameId =
        String.format(
            "%s.%s", SAML_PERSISTENT_NAME_ID_FOR, clientSession.getClient().getClientId());
    String samlPersistentNameId = user.getFirstAttribute(clientNameId);
    if (samlPersistentNameId != null) {
      return samlPersistentNameId;
    }

    // check for a wildcard attribute
    final String wildcardNameId = String.format("%s.*", SAML_PERSISTENT_NAME_ID_FOR);
    samlPersistentNameId = user.getFirstAttribute(wildcardNameId);
    if (samlPersistentNameId != null) {
      return samlPersistentNameId;
    }

    // default to generated.  "G-" stands for "generated"
    samlPersistentNameId = "G-" + UUID.randomUUID().toString();
    user.setSingleAttribute(clientNameId, samlPersistentNameId);
    return samlPersistentNameId;
  }
  private void initEvent(ClientSessionModel clientSession) {
    event
        .event(EventType.LOGIN)
        .client(clientSession.getClient())
        .user(clientSession.getUserSession().getUser())
        .session(clientSession.getUserSession().getId())
        .detail(Details.CODE_ID, clientSession.getId())
        .detail(Details.REDIRECT_URI, clientSession.getRedirectUri())
        .detail(
            Details.USERNAME,
            clientSession.getNote(AbstractUsernameFormAuthenticator.ATTEMPTED_USERNAME))
        .detail(Details.RESPONSE_TYPE, "code");

    UserSessionModel userSession = clientSession.getUserSession();

    if (userSession != null) {
      event.detail(Details.AUTH_METHOD, userSession.getAuthMethod());
      event.detail(Details.USERNAME, userSession.getLoginUsername());
      if (userSession.isRememberMe()) {
        event.detail(Details.REMEMBER_ME, "true");
      }
    }
  }
Exemple #26
0
  @GET
  @Path("clients/{client}")
  @Produces(MediaType.TEXT_HTML)
  public Response idpInitiatedSSO(
      @PathParam("client") String clientUrlName, @QueryParam("RelayState") String relayState) {
    event.event(EventType.LOGIN);
    CacheControlUtil.noBackButtonCacheControlHeader();
    ClientModel client = null;
    for (ClientModel c : realm.getClients()) {
      String urlName = c.getAttribute(SamlProtocol.SAML_IDP_INITIATED_SSO_URL_NAME);
      if (urlName == null) continue;
      if (urlName.equals(clientUrlName)) {
        client = c;
        break;
      }
    }
    if (client == null) {
      event.error(Errors.CLIENT_NOT_FOUND);
      return ErrorPage.error(session, Messages.CLIENT_NOT_FOUND);
    }
    if (client.getManagementUrl() == null
        && client.getAttribute(SamlProtocol.SAML_ASSERTION_CONSUMER_URL_POST_ATTRIBUTE) == null
        && client.getAttribute(SamlProtocol.SAML_ASSERTION_CONSUMER_URL_REDIRECT_ATTRIBUTE)
            == null) {
      logger.error("SAML assertion consumer url not set up");
      event.error(Errors.INVALID_REDIRECT_URI);
      return ErrorPage.error(session, Messages.INVALID_REDIRECT_URI);
    }

    String bindingType = SamlProtocol.SAML_POST_BINDING;
    if (client.getManagementUrl() == null
        && client.getAttribute(SamlProtocol.SAML_ASSERTION_CONSUMER_URL_POST_ATTRIBUTE) == null
        && client.getAttribute(SamlProtocol.SAML_ASSERTION_CONSUMER_URL_REDIRECT_ATTRIBUTE)
            != null) {
      bindingType = SamlProtocol.SAML_REDIRECT_BINDING;
    }

    String redirect = null;
    if (bindingType.equals(SamlProtocol.SAML_REDIRECT_BINDING)) {
      redirect = client.getAttribute(SamlProtocol.SAML_ASSERTION_CONSUMER_URL_REDIRECT_ATTRIBUTE);
    } else {
      redirect = client.getAttribute(SamlProtocol.SAML_ASSERTION_CONSUMER_URL_POST_ATTRIBUTE);
    }
    if (redirect == null) {
      redirect = client.getManagementUrl();
    }

    ClientSessionModel clientSession = session.sessions().createClientSession(realm, client);
    clientSession.setAuthMethod(SamlProtocol.LOGIN_PROTOCOL);
    clientSession.setAction(ClientSessionModel.Action.AUTHENTICATE.name());
    clientSession.setNote(SamlProtocol.SAML_BINDING, SamlProtocol.SAML_POST_BINDING);
    clientSession.setNote(SamlProtocol.SAML_IDP_INITIATED_LOGIN, "true");
    clientSession.setRedirectUri(redirect);

    if (relayState == null) {
      relayState = client.getAttribute(SamlProtocol.SAML_IDP_INITIATED_SSO_RELAY_STATE);
    }
    if (relayState != null && !relayState.trim().equals("")) {
      clientSession.setNote(GeneralConstants.RELAY_STATE, relayState);
    }

    return newBrowserAuthentication(clientSession, false, false);
  }
Exemple #27
0
    protected Response logoutRequest(
        LogoutRequestType logoutRequest, ClientModel client, String relayState) {
      SamlClient samlClient = new SamlClient(client);
      // validate destination
      if (logoutRequest.getDestination() != null
          && !uriInfo.getAbsolutePath().equals(logoutRequest.getDestination())) {
        event.detail(Details.REASON, "invalid_destination");
        event.error(Errors.INVALID_SAML_LOGOUT_REQUEST);
        return ErrorPage.error(session, Messages.INVALID_REQUEST);
      }

      // authenticate identity cookie, but ignore an access token timeout as we're logging out
      // anyways.
      AuthenticationManager.AuthResult authResult =
          authManager.authenticateIdentityCookie(session, realm, false);
      if (authResult != null) {
        String logoutBinding = getBindingType();
        if ("true".equals(samlClient.forcePostBinding()))
          logoutBinding = SamlProtocol.SAML_POST_BINDING;
        String bindingUri = SamlProtocol.getLogoutServiceUrl(uriInfo, client, logoutBinding);
        UserSessionModel userSession = authResult.getSession();
        userSession.setNote(SamlProtocol.SAML_LOGOUT_BINDING_URI, bindingUri);
        if (samlClient.requiresRealmSignature()) {
          userSession.setNote(
              SamlProtocol.SAML_LOGOUT_SIGNATURE_ALGORITHM,
              samlClient.getSignatureAlgorithm().toString());
        }
        if (relayState != null)
          userSession.setNote(SamlProtocol.SAML_LOGOUT_RELAY_STATE, relayState);
        userSession.setNote(SamlProtocol.SAML_LOGOUT_REQUEST_ID, logoutRequest.getID());
        userSession.setNote(SamlProtocol.SAML_LOGOUT_BINDING, logoutBinding);
        userSession.setNote(
            SamlProtocol.SAML_LOGOUT_CANONICALIZATION, samlClient.getCanonicalizationMethod());
        userSession.setNote(
            AuthenticationManager.KEYCLOAK_LOGOUT_PROTOCOL, SamlProtocol.LOGIN_PROTOCOL);
        // remove client from logout requests
        for (ClientSessionModel clientSession : userSession.getClientSessions()) {
          if (clientSession.getClient().getId().equals(client.getId())) {
            clientSession.setAction(ClientSessionModel.Action.LOGGED_OUT.name());
          }
        }
        logger.debug("browser Logout");
        return authManager.browserLogout(
            session, realm, userSession, uriInfo, clientConnection, headers);
      } else if (logoutRequest.getSessionIndex() != null) {
        for (String sessionIndex : logoutRequest.getSessionIndex()) {
          ClientSessionModel clientSession =
              session.sessions().getClientSession(realm, sessionIndex);
          if (clientSession == null) continue;
          UserSessionModel userSession = clientSession.getUserSession();
          if (clientSession.getClient().getClientId().equals(client.getClientId())) {
            // remove requesting client from logout
            clientSession.setAction(ClientSessionModel.Action.LOGGED_OUT.name());

            // Remove also other clientSessions of this client as there could be more in this
            // UserSession
            if (userSession != null) {
              for (ClientSessionModel clientSession2 : userSession.getClientSessions()) {
                if (clientSession2.getClient().getId().equals(client.getId())) {
                  clientSession2.setAction(ClientSessionModel.Action.LOGGED_OUT.name());
                }
              }
            }
          }

          try {
            authManager.backchannelLogout(
                session, realm, userSession, uriInfo, clientConnection, headers, true);
          } catch (Exception e) {
            logger.warn("Failure with backchannel logout", e);
          }
        }
      }

      // default

      String logoutBinding = getBindingType();
      String logoutBindingUri = SamlProtocol.getLogoutServiceUrl(uriInfo, client, logoutBinding);
      String logoutRelayState = relayState;
      SAML2LogoutResponseBuilder builder = new SAML2LogoutResponseBuilder();
      builder.logoutRequestID(logoutRequest.getID());
      builder.destination(logoutBindingUri);
      builder.issuer(RealmsResource.realmBaseUrl(uriInfo).build(realm.getName()).toString());
      JaxrsSAML2BindingBuilder binding =
          new JaxrsSAML2BindingBuilder().relayState(logoutRelayState);
      if (samlClient.requiresRealmSignature()) {
        SignatureAlgorithm algorithm = samlClient.getSignatureAlgorithm();
        KeyManager.ActiveKey keys = session.keys().getActiveKey(realm);
        binding
            .signatureAlgorithm(algorithm)
            .signWith(keys.getPrivateKey(), keys.getPublicKey(), keys.getCertificate())
            .signDocument();
      }
      try {
        if (SamlProtocol.SAML_POST_BINDING.equals(logoutBinding)) {
          return binding.postBinding(builder.buildDocument()).response(logoutBindingUri);
        } else {
          return binding.redirectBinding(builder.buildDocument()).response(logoutBindingUri);
        }
      } catch (Exception e) {
        throw new RuntimeException(e);
      }
    }
Exemple #28
0
    protected Response loginRequest(
        String relayState, AuthnRequestType requestAbstractType, ClientModel client) {
      SamlClient samlClient = new SamlClient(client);
      // validate destination
      if (requestAbstractType.getDestination() != null
          && !uriInfo.getAbsolutePath().equals(requestAbstractType.getDestination())) {
        event.detail(Details.REASON, "invalid_destination");
        event.error(Errors.INVALID_SAML_AUTHN_REQUEST);
        return ErrorPage.error(session, Messages.INVALID_REQUEST);
      }
      String bindingType = getBindingType(requestAbstractType);
      if (samlClient.forcePostBinding()) bindingType = SamlProtocol.SAML_POST_BINDING;
      String redirect = null;
      URI redirectUri = requestAbstractType.getAssertionConsumerServiceURL();
      if (redirectUri != null && !"null".equals(redirectUri)) { // "null" is for testing purposes
        redirect = RedirectUtils.verifyRedirectUri(uriInfo, redirectUri.toString(), realm, client);
      } else {
        if (bindingType.equals(SamlProtocol.SAML_POST_BINDING)) {
          redirect = client.getAttribute(SamlProtocol.SAML_ASSERTION_CONSUMER_URL_POST_ATTRIBUTE);
        } else {
          redirect =
              client.getAttribute(SamlProtocol.SAML_ASSERTION_CONSUMER_URL_REDIRECT_ATTRIBUTE);
        }
        if (redirect == null) {
          redirect = client.getManagementUrl();
        }
      }

      if (redirect == null) {
        event.error(Errors.INVALID_REDIRECT_URI);
        return ErrorPage.error(session, Messages.INVALID_REDIRECT_URI);
      }

      ClientSessionModel clientSession = session.sessions().createClientSession(realm, client);
      clientSession.setAuthMethod(SamlProtocol.LOGIN_PROTOCOL);
      clientSession.setRedirectUri(redirect);
      clientSession.setAction(ClientSessionModel.Action.AUTHENTICATE.name());
      clientSession.setNote(SamlProtocol.SAML_BINDING, bindingType);
      clientSession.setNote(GeneralConstants.RELAY_STATE, relayState);
      clientSession.setNote(SamlProtocol.SAML_REQUEST_ID, requestAbstractType.getID());

      // Handle NameIDPolicy from SP
      NameIDPolicyType nameIdPolicy = requestAbstractType.getNameIDPolicy();
      if (nameIdPolicy != null && !samlClient.forceNameIDFormat()) {
        String nameIdFormat = nameIdPolicy.getFormat().toString();
        // TODO: Handle AllowCreate too, relevant for persistent NameID.
        if (isSupportedNameIdFormat(nameIdFormat)) {
          clientSession.setNote(GeneralConstants.NAMEID_FORMAT, nameIdFormat);
        } else {
          event.detail(Details.REASON, "unsupported_nameid_format");
          event.error(Errors.INVALID_SAML_AUTHN_REQUEST);
          return ErrorPage.error(session, Messages.UNSUPPORTED_NAME_ID_FORMAT);
        }
      }

      // Reading subject/nameID in the saml request
      SubjectType subject = requestAbstractType.getSubject();
      if (subject != null) {
        SubjectType.STSubType subType = subject.getSubType();
        if (subType != null) {
          BaseIDAbstractType baseID = subject.getSubType().getBaseID();
          if (baseID != null && baseID instanceof NameIDType) {
            NameIDType nameID = (NameIDType) baseID;
            clientSession.setNote(OIDCLoginProtocol.LOGIN_HINT_PARAM, nameID.getValue());
          }
        }
      }

      return newBrowserAuthentication(
          clientSession, requestAbstractType.isIsPassive(), redirectToAuthentication);
    }
Exemple #29
0
  @Path("federated-identity-update")
  @GET
  public Response processFederatedIdentityUpdate(
      @QueryParam("action") String action,
      @QueryParam("provider_id") String providerId,
      @QueryParam("stateChecker") String stateChecker) {
    if (auth == null) {
      return login("identity");
    }

    require(AccountRoles.MANAGE_ACCOUNT);
    csrfCheck(stateChecker);
    UserModel user = auth.getUser();

    if (Validation.isEmpty(providerId)) {
      setReferrerOnPage();
      return account
          .setError(Messages.MISSING_IDENTITY_PROVIDER)
          .createResponse(AccountPages.FEDERATED_IDENTITY);
    }
    AccountSocialAction accountSocialAction = AccountSocialAction.getAction(action);
    if (accountSocialAction == null) {
      setReferrerOnPage();
      return account
          .setError(Messages.INVALID_FEDERATED_IDENTITY_ACTION)
          .createResponse(AccountPages.FEDERATED_IDENTITY);
    }

    boolean hasProvider = false;

    for (IdentityProviderModel model : realm.getIdentityProviders()) {
      if (model.getAlias().equals(providerId)) {
        hasProvider = true;
      }
    }

    if (!hasProvider) {
      setReferrerOnPage();
      return account
          .setError(Messages.IDENTITY_PROVIDER_NOT_FOUND)
          .createResponse(AccountPages.FEDERATED_IDENTITY);
    }

    if (!user.isEnabled()) {
      setReferrerOnPage();
      return account
          .setError(Messages.ACCOUNT_DISABLED)
          .createResponse(AccountPages.FEDERATED_IDENTITY);
    }

    switch (accountSocialAction) {
      case ADD:
        String redirectUri =
            UriBuilder.fromUri(
                    Urls.accountFederatedIdentityPage(uriInfo.getBaseUri(), realm.getName()))
                .build()
                .toString();

        try {
          ClientSessionModel clientSession = auth.getClientSession();
          ClientSessionCode clientSessionCode = new ClientSessionCode(realm, clientSession);
          clientSessionCode.setAction(ClientSessionModel.Action.AUTHENTICATE.name());
          clientSession.setRedirectUri(redirectUri);
          clientSession.setNote(OIDCLoginProtocol.STATE_PARAM, UUID.randomUUID().toString());

          return Response.temporaryRedirect(
                  Urls.identityProviderAuthnRequest(
                      this.uriInfo.getBaseUri(),
                      providerId,
                      realm.getName(),
                      clientSessionCode.getCode()))
              .build();
        } catch (Exception spe) {
          setReferrerOnPage();
          return account
              .setError(Messages.IDENTITY_PROVIDER_REDIRECT_ERROR)
              .createResponse(AccountPages.FEDERATED_IDENTITY);
        }
      case REMOVE:
        FederatedIdentityModel link = session.users().getFederatedIdentity(user, providerId, realm);
        if (link != null) {

          // Removing last social provider is not possible if you don't have other possibility to
          // authenticate
          if (session.users().getFederatedIdentities(user, realm).size() > 1
              || user.getFederationLink() != null
              || isPasswordSet(user)) {
            session.users().removeFederatedIdentity(realm, user, providerId);

            logger.debugv(
                "Social provider {0} removed successfully from user {1}",
                providerId, user.getUsername());

            event
                .event(EventType.REMOVE_FEDERATED_IDENTITY)
                .client(auth.getClient())
                .user(auth.getUser())
                .detail(Details.USERNAME, link.getUserId() + "@" + link.getIdentityProvider())
                .success();

            setReferrerOnPage();
            return account
                .setSuccess(Messages.IDENTITY_PROVIDER_REMOVED)
                .createResponse(AccountPages.FEDERATED_IDENTITY);
          } else {
            setReferrerOnPage();
            return account
                .setError(Messages.FEDERATED_IDENTITY_REMOVING_LAST_PROVIDER)
                .createResponse(AccountPages.FEDERATED_IDENTITY);
          }
        } else {
          setReferrerOnPage();
          return account
              .setError(Messages.FEDERATED_IDENTITY_NOT_ACTIVE)
              .createResponse(AccountPages.FEDERATED_IDENTITY);
        }
      default:
        throw new IllegalArgumentException();
    }
  }
Exemple #30
0
  public void init() {
    eventStore = session.getProvider(EventStoreProvider.class);

    account =
        session
            .getProvider(AccountProvider.class)
            .setRealm(realm)
            .setUriInfo(uriInfo)
            .setHttpHeaders(headers);

    AuthenticationManager.AuthResult authResult =
        authManager.authenticateBearerToken(session, realm, uriInfo, clientConnection, headers);
    if (authResult != null) {
      auth =
          new Auth(
              realm,
              authResult.getToken(),
              authResult.getUser(),
              client,
              authResult.getSession(),
              false);
    } else {
      authResult = authManager.authenticateIdentityCookie(session, realm);
      if (authResult != null) {
        auth =
            new Auth(
                realm,
                authResult.getToken(),
                authResult.getUser(),
                client,
                authResult.getSession(),
                true);
        updateCsrfChecks();
        account.setStateChecker(stateChecker);
      }
    }

    String requestOrigin = UriUtils.getOrigin(uriInfo.getBaseUri());

    // don't allow cors requests unless they were authenticated by an access token
    // This is to prevent CSRF attacks.
    if (auth != null && auth.isCookieAuthenticated()) {
      String origin = headers.getRequestHeaders().getFirst("Origin");
      if (origin != null && !requestOrigin.equals(origin)) {
        throw new ForbiddenException();
      }

      if (!request.getHttpMethod().equals("GET")) {
        String referrer = headers.getRequestHeaders().getFirst("Referer");
        if (referrer != null && !requestOrigin.equals(UriUtils.getOrigin(referrer))) {
          throw new ForbiddenException();
        }
      }
    }

    if (authResult != null) {
      UserSessionModel userSession = authResult.getSession();
      if (userSession != null) {
        boolean associated = false;
        for (ClientSessionModel c : userSession.getClientSessions()) {
          if (c.getClient().equals(client)) {
            auth.setClientSession(c);
            associated = true;
            break;
          }
        }
        if (!associated) {
          ClientSessionModel clientSession = session.sessions().createClientSession(realm, client);
          clientSession.setUserSession(userSession);
          auth.setClientSession(clientSession);
        }
      }

      account.setUser(auth.getUser());
    }

    boolean eventsEnabled = eventStore != null && realm.isEventsEnabled();

    // todo find out from federation if password is updatable
    account.setFeatures(realm.isIdentityFederationEnabled(), eventsEnabled, true);
  }