aboutsummaryrefslogtreecommitdiff
path: root/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/PEPSConnectorServlet.java
diff options
context:
space:
mode:
Diffstat (limited to 'id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/PEPSConnectorServlet.java')
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/PEPSConnectorServlet.java248
1 files changed, 164 insertions, 84 deletions
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/PEPSConnectorServlet.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/PEPSConnectorServlet.java
index 9a13129d8..1e6821912 100644
--- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/PEPSConnectorServlet.java
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/PEPSConnectorServlet.java
@@ -22,7 +22,12 @@
******************************************************************************/
package at.gv.egovernment.moa.id.auth.servlet;
+import iaik.x509.X509Certificate;
import java.io.IOException;
+import java.io.InputStream;
+import java.io.StringWriter;
+import java.net.URL;
+import java.util.ArrayList;
import java.util.List;
import javax.servlet.ServletException;
@@ -31,42 +36,53 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBElement;
+import javax.xml.transform.stream.StreamSource;
-import org.opensaml.saml2.core.Assertion;
+import org.apache.commons.io.IOUtils;
+import org.apache.velocity.Template;
+import org.apache.velocity.VelocityContext;
+import org.apache.velocity.app.VelocityEngine;
import org.opensaml.saml2.core.StatusCode;
-import org.opensaml.xml.util.XMLHelper;
-import org.w3c.dom.Element;
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.exception.AuthenticationException;
import at.gv.egovernment.moa.id.auth.exception.MOAIDException;
import at.gv.egovernment.moa.id.auth.stork.STORKException;
import at.gv.egovernment.moa.id.auth.stork.STORKResponseProcessor;
+import at.gv.egovernment.moa.id.auth.stork.VelocityProvider;
import at.gv.egovernment.moa.id.commons.db.ex.MOADatabaseException;
+import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProvider;
+import at.gv.egovernment.moa.id.config.auth.OAAuthParameter;
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 at.gv.util.xsd.xmldsig.SignatureType;
-import eu.stork.mw.messages.saml.STORKAuthnRequest;
-import eu.stork.mw.messages.saml.STORKResponse;
-import eu.stork.vidp.messages.util.XMLUtil;
+import at.gv.util.xsd.xmldsig.X509DataType;
+import eu.stork.oasisdss.api.ApiUtils;
+import eu.stork.oasisdss.profile.DocumentWithSignature;
+import eu.stork.oasisdss.profile.SignResponse;
+import eu.stork.peps.auth.commons.PEPSUtil;
+import eu.stork.peps.auth.commons.PersonalAttribute;
+import eu.stork.peps.auth.commons.STORKAuthnRequest;
+import eu.stork.peps.auth.commons.STORKAuthnResponse;
+import eu.stork.peps.auth.engine.STORKSAMLEngine;
+import eu.stork.peps.exceptions.STORKSAMLEngineException;
/**
* 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)
*/
@@ -101,9 +117,6 @@ public class PEPSConnectorServlet extends AuthServlet {
//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();
}
pendingRequestID = AuthenticationSessionStoreage.getPendingRequestID(moaSessionID);
@@ -113,33 +126,35 @@ public class PEPSConnectorServlet extends AuthServlet {
Logger.debug("Beginning to extract SAMLResponse out of HTTP Request");
//extract STORK Response from HTTP Request
- STORKResponse storkResponse = null;
+ //Decodes SAML Response
+ byte[] decSamlToken;
try {
- storkResponse = STORKResponseProcessor.receiveSTORKRepsonse(request, response);
- } catch (STORKException e) {
+ decSamlToken = PEPSUtil.decodeSAMLToken(request.getParameter("SAMLResponse"));
+ } catch(NullPointerException 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
+
+ //Get SAMLEngine instance
+ STORKSAMLEngine engine = STORKSAMLEngine.getInstance("outgoing");
+
+ STORKAuthnResponse authnResponse = null;
try {
- STORKResponseProcessor.verifySTORKResponse(storkResponse);
- } catch (STORKException e) {
+ //validate SAML Token
+ Logger.debug("Starting validation of SAML response");
+ authnResponse = engine.validateSTORKAuthnResponse(decSamlToken, (String) request.getRemoteHost());
+ Logger.info("SAML response succesfully verified!");
+ }catch(STORKSAMLEngineException 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();
-
+
+ Logger.info("STORK SAML Response message succesfully extracted");
+ Logger.debug("STORK response: ");
+ Logger.debug(authnResponse.toString());
+
+ String statusCodeValue = authnResponse.getStatusCode();
+
if (!statusCodeValue.equals(StatusCode.SUCCESS_URI)) {
Logger.error("Received ErrorResponse from PEPS: " + statusCodeValue);
throw new MOAIDException("stork.06", new Object[] { statusCodeValue });
@@ -160,46 +175,132 @@ public class PEPSConnectorServlet extends AuthServlet {
}
Logger.debug("Found a preceeding STORK AuthnRequest to this MOA session: " + moaSessionID);
+
+ ////////////// incorporate gender from parameters if not in stork response
- 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);
+ PersonalAttribute gender = authnResponse.getPersonalAttributeList().get("gender");
+ if(null == gender) {
+ String gendervalue = (String) request.getParameter("gender");
+ if(null != gendervalue) {
+ gender = new PersonalAttribute();
+ gender.setName("gender");
+ ArrayList<String> tmp = new ArrayList<String>();
+ tmp.add(gendervalue);
+ gender.setValue(tmp);
+
+ authnResponse.getPersonalAttributeList().add(gender);
+ } else {
+ // this is really nasty but we work against the system here. We are supposed to get the gender attribute from
+ // stork. If we do not, we cannot register the person in the ERnP - we have to have the
+ // gender for the represented person. So here comes the dirty hack.
+ try {
+ Logger.trace("Initialize VelocityEngine...");
+
+ VelocityEngine velocityEngine = VelocityProvider.getClassPathVelocityEngine();
+ Template template = velocityEngine.getTemplate("/resources/templates/fetchGender.html");
+ VelocityContext context = new VelocityContext();
+ context.put("SAMLResponse", request.getParameter("SAMLResponse"));
+ context.put("action", request.getRequestURL());
+
+ StringWriter writer = new StringWriter();
+ template.merge(context, writer);
+
+ response.getOutputStream().write(writer.toString().getBytes());
+ } catch (Exception e1) {
+ Logger.error("Error sending gender retrival form.", e1);
+ httpSession.invalidate();
+ throw new MOAIDException("stork.10", null);
+ }
+
+ return;
+ }
}
- Logger.info("SAML assertion succesfully verified!");
+ //////////////////////////////////////////////////////////////////////////
- Logger.debug("Starting extraction of signedDoc attribute");
+ Logger.debug("Starting extraction of signedDoc attribute");
//extract signed doc element and citizen signature
- Element citizenSignature = null;
+ String citizenSignature = null;
try {
-
- citizenSignature = STORKResponseProcessor.extractCitizenSignature(storkAssertion);
- moaSession.setAuthBlock(DOMUtils.serializeNode(citizenSignature));
- moaSession.setSignerCertificate(AuthenticationServer.getCertificateFromXML(citizenSignature));
+ String signatureInfo = authnResponse.getPersonalAttributeList().get("signedDoc").getValue().get(0);
+ SignResponse dssSignResponse = (SignResponse) ApiUtils.unmarshal(new StreamSource(new java.io.StringReader(signatureInfo)));
+
+ List<DocumentWithSignature> doclocations = ApiUtils.findNamedElement(dssSignResponse.getOptionalOutputs(), DocumentWithSignature.class.getSimpleName(), DocumentWithSignature.class);
+ // TODO handle multiple docs?
+ Logger.debug("trying first doclocation");
+ String docUrl = doclocations.get(0).getDocument().getDocumentURL();
+ Logger.debug("trying first doclocation successful");
- } catch (Exception e) {
+ // fetch signed doc
+ URL url = new URL(docUrl);
+ InputStream incomming = url.openStream();
+ citizenSignature = IOUtils.toString(incomming);
+ incomming.close();
+
+ JAXBContext ctx = JAXBContext.newInstance(SignatureType.class.getPackage().getName());
+ SignatureType root = ((JAXBElement<SignatureType>) ctx.createUnmarshaller().unmarshal(IOUtils.toInputStream(citizenSignature))).getValue();
+
+ // memorize signature into authblock
+ moaSession.setAuthBlock(citizenSignature);
+
+ // extract certificate
+ for(Object current : root.getKeyInfo().getContent())
+ if(((JAXBElement<?>) current).getValue() instanceof X509DataType) {
+ for(Object currentX509Data : ((JAXBElement<X509DataType>) current).getValue().getX509IssuerSerialOrX509SKIOrX509SubjectName()) {
+ JAXBElement<?> casted = ((JAXBElement<?>) currentX509Data);
+ if(casted.getName().getLocalPart().equals("X509Certificate")) {
+ moaSession.setSignerCertificate(new X509Certificate(((String)casted.getValue()).getBytes()));
+ break;
+ }
+ }
+ }
+
+
+ } catch (Throwable 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("fetching OAParameters from database");
+
+ //read configuration paramters of OA
+ AuthenticationSession moasession;
+ try {
+ moasession = AuthenticationSessionStoreage.getSession(moaSessionID);
+ } catch (MOADatabaseException e2) {
+ Logger.error("could not retrieve moa session");
+ throw new AuthenticationException("auth.01", null);
+ }
+ OAAuthParameter oaParam = AuthConfigurationProvider.getInstance().getOnlineApplicationParameter(moasession.getPublicOAURLPrefix());
+ if (oaParam == null)
+ throw new AuthenticationException("auth.00", new Object[] { moasession.getPublicOAURLPrefix() });
+
+ // retrieve target
+ //TODO: check in case of SSO!!!
+ String targetType = null;
+ String targetValue = null;
+ if(oaParam.getBusinessService()) {
+ String id = oaParam.getIdentityLinkDomainIdentifier();
+ if (id.startsWith(AuthenticationSession.REGISTERANDORDNR_PREFIX_))
+ targetValue = id.substring(AuthenticationSession.REGISTERANDORDNR_PREFIX_.length());
+ else
+ targetValue = moasession.getDomainIdentifier();
+ targetType = AuthenticationSession.REGISTERANDORDNR_PREFIX_;
+ } else {
+ targetType = AuthenticationSession.TARGET_PREFIX_;
+ targetValue = oaParam.getTarget();
+ }
+
Logger.debug("Starting connecting SZR Gateway");
//contact SZR Gateway
IdentityLink identityLink = null;
try {
- identityLink = STORKResponseProcessor.connectToSZRGateway(citizenSignature, storkAssertion.getAttributeStatements().get(0).getAttributes());
+ identityLink = STORKResponseProcessor.connectToSZRGateway(authnResponse.getPersonalAttributeList(),
+ oaParam.getFriendlyName(),
+ targetType, targetValue,
+ oaParam.getMandateProfiles());
} catch (STORKException e) {
Logger.error("Error connecting SZR Gateway", e);
throw new MOAIDException("stork.10", null);
@@ -213,49 +314,28 @@ public class PEPSConnectorServlet extends AuthServlet {
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<ExtendedSAMLAttribute> moaExtendedSAMLAttibutes = STORKResponseProcessor.addAdditionalSTORKAttributes(storkAssertion.getAttributeStatements().get(0).getAttributes());
- moaSession.setExtendedSAMLAttributesOA(moaExtendedSAMLAttibutes);
+ Logger.debug("Adding addtional STORK attributes to MOA session");
+ moaSession.setStorkAttributes(authnResponse.getPersonalAttributeList());
//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(moaSession);
- Logger.info("MOA assertion assembled and SAML Artifact generated.");
+
+ // free for single use
+ moaSession.setAuthenticatedUsed(false);
+
+ // stork did the authentication step
+ moaSession.setAuthenticated(true);
//session is implicit stored in changeSessionID!!!!
String newMOASessionID = AuthenticationSessionStoreage.changeSessionID(moaSession);
Logger.info("Changed MOASession " + moaSessionID + " to Session " + newMOASessionID);
- Logger.info("Daten angelegt zu MOASession " + newMOASessionID);
//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(), pendingRequestID), newMOASessionID);
redirectURL = response.encodeRedirectURL(redirectURL);
- } else {
-
- redirectURL = new DataURLBuilder().buildDataURL(moaSession.getAuthURL(), AuthenticationServer.REQ_PROCESS_VALIDATOR_INPUT, newMOASessionID);
- }
-
- try {
- AuthenticationSessionStoreage.storeSession(moaSession);
- } catch (MOADatabaseException e) {
- throw new MOAIDException("Session store error", null);
- }
response.setContentType("text/html");
response.setStatus(302);