예제 #1
0
  private boolean handleSAML2Response(HttpServletRequest request, HttpServletResponse response)
      throws IOException {
    HttpSession session = request.getSession(true);
    String samlResponse = request.getParameter(GeneralConstants.SAML_RESPONSE_KEY);
    HTTPContext httpContext = new HTTPContext(request, response, this.servletContext);
    Set<SAML2Handler> handlers = chain.handlers();

    Principal principal = request.getUserPrincipal();

    boolean willSendRequest; // deal with SAML response from IDP

    try {
      ServiceProviderSAMLResponseProcessor responseProcessor =
          new ServiceProviderSAMLResponseProcessor(
              request.getMethod().equals("POST"),
              serviceURL,
              this.picketLinkConfiguration,
              this.idpMetadata);
      if (auditHelper != null) {
        responseProcessor.setAuditHelper(auditHelper);
      }

      responseProcessor.setTrustKeyManager(keyManager);

      SAML2HandlerResponse saml2HandlerResponse =
          responseProcessor.process(samlResponse, httpContext, handlers, chainLock);

      Document samlResponseDocument = saml2HandlerResponse.getResultingDocument();
      String relayState = saml2HandlerResponse.getRelayState();

      String destination = saml2HandlerResponse.getDestination();

      willSendRequest = saml2HandlerResponse.getSendRequest();

      String destinationQueryStringWithSignature =
          saml2HandlerResponse.getDestinationQueryStringWithSignature();

      if (destination != null && samlResponseDocument != null) {
        sendRequestToIDP(
            destination,
            samlResponseDocument,
            relayState,
            request,
            response,
            willSendRequest,
            destinationQueryStringWithSignature);
      } else {
        // See if the session has been invalidated
        boolean sessionValidity = request.getUserPrincipal() != null;

        if (!sessionValidity) {
          sendToLogoutPage(request, response, session);
          return false;
        }

        // We got a response with the principal
        List<String> roles = saml2HandlerResponse.getRoles();
        if (principal == null) {
          principal = (Principal) session.getAttribute(GeneralConstants.PRINCIPAL_ID);
        }

        if (principal == null) {
          throw new RuntimeException(ErrorCodes.NULL_VALUE + " principal");
        }

        if (isEnableAudit()) {
          PicketLinkAuditEvent auditEvent = new PicketLinkAuditEvent(AuditLevel.INFO);
          auditEvent.setType(PicketLinkAuditEventType.RESPONSE_FROM_IDP);
          auditEvent.setSubjectName(principal.getName());
          auditEvent.setWhoIsAuditing(getContextPath());
          auditHelper.audit(auditEvent);
        }

        return true;
      }
    } catch (ProcessingException pe) {
      Throwable t = pe.getCause();
      if (t != null && t instanceof AssertionExpiredException) {
        logger.error("Assertion has expired. Asking IDP for reissue");
        if (isEnableAudit()) {
          PicketLinkAuditEvent auditEvent = new PicketLinkAuditEvent(AuditLevel.INFO);
          auditEvent.setType(PicketLinkAuditEventType.EXPIRED_ASSERTION);
          auditEvent.setAssertionID(((AssertionExpiredException) t).getId());
          auditHelper.audit(auditEvent);
        }
        // Just issue a fresh request back to IDP
        return generalUserRequest(request, response);
      }
      logger.samlSPHandleRequestError(pe);
      throw logger.samlSPProcessingExceptionError(pe);
    } catch (Exception e) {
      logger.samlSPHandleRequestError(e);
      throw logger.samlSPProcessingExceptionError(e);
    }

    return localAuthentication(request, response);
  }