예제 #1
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);
   }
 }
예제 #2
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;
    }
  }
예제 #3
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());
   }
 }
예제 #4
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);
   }
 }
예제 #5
0
 protected Response buildAuthenticatedResponse(
     ClientSessionModel clientSession,
     String redirectUri,
     Document samlDocument,
     JaxrsSAML2BindingBuilder bindingBuilder)
     throws ConfigurationException, ProcessingException, IOException {
   if (isPostBinding(clientSession)) {
     return bindingBuilder.postBinding(samlDocument).response(redirectUri);
   } else {
     return bindingBuilder.redirectBinding(samlDocument).response(redirectUri);
   }
 }
예제 #6
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);
      }
    }