protected AuthOutcome handleSamlRequest(String samlRequest, String relayState) {
    SAMLDocumentHolder holder = null;
    boolean postBinding = false;
    String requestUri = facade.getRequest().getURI();
    if (facade.getRequest().getMethod().equalsIgnoreCase("GET")) {
      // strip out query params
      int index = requestUri.indexOf('?');
      if (index > -1) {
        requestUri = requestUri.substring(0, index);
      }
      holder = SAMLRequestParser.parseRequestRedirectBinding(samlRequest);
    } else {
      postBinding = true;
      holder = SAMLRequestParser.parseRequestPostBinding(samlRequest);
    }
    RequestAbstractType requestAbstractType = (RequestAbstractType) holder.getSamlObject();
    if (!requestUri.equals(requestAbstractType.getDestination().toString())) {
      log.error(
          "expected destination '"
              + requestUri
              + "' got '"
              + requestAbstractType.getDestination()
              + "'");
      return AuthOutcome.FAILED;
    }

    if (requestAbstractType instanceof LogoutRequestType) {
      if (deployment.getIDP().getSingleLogoutService().validateRequestSignature()) {
        try {
          validateSamlSignature(holder, postBinding, GeneralConstants.SAML_REQUEST_KEY);
        } catch (VerificationException e) {
          log.error("Failed to verify saml request signature", e);
          return AuthOutcome.FAILED;
        }
      }
      LogoutRequestType logout = (LogoutRequestType) requestAbstractType;
      return logoutRequest(logout, relayState);

    } else {
      log.error("unknown SAML request type");
      return AuthOutcome.FAILED;
    }
  }
 private void validateSamlSignature(
     SAMLDocumentHolder holder, boolean postBinding, String paramKey)
     throws VerificationException {
   if (postBinding) {
     verifyPostBindingSignature(
         holder.getSamlDocument(), deployment.getIDP().getSignatureValidationKey());
   } else {
     verifyRedirectBindingSignature(deployment.getIDP().getSignatureValidationKey(), paramKey);
   }
 }
Esempio n. 3
0
    protected Response handleSamlResponse(String samlResponse, String relayState) {
      event.event(EventType.LOGOUT);
      SAMLDocumentHolder holder = extractResponseDocument(samlResponse);
      StatusResponseType statusResponse = (StatusResponseType) holder.getSamlObject();
      // validate destination
      if (statusResponse.getDestination() != null
          && !uriInfo.getAbsolutePath().toString().equals(statusResponse.getDestination())) {
        event.detail(Details.REASON, "invalid_destination");
        event.error(Errors.INVALID_SAML_LOGOUT_RESPONSE);
        return ErrorPage.error(session, Messages.INVALID_REQUEST);
      }

      AuthenticationManager.AuthResult authResult =
          authManager.authenticateIdentityCookie(session, realm, false);
      if (authResult == null) {
        logger.warn("Unknown saml response.");
        event.event(EventType.LOGOUT);
        event.error(Errors.INVALID_TOKEN);
        return ErrorPage.error(session, Messages.INVALID_REQUEST);
      }
      // assume this is a logout response
      UserSessionModel userSession = authResult.getSession();
      if (userSession.getState() != UserSessionModel.State.LOGGING_OUT) {
        logger.warn("Unknown saml response.");
        logger.warn("UserSession is not tagged as logging out.");
        event.event(EventType.LOGOUT);
        event.error(Errors.INVALID_SAML_LOGOUT_RESPONSE);
        return ErrorPage.error(session, Messages.INVALID_REQUEST);
      }
      logger.debug("logout response");
      Response response =
          authManager.browserLogout(
              session, realm, userSession, uriInfo, clientConnection, headers);
      event.success();
      return response;
    }
Esempio n. 4
0
 @Override
 protected void verifySignature(SAMLDocumentHolder documentHolder, ClientModel client)
     throws VerificationException {
   SamlProtocolUtils.verifyDocumentSignature(client, documentHolder.getSamlDocument());
 }
