/** * Determines the return location and redirects based on federation termination Return URL of the * provider that sent the termination request. */ private void returnToSource() { FSUtils.debug.message("Entered FSFedTerminationHandler::returnToSource"); try { StringBuffer finalReturnURL = new StringBuffer(); String retURL = remoteDescriptor.getFederationTerminationServiceReturnURL(); if (FSUtils.debug.messageEnabled()) { FSUtils.debug.message("Redirecting to : " + retURL); } resetFederateCookie(); FSUtils.debug.message("Checking retURL for null value"); if (retURL == null || retURL.length() < 1) { FSUtils.debug.error("Return URL is null"); FSServiceUtils.showErrorPage( response, error_page_url, IFSConstants.TERMINATION_INVALID_REDIRECT_URL, IFSConstants.METADATA_ERROR); return; } else { finalReturnURL.append(retURL); if (!(relayState == null || relayState.length() < 1)) { char delimiter; if (retURL.indexOf(IFSConstants.QUESTION_MARK) < 0) { delimiter = IFSConstants.QUESTION_MARK; } else { delimiter = IFSConstants.AMPERSAND; } finalReturnURL .append(delimiter) .append(RELAY_STATE) .append(IFSConstants.EQUAL_TO) .append(URLEncDec.encode(relayState)); } if (FSUtils.debug.messageEnabled()) { FSUtils.debug.message("Now sendRedirecting to : " + finalReturnURL.toString()); } response.sendRedirect(finalReturnURL.toString()); return; } } catch (IOException e) { FSUtils.debug.error( "Unable to get LRURL. No location to redirect." + " processing completed", e); } // create new bundle entry for redirect failure FSUtils.debug.message("After exception calling response.sendError"); FSServiceUtils.showErrorPage( response, error_page_url, IFSConstants.TERMINATION_INVALID_REDIRECT_URL, IFSConstants.METADATA_ERROR); return; }
/* * Method to construct the URLEndpoint depending on whether basic * authentication of one provider to another is to be done. Otherwise the * SOAPEndpoint of the remote provider is returned * @param response the response object * @param partnerDecriptor the remote provider descriptor * @param needAuthn determines forced authn * @return Element corresponding to liberty request/response */ public String createSOAPReceiverUrl( HttpServletResponse response, ProviderDescriptorType partnerDecriptor, boolean needAuthn) throws IOException { // TODO: need to handle needAuthn correctly // TODO: need to retrieve auth type, user name and password from meta // basic authentication String username = null; String password = null; String to = partnerDecriptor.getSoapEndpoint(); String authtype = null; String soapURL = null; if (needAuthn) { int idnx = -1; if ((idnx = to.indexOf("//")) == -1) { FSUtils.debug.error( "FSSOAPService.createSOAPReceiverUrl: " + "createSOAPReceiverUrl: SOAP-Receiver-URL illegal format."); response.sendError( response.SC_INTERNAL_SERVER_ERROR, FSUtils.bundle.getString("illegalFormatSOAPUrl")); return null; } String protocol = to.substring(0, idnx - 1); if (authtype.equalsIgnoreCase(IFSConstants.BASICAUTH) || authtype.equalsIgnoreCase(IFSConstants.NOAUTH)) { if (!protocol.equals(IFSConstants.HTTP)) { String[] data = {protocol, authtype}; LogUtil.error(Level.INFO, LogUtil.MISMATCH_AUTH_TYPE_AND_PROTOCOL, data); response.sendError( response.SC_INTERNAL_SERVER_ERROR, FSUtils.bundle.getString("mismatchAuthTypeandProtocol")); return null; } } else if (authtype.equalsIgnoreCase(IFSConstants.SSLWITHBASICAUTH) || authtype.equalsIgnoreCase(IFSConstants.SSL)) { if (!protocol.equals(IFSConstants.HTTPS)) { String[] data = {protocol, authtype}; LogUtil.error(Level.INFO, LogUtil.MISMATCH_AUTH_TYPE_AND_PROTOCOL, data); response.sendError( response.SC_INTERNAL_SERVER_ERROR, FSUtils.bundle.getString("mismatchAuthTypeandProtocol")); return null; } } else { String[] data = {authtype}; LogUtil.error(Level.INFO, LogUtil.WRONG_AUTH_TYPE, data); response.sendError( response.SC_INTERNAL_SERVER_ERROR, FSUtils.bundle.getString("wrongAuthType")); return null; } if (authtype.equalsIgnoreCase(IFSConstants.BASICAUTH) || authtype.equalsIgnoreCase(IFSConstants.SSLWITHBASICAUTH)) { Map userMap = null; // partnerDecriptor.getAuthType(); username = (String) userMap.get(IFSConstants.USER); password = (String) userMap.get(IFSConstants.PASSWORD); if (username == null || password == null) { FSUtils.debug.error( "FSSOAPService.createSOAPReceiverUrl: " + "PartnerSite required basic authentication. But " + "the user name used for authentication is null."); response.sendError( response.SC_INTERNAL_SERVER_ERROR, FSUtils.bundle.getString("wrongConfigBasicAuth")); return null; } StringBuffer toSOAP = new StringBuffer(100); toSOAP .append(to.substring(0, idnx + 2)) .append(username) .append(":") .append(password) .append("@") .append(to.substring(idnx + 2)); soapURL = toSOAP.toString(); } return null; } else { soapURL = to; } if (FSUtils.debug.messageEnabled()) { FSUtils.debug.message( "FSSOAPService.createSOAPReceiverUrl: Sending message to URL: " + soapURL); } String[] data = {soapURL}; LogUtil.access(Level.FINER, "SOAP_RECEIVER_URL", data); return soapURL; }
/** * Initiates federation termination at remote end. The termination requested is constructed and * based on the profile the request is sent over SOAP or as HTTP redirect. Profile is always based * on the SPs profile * * @param acctInfo represents the user account federation information * @return <code>true</code> if termination request is sent to remote provider successfully; * <code>false</code> otherwise. */ private boolean doFederationTermination( HttpServletRequest request, HttpServletResponse response, FSAccountFedInfo acctInfo) { FSUtils.debug.message("Entered FSFedTerminationHandler::doFederationTermination"); try { if (FSUtils.debug.messageEnabled()) { FSUtils.debug.message( "FSFedTerminationHandler::doFederationTermination create" + " request start"); } FSFederationTerminationNotification reqFedTermination = createFederationTerminationRequest(acctInfo); reqFedTermination.setMinorVersion( FSServiceUtils.getMinorVersion(remoteDescriptor.getProtocolSupportEnumeration())); if (reqFedTermination == null) { if (FSUtils.debug.messageEnabled()) { FSUtils.debug.message( "FSIDPFedTerminationHandler::Termination request could " + "not be formed"); } // Always show success page since local termination succeeded FSServiceUtils.returnLocallyAfterOperation( response, termination_done_url, true, IFSConstants.TERMINATION_SUCCESS, IFSConstants.TERMINATION_FAILURE); return false; } if (FSUtils.debug.messageEnabled()) { FSUtils.debug.message( "FSIDPFedTerminationHandler::Termination request formed" + "successfully"); } // Find out which profile to use boolean isSOAPProfile = true; if (acctInfo.isRoleIDP()) { List hostProfiles = hostedDescriptor.getFederationTerminationNotificationProtocolProfile(); if (hostProfiles == null || hostProfiles.isEmpty()) { FSUtils.debug.error( "FSFedTerminationHandler::" + "doFederationTermination no termination profile" + " cannot process request"); FSServiceUtils.returnLocallyAfterOperation( response, termination_done_url, true, IFSConstants.TERMINATION_SUCCESS, IFSConstants.TERMINATION_FAILURE); return false; } String profile = (String) hostProfiles.iterator().next(); if (profile.equalsIgnoreCase(IFSConstants.TERMINATION_SP_SOAP_PROFILE) || profile.equalsIgnoreCase(IFSConstants.TERMINATION_IDP_SOAP_PROFILE)) { isSOAPProfile = true; } else if (profile.equalsIgnoreCase(IFSConstants.TERMINATION_SP_HTTP_PROFILE) || profile.equalsIgnoreCase(IFSConstants.TERMINATION_IDP_HTTP_PROFILE)) { isSOAPProfile = false; } else { FSUtils.debug.error( "FSFedTerminationHandler::" + "doFederationTermination Invalid termination profile" + " cannot process request"); FSServiceUtils.returnLocallyAfterOperation( response, termination_done_url, true, IFSConstants.TERMINATION_SUCCESS, IFSConstants.TERMINATION_FAILURE); return false; } } else { List remoteProfiles = remoteDescriptor.getFederationTerminationNotificationProtocolProfile(); if (remoteProfiles == null || remoteProfiles.isEmpty()) { FSUtils.debug.error( "FSFedTerminationHandler::" + "doFederationTermination no termination profile" + " cannot process request"); FSServiceUtils.returnLocallyAfterOperation( response, termination_done_url, true, IFSConstants.TERMINATION_SUCCESS, IFSConstants.TERMINATION_FAILURE); return false; } String profile = (String) remoteProfiles.iterator().next(); if (profile.equalsIgnoreCase(IFSConstants.TERMINATION_SP_SOAP_PROFILE) || profile.equalsIgnoreCase(IFSConstants.TERMINATION_IDP_SOAP_PROFILE)) { isSOAPProfile = true; } else if (profile.equalsIgnoreCase(IFSConstants.TERMINATION_SP_HTTP_PROFILE) || profile.equalsIgnoreCase(IFSConstants.TERMINATION_IDP_HTTP_PROFILE)) { isSOAPProfile = false; } else { FSUtils.debug.error( "FSFedTerminationHandler::" + "doFederationTermination Invalid termination profile" + " cannot process request"); FSServiceUtils.returnLocallyAfterOperation( response, termination_done_url, true, IFSConstants.TERMINATION_SUCCESS, IFSConstants.TERMINATION_FAILURE); return false; } } if (isSOAPProfile) { FSSOAPService instSOAP = FSSOAPService.getInstance(); if (instSOAP != null) { FSUtils.debug.message("Signing suceeded. To call bindTerminationRequest"); // String id = reqFedTermination.getRequestID(); reqFedTermination.setID(IFSConstants.TERMINATIONID); SOAPMessage msgTermination = instSOAP.bind(reqFedTermination.toXMLString(true, true)); if (msgTermination != null) { try { if (FSServiceUtils.isSigningOn()) { int minorVersion = reqFedTermination.getMinorVersion(); if (minorVersion == IFSConstants.FF_11_PROTOCOL_MINOR_VERSION) { msgTermination = signTerminationRequest( msgTermination, IFSConstants.ID, reqFedTermination.getID()); } else if (minorVersion == IFSConstants.FF_12_PROTOCOL_MINOR_VERSION) { msgTermination = signTerminationRequest( msgTermination, IFSConstants.REQUEST_ID, reqFedTermination.getRequestID()); } else { FSUtils.debug.message("invalid minor version."); } } boolean sendStatus = instSOAP.sendTerminationMessage( msgTermination, remoteDescriptor.getSoapEndpoint()); // Call SP Adapter for SP initiated SOAP profile if (hostedProviderRole != null && hostedProviderRole.equalsIgnoreCase(IFSConstants.SP)) { FederationSPAdapter spAdapter = FSServiceUtils.getSPAdapter(hostedEntityId, hostedConfig); if (spAdapter != null) { try { spAdapter.postTerminationNotificationSuccess( hostedEntityId, request, response, userID, reqFedTermination, IFSConstants.TERMINATION_SP_SOAP_PROFILE); } catch (Exception e) { // ignore adapter exception FSUtils.debug.error("postTerm.SP/SOAP", e); } } } // Always show success page since local termination // succeeded and that is what is important FSServiceUtils.returnLocallyAfterOperation( response, termination_done_url, true, IFSConstants.TERMINATION_SUCCESS, IFSConstants.TERMINATION_FAILURE); return sendStatus; } catch (Exception e) { FSUtils.debug.error( "FSFedTerminationHandler::" + "doFederationTermination " + FSUtils.bundle.getString(IFSConstants.TERMINATION_FAILED_SEND_REMOTE)); // Always show success page since local // termination succeeded FSServiceUtils.returnLocallyAfterOperation( response, termination_done_url, true, IFSConstants.TERMINATION_SUCCESS, IFSConstants.TERMINATION_FAILURE); return false; } } else { if (FSUtils.debug.messageEnabled()) { FSUtils.debug.message( "FSSPFedTerminationHandler::doFederation" + "Termination failed. Error in forming Message"); } FSUtils.debug.error( "FSSPFedTerminationHandler.doFederationTermination " + FSUtils.bundle.getString(IFSConstants.TERMINATION_FAILED_SEND_REMOTE)); // Always show success page since local termination // succeeded FSServiceUtils.returnLocallyAfterOperation( response, termination_done_url, true, IFSConstants.TERMINATION_SUCCESS, IFSConstants.TERMINATION_FAILURE); return false; } } if (FSUtils.debug.messageEnabled()) { FSUtils.debug.message( "FSFedTerminationHandler::doFederationTermination " + "failed. Cannot get Service Manager instance"); } FSUtils.debug.error( "FSSPFedTerminationHandler::doFederationTermination " + FSUtils.bundle.getString(IFSConstants.TERMINATION_FAILED_SEND_REMOTE)); // Always show success page since local termination succeeded FSServiceUtils.returnLocallyAfterOperation( response, termination_done_url, true, IFSConstants.TERMINATION_SUCCESS, IFSConstants.TERMINATION_FAILURE); return false; } else { if (FSUtils.debug.messageEnabled()) { FSUtils.debug.message( "FSFedTerminationHandler::doFederationTermination " + "In Redirect profile"); } String urlEncodedRequest = reqFedTermination.toURLEncodedQueryString(); // Sign the request querystring if (FSServiceUtils.isSigningOn()) { String certAlias = IDFFMetaUtils.getFirstAttributeValueFromConfig( hostedConfig, IFSConstants.SIGNING_CERT_ALIAS); if (certAlias == null || certAlias.length() == 0) { if (FSUtils.debug.messageEnabled()) { FSUtils.debug.message( "FSBrowserArtifactConsumerHandler:: " + "signSAMLRequest:" + "couldn't obtain this site's cert alias."); } throw new SAMLResponderException(FSUtils.bundle.getString(IFSConstants.NO_CERT_ALIAS)); } urlEncodedRequest = FSSignatureUtil.signAndReturnQueryString(urlEncodedRequest, certAlias); } StringBuffer redirectURL = new StringBuffer(); if (FSUtils.debug.messageEnabled()) { FSUtils.debug.message("Request to be sent : " + urlEncodedRequest); } String retURL = remoteDescriptor.getFederationTerminationServiceURL(); redirectURL.append(retURL); if (retURL.indexOf(IFSConstants.QUESTION_MARK) == -1) { redirectURL.append(IFSConstants.QUESTION_MARK); } else { redirectURL.append(IFSConstants.AMPERSAND); } redirectURL.append(urlEncodedRequest); if (FSUtils.debug.messageEnabled()) { FSUtils.debug.message( "FSFedTerminationHandler::Redirect URL is " + redirectURL.toString()); } // Call SP Adaper for SP initiated HTTP profile // ideally this should be called from the // FSTerminationReturnServlet, but info not available there if (hostedProviderRole != null && hostedProviderRole.equalsIgnoreCase(IFSConstants.SP)) { FederationSPAdapter spAdapter = FSServiceUtils.getSPAdapter(hostedEntityId, hostedConfig); if (spAdapter != null) { try { spAdapter.postTerminationNotificationSuccess( hostedEntityId, request, response, userID, reqFedTermination, IFSConstants.TERMINATION_SP_HTTP_PROFILE); } catch (Exception e) { // ignore adapter exception FSUtils.debug.error("postTerm.SP/HTTP", e); } } } response.sendRedirect(redirectURL.toString()); return true; } } catch (IOException e) { FSUtils.debug.error( "FSFedTerminationHandler" + FSUtils.bundle.getString(IFSConstants.FEDERATION_REDIRECT_FAILED)); } catch (FSMsgException e) { FSUtils.debug.error( "FSFedTerminationHandler::doFederationTermination " + FSUtils.bundle.getString(IFSConstants.TERMINATION_FAILED_SEND_REMOTE)); } catch (SAMLResponderException e) { FSUtils.debug.error( "FSFedTerminationHandler::doFederationTermination " + FSUtils.bundle.getString(IFSConstants.TERMINATION_FAILED_SEND_REMOTE)); } // Always show success page since local termination succeeded FSServiceUtils.returnLocallyAfterOperation( response, termination_done_url, true, IFSConstants.TERMINATION_SUCCESS, IFSConstants.TERMINATION_FAILURE); return false; }