Example #1
0
 protected Response buildLogoutResponse(
     UserSessionModel userSession,
     String logoutBindingUri,
     SAML2LogoutResponseBuilder builder,
     JaxrsSAML2BindingBuilder binding)
     throws ConfigurationException, ProcessingException, IOException {
   if (isLogoutPostBindingForInitiator(userSession)) {
     return binding.postBinding(builder.buildDocument()).response(logoutBindingUri);
   } else {
     return binding.redirectBinding(builder.buildDocument()).response(logoutBindingUri);
   }
 }
Example #2
0
  @Override
  public Response finishLogout(UserSessionModel userSession) {
    logger.debug("finishLogout");
    String logoutBindingUri = userSession.getNote(SAML_LOGOUT_BINDING_URI);
    if (logoutBindingUri == null) {
      logger.error(
          "Can't finish SAML logout as there is no logout binding set.  Please configure the logout service url in the admin console for your client applications.");
      return ErrorPage.error(session, Messages.FAILED_LOGOUT);
    }
    String logoutRelayState = userSession.getNote(SAML_LOGOUT_RELAY_STATE);
    SAML2LogoutResponseBuilder builder = new SAML2LogoutResponseBuilder();
    builder.logoutRequestID(userSession.getNote(SAML_LOGOUT_REQUEST_ID));
    builder.destination(logoutBindingUri);
    builder.issuer(getResponseIssuer(realm));
    JaxrsSAML2BindingBuilder binding = new JaxrsSAML2BindingBuilder();
    binding.relayState(logoutRelayState);
    String signingAlgorithm = userSession.getNote(SAML_LOGOUT_SIGNATURE_ALGORITHM);
    if (signingAlgorithm != null) {
      SignatureAlgorithm algorithm = SignatureAlgorithm.valueOf(signingAlgorithm);
      String canonicalization = userSession.getNote(SAML_LOGOUT_CANONICALIZATION);
      if (canonicalization != null) {
        binding.canonicalizationMethod(canonicalization);
      }
      KeyManager.ActiveKey keys = session.keys().getActiveKey(realm);
      binding
          .signatureAlgorithm(algorithm)
          .signWith(keys.getPrivateKey(), keys.getPublicKey(), keys.getCertificate())
          .signDocument();
    }

    try {
      return buildLogoutResponse(userSession, logoutBindingUri, builder, binding);
    } catch (ConfigurationException e) {
      throw new RuntimeException(e);
    } catch (ProcessingException e) {
      throw new RuntimeException(e);
    } catch (IOException e) {
      throw new RuntimeException(e);
    }
  }
Example #3
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);
      }
    }