Esempio n. 5
0
    protected Response handleSamlRequest(String samlRequest, String relayState) {
      SAMLDocumentHolder documentHolder = extractRequestDocument(samlRequest);
      if (documentHolder == null) {
        event.event(EventType.LOGIN);
        event.error(Errors.INVALID_TOKEN);
        return ErrorPage.error(session, Messages.INVALID_REQUEST);
      }

      SAML2Object samlObject = documentHolder.getSamlObject();

      RequestAbstractType requestAbstractType = (RequestAbstractType) samlObject;
      String issuer = requestAbstractType.getIssuer().getValue();
      ClientModel client = realm.getClientByClientId(issuer);

      if (client == null) {
        event.event(EventType.LOGIN);
        event.client(issuer);
        event.error(Errors.CLIENT_NOT_FOUND);
        return ErrorPage.error(session, Messages.UNKNOWN_LOGIN_REQUESTER);
      }

      if (!client.isEnabled()) {
        event.event(EventType.LOGIN);
        event.error(Errors.CLIENT_DISABLED);
        return ErrorPage.error(session, Messages.LOGIN_REQUESTER_NOT_ENABLED);
      }
      if (client.isBearerOnly()) {
        event.event(EventType.LOGIN);
        event.error(Errors.NOT_ALLOWED);
        return ErrorPage.error(session, Messages.BEARER_ONLY);
      }
      if (!client.isStandardFlowEnabled()) {
        event.event(EventType.LOGIN);
        event.error(Errors.NOT_ALLOWED);
        return ErrorPage.error(session, Messages.STANDARD_FLOW_DISABLED);
      }

      session.getContext().setClient(client);

      try {
        verifySignature(documentHolder, client);
      } catch (VerificationException e) {
        SamlService.logger.error("request validation failed", e);
        event.event(EventType.LOGIN);
        event.error(Errors.INVALID_SIGNATURE);
        return ErrorPage.error(session, Messages.INVALID_REQUESTER);
      }
      logger.debug("verified request");
      if (samlObject instanceof AuthnRequestType) {
        logger.debug("** login request");
        event.event(EventType.LOGIN);
        // Get the SAML Request Message
        AuthnRequestType authn = (AuthnRequestType) samlObject;
        return loginRequest(relayState, authn, client);
      } else if (samlObject instanceof LogoutRequestType) {
        logger.debug("** logout request");
        event.event(EventType.LOGOUT);
        LogoutRequestType logout = (LogoutRequestType) samlObject;
        return logoutRequest(logout, client, relayState);

      } else {
        event.event(EventType.LOGIN);
        event.error(Errors.INVALID_TOKEN);
        return ErrorPage.error(session, Messages.INVALID_REQUEST);
      }
    }
  protected AuthOutcome handleSamlResponse(
      String samlResponse, String relayState, OnSessionCreated onCreateSession) {
    SAMLDocumentHolder holder = null;
    boolean postBinding = false;
    String requestUri = facade.getRequest().getURI();
    if (facade.getRequest().getMethod().equalsIgnoreCase("GET")) {
      int index = requestUri.indexOf('?');
      if (index > -1) {
        requestUri = requestUri.substring(0, index);
      }
      holder = extractRedirectBindingResponse(samlResponse);
    } else {
      postBinding = true;
      holder = extractPostBindingResponse(samlResponse);
    }
    final StatusResponseType statusResponse = (StatusResponseType) holder.getSamlObject();
    // validate destination
    if (!requestUri.equals(statusResponse.getDestination())) {
      log.error("Request URI does not match SAML request destination");
      return AuthOutcome.FAILED;
    }

    if (statusResponse instanceof ResponseType) {
      try {
        if (deployment.getIDP().getSingleSignOnService().validateResponseSignature()) {
          try {
            validateSamlSignature(holder, postBinding, GeneralConstants.SAML_RESPONSE_KEY);
          } catch (VerificationException e) {
            log.error("Failed to verify saml response signature", e);

            challenge =
                new AuthChallenge() {
                  @Override
                  public boolean challenge(HttpFacade exchange) {
                    SamlAuthenticationError error =
                        new SamlAuthenticationError(
                            SamlAuthenticationError.Reason.INVALID_SIGNATURE);
                    exchange.getRequest().setError(error);
                    exchange.getResponse().sendError(403);
                    return true;
                  }

                  @Override
                  public int getResponseCode() {
                    return 403;
                  }
                };
            return AuthOutcome.FAILED;
          }
        }
        return handleLoginResponse((ResponseType) statusResponse, onCreateSession);
      } finally {
        sessionStore.setCurrentAction(SamlSessionStore.CurrentAction.NONE);
      }

    } else {
      if (sessionStore.isLoggingOut()) {
        try {
          if (deployment.getIDP().getSingleLogoutService().validateResponseSignature()) {
            try {
              validateSamlSignature(holder, postBinding, GeneralConstants.SAML_RESPONSE_KEY);
            } catch (VerificationException e) {
              log.error("Failed to verify saml response signature", e);
              return AuthOutcome.FAILED;
            }
          }
          return handleLogoutResponse(holder, statusResponse, relayState);
        } finally {
          sessionStore.setCurrentAction(SamlSessionStore.CurrentAction.NONE);
        }

      } else if (sessionStore.isLoggingIn()) {

        try {
          // KEYCLOAK-2107 - handle user not authenticated due passive mode. Return special outcome
          // so different authentication mechanisms can behave accordingly.
          StatusType status = statusResponse.getStatus();
          if (checkStatusCodeValue(
                  status.getStatusCode(), JBossSAMLURIConstants.STATUS_RESPONDER.get())
              && checkStatusCodeValue(
                  status.getStatusCode().getStatusCode(),
                  JBossSAMLURIConstants.STATUS_NO_PASSIVE.get())) {
            log.debug(
                "Not authenticated due passive mode Status found in SAML response: "
                    + status.toString());
            return AuthOutcome.NOT_AUTHENTICATED;
          }

          challenge =
              new AuthChallenge() {
                @Override
                public boolean challenge(HttpFacade exchange) {
                  SamlAuthenticationError error =
                      new SamlAuthenticationError(
                          SamlAuthenticationError.Reason.ERROR_STATUS, statusResponse);
                  exchange.getRequest().setError(error);
                  exchange.getResponse().sendError(403);
                  return true;
                }

                @Override
                public int getResponseCode() {
                  return 403;
                }
              };
          return AuthOutcome.FAILED;
        } finally {
          sessionStore.setCurrentAction(SamlSessionStore.CurrentAction.NONE);
        }
      }
      return AuthOutcome.NOT_ATTEMPTED;
    }
  }