package at.gv.egovernment.moa.id.auth.servlet; import java.io.IOException; import java.util.List; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import org.opensaml.saml2.core.Assertion; import org.opensaml.saml2.core.StatusCode; import org.opensaml.xml.util.XMLHelper; import org.w3c.dom.Element; import at.gv.egovernment.moa.id.AuthenticationException; import at.gv.egovernment.moa.id.MOAIDException; import at.gv.egovernment.moa.id.auth.AuthenticationServer; import at.gv.egovernment.moa.id.auth.builder.DataURLBuilder; import at.gv.egovernment.moa.id.auth.data.AuthenticationSession; import at.gv.egovernment.moa.id.auth.data.ExtendedSAMLAttribute; import at.gv.egovernment.moa.id.auth.data.IdentityLink; import at.gv.egovernment.moa.id.auth.stork.STORKException; import at.gv.egovernment.moa.id.auth.stork.STORKResponseProcessor; import at.gv.egovernment.moa.id.commons.db.ex.MOADatabaseException; import at.gv.egovernment.moa.id.moduls.ModulUtils; import at.gv.egovernment.moa.id.storage.AuthenticationSessionStoreage; import at.gv.egovernment.moa.id.util.HTTPUtils; import at.gv.egovernment.moa.logging.Logger; import at.gv.egovernment.moa.util.DOMUtils; import at.gv.egovernment.moa.util.StringUtils; import eu.stork.mw.messages.saml.STORKAuthnRequest; import eu.stork.mw.messages.saml.STORKResponse; import eu.stork.vidp.messages.util.XMLUtil; /** * Endpoint for receiving STORK response messages */ public class PEPSConnectorServlet extends AuthServlet { private static final long serialVersionUID = 1L; public static final String PEPSCONNECTOR_SERVLET_URL_PATTERN = "/PEPSConnector"; /** * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response) */ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { super.doGet(request, response); } /** * Handles the reception of a STORK response message * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) */ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { try { Logger.info("PEPSConnector Servlet invoked, expecting C-PEPS message."); Logger.debug("This ACS endpoint is: " + HTTPUtils.getBaseURL(request)); super.setNoCachingHeadersInHttpRespone(request, response); Logger.trace("No Caching headers set for HTTP response"); //check if https or only http super.checkIfHTTPisAllowed(request.getRequestURL().toString()); Logger.debug("Trying to find MOA Session-ID"); HttpSession httpSession = request.getSession(); String moaSessionID = (String) httpSession.getAttribute("MOA-Session-ID"); if (StringUtils.isEmpty(moaSessionID)) { //No authentication session has been started before Logger.error("MOA-SessionID was not found, no previous AuthnRequest had been started"); throw new AuthenticationException("auth.02", new Object[] { moaSessionID }); } else { //We know user and MOA takes over session handling, invalidate HttpSession httpSession.invalidate(); } Logger.info("Found MOA sessionID: " + moaSessionID); Logger.debug("Beginning to extract SAMLResponse out of HTTP Request"); //extract STORK Response from HTTP Request STORKResponse storkResponse = null; try { storkResponse = STORKResponseProcessor.receiveSTORKRepsonse(request, response); } catch (STORKException e) { Logger.error("Unable to retrieve STORK Response", e); throw new MOAIDException("stork.04", null); } Logger.info("STORK SAML Response message succesfully extracted"); Logger.debug("STORK response (pretty print): "); Logger.debug(XMLHelper.prettyPrintXML(storkResponse.getDOM())); Logger.trace("STORK response (original): "); Logger.trace(XMLUtil.printXML(storkResponse.getDOM())); Logger.debug("Starting validation of SAML response"); //verify SAML response try { STORKResponseProcessor.verifySTORKResponse(storkResponse); } catch (STORKException e) { Logger.error("Failed to verify STORK SAML Response", e); throw new MOAIDException("stork.05", null); } Logger.info("SAML response succesfully verified!"); String statusCodeValue = storkResponse.getStatus().getStatusCode().getValue(); if (!statusCodeValue.equals(StatusCode.SUCCESS_URI)) { Logger.error("Received ErrorResponse from PEPS: " + statusCodeValue); throw new MOAIDException("stork.06", new Object[] { statusCodeValue }); } Logger.info("Got SAML response with authentication success message."); //check if authentication request was created before AuthenticationSession moaSession = AuthenticationServer.getSession(moaSessionID); Logger.debug("MOA session is still valid"); STORKAuthnRequest storkAuthnRequest = moaSession.getStorkAuthnRequest(); if (storkAuthnRequest == null) { Logger.error("Could not find any preceeding STORK AuthnRequest to this MOA session: " + moaSessionID); throw new MOAIDException("stork.07", null); } Logger.debug("Found a preceeding STORK AuthnRequest to this MOA session: " + moaSessionID); Logger.debug("Starting validation of SAML assertion"); //verify SAML assertion Assertion storkAssertion = storkResponse.getAssertions().get(0); try { STORKResponseProcessor.verifySTORKAssertion( storkAssertion, //assertion request.getRemoteAddr(), //IP address of user storkAuthnRequest.getID(), //ID of STORK AuthnRequest request.getRequestURL().toString(), //destination HTTPUtils.getBaseURL(request), //audience storkAuthnRequest.getRequestedAttributes()); //Requested Attributes } catch (STORKException e) { Logger.error("Failed to verify STORK SAML Assertion", e); throw new MOAIDException("stork.08", null); } Logger.info("SAML assertion succesfully verified!"); Logger.debug("Starting extraction of signedDoc attribute"); //extract signed doc element and citizen signature Element citizenSignature = null; try { citizenSignature = STORKResponseProcessor.extractCitizenSignature(storkAssertion); moaSession.setAuthBlock(DOMUtils.serializeNode(citizenSignature)); moaSession.setSignerCertificate(AuthenticationServer.getCertificateFromXML(citizenSignature)); } catch (Exception e) { Logger.error("Could not extract citizen signature from C-PEPS", e); throw new MOAIDException("stork.09", null); } Logger.debug("Foregin Citizen signature successfully extracted from STORK Assertion (signedDoc)"); Logger.debug("Citizen signature will be verified by SZR Gateway!"); Logger.debug("Starting connecting SZR Gateway"); //contact SZR Gateway IdentityLink identityLink = null; try { identityLink = STORKResponseProcessor.connectToSZRGateway(citizenSignature, storkAssertion.getAttributeStatements().get(0).getAttributes()); } catch (STORKException e) { Logger.error("Error connecting SZR Gateway", e); throw new MOAIDException("stork.10", null); } Logger.debug("SZR communication was successfull"); if (identityLink == null) { Logger.error("SZR Gateway did not return an identity link."); throw new MOAIDException("stork.10", null); } Logger.info("Received Identity Link from SZR Gateway"); moaSession.setIdentityLink(identityLink); Logger.debug("Adding addtional STORK attributes to MOA assertion"); //add other stork attributes to MOA assertion List moaExtendedSAMLAttibutes = STORKResponseProcessor.addAdditionalSTORKAttributes(storkAssertion.getAttributeStatements().get(0).getAttributes()); moaSession.setExtendedSAMLAttributesOA(moaExtendedSAMLAttibutes); //We don't have BKUURL, setting from null to "Not applicable" moaSession.setBkuURL("Not applicable (STORK Authentication)"); Logger.debug("Starting to assemble MOA assertion"); //produce MOA-Assertion and artifact String samlArtifactBase64 = AuthenticationServer.getInstance().getForeignAuthenticationData(moaSessionID); Logger.info("MOA assertion assembled and SAML Artifact generated."); //redirect String redirectURL = null; if (!samlArtifactBase64.equals("Redirect to Input Processor")) { /*redirectURL = moaSession.getOAURLRequested(); if (!moaSession.getBusinessService()) { redirectURL = addURLParameter(redirectURL, PARAM_TARGET, URLEncoder.encode(moaSession.getTarget(), "UTF-8")); } redirectURL = addURLParameter(redirectURL, PARAM_SAMLARTIFACT, URLEncoder.encode(samlArtifactBase64, "UTF-8")); redirectURL = response.encodeRedirectURL(redirectURL);*/ redirectURL = new DataURLBuilder().buildDataURL(moaSession.getAuthURL(), ModulUtils.buildAuthURL(moaSession.getModul(), moaSession.getAction()), samlArtifactBase64); redirectURL = response.encodeRedirectURL(redirectURL); } else { redirectURL = new DataURLBuilder().buildDataURL(moaSession.getAuthURL(), AuthenticationServer.REQ_PROCESS_VALIDATOR_INPUT, moaSession.getSessionID()); } try { AuthenticationSessionStoreage.storeSession(moaSession); } catch (MOADatabaseException e) { throw new MOAIDException("Session store error", null); } response.setContentType("text/html"); response.setStatus(302); response.addHeader("Location", redirectURL); Logger.info("REDIRECT TO: " + redirectURL); } catch (AuthenticationException e) { handleError(null, e, request, response); } catch (MOAIDException e) { handleError(null, e, request, response); } } }