diff options
Diffstat (limited to 'id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/AuthenticationRequest.java')
-rw-r--r-- | id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/AuthenticationRequest.java | 319 |
1 files changed, 290 insertions, 29 deletions
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/AuthenticationRequest.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/AuthenticationRequest.java index 7269e361c..110ef327f 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/AuthenticationRequest.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/AuthenticationRequest.java @@ -3,24 +3,33 @@ package at.gv.egovernment.moa.id.protocols.stork2; import at.gv.egovernment.moa.id.auth.data.AuthenticationSession; import at.gv.egovernment.moa.id.auth.exception.AuthenticationException; import at.gv.egovernment.moa.id.auth.exception.MOAIDException; +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.data.SLOInformationImpl; import at.gv.egovernment.moa.id.data.SLOInformationInterface; import at.gv.egovernment.moa.id.moduls.IAction; import at.gv.egovernment.moa.id.moduls.IRequest; +import at.gv.egovernment.moa.id.storage.AssertionStorage; +import at.gv.egovernment.moa.id.util.VelocityProvider; import at.gv.egovernment.moa.id.util.client.mis.simple.MISMandate; import at.gv.egovernment.moa.logging.Logger; import eu.stork.peps.auth.commons.*; import eu.stork.peps.auth.engine.STORKSAMLEngine; import eu.stork.peps.exceptions.STORKSAMLEngineException; +import org.apache.velocity.Template; +import org.apache.velocity.VelocityContext; import org.apache.velocity.app.VelocityEngine; import org.apache.velocity.runtime.RuntimeConstants; -import org.joda.time.DateTime; import org.w3c.dom.Element; import org.w3c.dom.NamedNodeMap; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.io.StringWriter; +import java.net.MalformedURLException; +import java.net.URL; /** @@ -42,23 +51,23 @@ public class AuthenticationRequest implements IAction { this.moaSession = moasession; - if (req instanceof MOASTORKRequest) { + if ((req instanceof MOASTORKRequest) && ((MOASTORKRequest) req).getStorkAuthnRequest().getCitizenCountryCode().equals("AT")) { this.moaStorkRequest = (MOASTORKRequest) req; Logger.debug("Entering MOASTORKRequest"); httpResp.reset(); - + OAAuthParameter oaParam = AuthConfigurationProvider.getInstance().getOnlineApplicationParameter(moasession.getPublicOAURLPrefix()); if (oaParam == null) throw new AuthenticationException("stork.12", new Object[]{moasession.getPublicOAURLPrefix()}); MOASTORKResponse moaStorkResponse = new MOASTORKResponse(); - + // check if it is attribute query if (moaStorkRequest.isAttrRequest()) { Logger.debug("Starting AttrQueryRequest"); - + moaStorkResponse.setSTORKAttrResponse(new STORKAttrQueryResponse()); } // check if we have authentication request @@ -66,22 +75,20 @@ public class AuthenticationRequest implements IAction { Logger.debug("Starting AuthenticationRequest"); moaStorkResponse.setSTORKAuthnResponse(new STORKAuthnResponse()); + //STORKSAMLEngine engine = STORKSAMLEngine.getInstance("VIDP"); - STORKSAMLEngine engine = STORKSAMLEngine.getInstance("VIDP"); - - Logger.debug("Starting generation of SAML response"); - try { - moaStorkResponse.setSTORKAuthnResponse(engine.generateSTORKAuthnResponse(moaStorkRequest.getStorkAuthnRequest(), moaStorkResponse.getStorkAuthnResponse(),httpReq.getRemoteAddr(), false)); - } catch (STORKSAMLEngineException ex) { - // TODO - } + // Logger.debug("Starting generation of SAML response"); + // try { + // moaStorkResponse.setSTORKAuthnResponse(engine.generateSTORKAuthnResponse(moaStorkRequest.getStorkAuthnRequest(), moaStorkResponse.getStorkAuthnResponse(), httpReq.getRemoteAddr(), false)); + // } catch (STORKSAMLEngineException ex) { + // Logger.error("Failed to generate STORK SAML Response", ex); + // throw new MOAIDException("stork.05", null); // TODO + // } // Get personal attributtes from MOA/IdentityLink moaStorkResponse.setPersonalAttributeList(populateAttributes()); - - } - + //moaStorkResponse.setCountry(moaStorkRequest.getSpCountry()); // Prepare extended attributes @@ -98,31 +105,285 @@ public class AuthenticationRequest implements IAction { container.setRemoteAddress(httpReq.getRemoteAddr()); + Logger.debug("Data container prepared"); - STORKAuthnResponse arep = moaStorkResponse.getStorkAuthnResponse(); + return (new AttributeCollector()).processRequest(container, httpReq, httpResp, moasession, oaParam); + } + // check if we are getting request for citizen of some other country + else if (req instanceof MOASTORKRequest) { + return handleMOAStorkRequest("VIDP", (MOASTORKRequest) req, httpReq.getRemoteAddr(), httpResp); + } + // Check if we got the response from PEPS + // If so then process it and forward to SP + else if ((req instanceof MOASTORKResponse)) { + return handleMOAStorkResponse("VIDP", (MOASTORKResponse) req, httpReq.getRemoteAddr(), httpResp); + } else { + Logger.error("Could not recognize request."); + throw new MOAIDException("stork.15", null); + } + } - arep.setCountry("XX"); - arep.setInResponseTo("xxxx"); - arep.setMessage("xxxx"); - arep.setSamlId("xxxx"); - arep.setStatusCode("xxxx"); + /* + Handles STORKAuthnRequeste received for citizens of other countries + */ + private SLOInformationInterface handleMOAStorkRequest(String instanceName, MOASTORKRequest moastorkRequest, String remoteAddr, HttpServletResponse httpResp) throws MOAIDException { - // arep.setNotBefore(new DateTime().withTimeAtStartOfDay()); - // arep.setNotOnOrAfter(new DateTime().withTimeAtStartOfDay()); + STORKAuthnRequest spAuthnRequest = moastorkRequest.getStorkAuthnRequest(); + STORKAuthnRequest storkAuthnRequest = null; + String citizenCountryCode = spAuthnRequest.getCitizenCountryCode(); + Logger.info("Got authentication request for citizen of " + citizenCountryCode); - Logger.debug("Data container prepared"); + try { + storkAuthnRequest = (STORKAuthnRequest) spAuthnRequest.clone(); + } catch (CloneNotSupportedException e) { + Logger.error("Could not clone AuthnRequest ", e); + throw new MOAIDException("stork.05", null); // TODO + } //TODO: in case of Single LogOut -> SLO information has to be stored - return (new AttributeCollector()).processRequest(container, httpReq, httpResp, moasession, oaParam); - } else { - Logger.error("Could not recognize request."); - throw new MOAIDException("stork.15", null); + // check if citizen country is configured in the system + if (!(AuthConfigurationProvider.getInstance().getStorkConfig().getCpepsMap().containsKey(citizenCountryCode))) { + Logger.error("Citizen country PEPS not configured in MOA instance: " + citizenCountryCode); + throw new MOAIDException("stork.05", null); // TODO + } + + // extracting basic settings and adjusting assertion consumer + String issuer = null; + String assertionConsumerURL = null; + String publicURLPrefix = null; + String destinationURL = null; + + try { + issuer = new URL(AuthConfigurationProvider.getInstance().getPublicURLPrefix()).toString(); + destinationURL = AuthConfigurationProvider.getInstance().getStorkConfig().getCPEPS(citizenCountryCode).getPepsURL().toString(); + publicURLPrefix = AuthConfigurationProvider.getInstance().getPublicURLPrefix(); + assertionConsumerURL = publicURLPrefix + "/stork2/SendPEPSAuthnRequest"; + } catch (MalformedURLException ex) { + Logger.error("Wrong PublicURLPrefix setting of MOA instance: " + AuthConfigurationProvider.getInstance().getPublicURLPrefix(), ex); + throw new MOAIDException("stork.05", null); // TODO + } catch (Exception ex) { + Logger.error("Problem with PEPS configuration of MOA instance.", ex); + throw new MOAIDException("stork.05", null); // TODO + } + + + // drop if we do not have publicprefix url configured on the instance + if (publicURLPrefix == null) + throw new AuthenticationException("stork.12", new String[]{"PublicURLPrefix"}); + + // adjusting request + storkAuthnRequest.setEIDCrossBorderShare(spAuthnRequest.isEIDCrossBorderShare()); + storkAuthnRequest.setEIDSectorShare(spAuthnRequest.isEIDSectorShare()); + storkAuthnRequest.setEIDCrossSectorShare(spAuthnRequest.isEIDCrossSectorShare()); + storkAuthnRequest.setCitizenCountryCode(spAuthnRequest.getCitizenCountryCode()); + storkAuthnRequest.setIssuer(issuer); + storkAuthnRequest.setAssertionConsumerServiceURL(assertionConsumerURL); + storkAuthnRequest.setDestination(destinationURL); + + // regenerate request + try { + //Get SAMLEngine instance + STORKSAMLEngine engine = STORKSAMLEngine.getInstance("VIDP"); + Logger.debug("Starting generation of SAML request"); + storkAuthnRequest = engine.generateSTORKAuthnRequest(storkAuthnRequest); + + //generateSAML Token + Logger.info("SAML response succesfully generated!"); + } catch (STORKSAMLEngineException e) { + Logger.error("Failed to generate STORK SAML Response", e); + throw new MOAIDException("stork.05", null); + } + + // store original request from SP in order to be able to extract it in later iteration/response + DataContainer spRequestContainer = new DataContainer(); + spRequestContainer.setRequest(moastorkRequest); + + try { + AssertionStorage.getInstance().put(storkAuthnRequest.getSamlId(), spRequestContainer); + Logger.info("Storing artifactId " + storkAuthnRequest.getSamlId() + " of SP authentication request with id " + spAuthnRequest.getSamlId()); + } catch (MOADatabaseException e) { + e.printStackTrace(); + } + + // preparing redirection for the client + performRedirection("SAMLRequest", destinationURL, storkAuthnRequest.getTokenSaml(), httpResp); + + SLOInformationImpl sloInfo = new SLOInformationImpl(); + sloInfo.setProtocolType(moastorkRequest.requestedModule()); + return sloInfo; + } + + /* + Handles STORKAuthnResponse received from PEPS (return to SP) + */ + private SLOInformationInterface handleMOAStorkResponse(String instanceName, MOASTORKResponse moastorkResponse, String remoteAddr, HttpServletResponse httpResp) throws MOAIDException { + + STORKAuthnResponse authnResponse = null; + + //Get SAMLEngine instance + STORKSAMLEngine engine = STORKSAMLEngine.getInstance(instanceName); + + try { + authnResponse = engine.validateSTORKAuthnResponse(moastorkResponse.getSTORKAuthnResponseToken(), remoteAddr); + } catch (STORKSAMLEngineException ex) { + Logger.error("Unable to validate Stork AuthenticationResponse: " + ex.getMessage()); + throw new MOAIDException("stork.15", null); // TODO + } + + Logger.debug("Requesting artifactId " + authnResponse.getInResponseTo() + " from store."); + + DataContainer dataContainer = null; + try { + dataContainer = AssertionStorage.getInstance().get(authnResponse.getInResponseTo(), DataContainer.class); + } catch (MOADatabaseException e) { + Logger.error("Unable to retrieve datacontainer with reference authentication request. Database exception."); + throw new MOAIDException("stork.15", null); // TODO + } + + // setting new reference request and return url + authnResponse.setInResponseTo(dataContainer.getRequest().getStorkAuthnRequest().getSamlId()); + authnResponse.setAudienceRestriction(dataContainer.getRequest().getAssertionConsumerServiceURL()); + //AudienceRestrictionBuilder audienceRestrictionBuilder = new AudienceRestrictionBuilder(); + //AudienceRestriction audienceRestriction = audienceRestrictionBuilder.buildObject(dataContainer.getRequest().getAssertionConsumerServiceURL(), "localname", "nameprefix"); + + //authnResponse.getAssertions().get(0).getConditions().getAudienceRestrictions().add(audienceRestriction); + + Logger.debug("Starting generation of SAML response"); + try { + authnResponse = engine.generateSTORKAuthnResponse(dataContainer.getRequest().getStorkAuthnRequest(), authnResponse, remoteAddr, false); + } catch (STORKSAMLEngineException e) { + Logger.error("Failed to generate STORK SAML Response", e); + throw new MOAIDException("stork.05", null); // TODO check + } + + Logger.info("SAML response succesfully generated."); + + // preparing redirection for the client + performRedirection("SAMLResponse", dataContainer.getRequest().getAssertionConsumerServiceURL(), authnResponse.getTokenSaml(), httpResp); + + return null; + } + + /* + Perform redirection of the client based on post binding + */ + private void performRedirection(String actionType, String assertionConsumerURL, byte[] tokenSaml, HttpServletResponse httpResp) throws MOAIDException { + Logger.info("Performing redirection, using action type: " + actionType); + + try { + VelocityEngine velocityEngine = VelocityProvider.getClassPathVelocityEngine(); + Template template = velocityEngine.getTemplate("/resources/templates/stork2_postbinding_template.html"); + VelocityContext context = new VelocityContext(); + + context.put(actionType, PEPSUtil.encodeSAMLToken(tokenSaml)); + Logger.debug("Encoded " + actionType + " original: " + new String(tokenSaml)); + + Logger.debug("Using assertion consumer url as action: " + assertionConsumerURL); + context.put("action", assertionConsumerURL); + + Logger.debug("Starting template merge"); + StringWriter writer = new StringWriter(); + + Logger.debug("Doing template merge"); + template.merge(context, writer); + Logger.debug("Template merge done"); + + Logger.debug("Sending html content: " + writer.getBuffer().toString()); + Logger.debug("Sending html content2 : " + new String(writer.getBuffer())); + + httpResp.getOutputStream().write(writer.getBuffer().toString().getBytes()); + + } catch (IOException e) { + Logger.error("Velocity IO error: " + e.getMessage()); + throw new MOAIDException("stork.15", null); // TODO + } catch (Exception e) { + Logger.error("Velocity general error: " + e.getMessage()); + throw new MOAIDException("stork.15", null); // TODO + } + + } + + public void generatePEPSRedirect(HttpServletResponse httpResp, DataContainer container) throws MOAIDException { + MOASTORKRequest request = container.getRequest(); + MOASTORKResponse response = container.getResponse(); + + Logger.info("generating stork response..."); + + try { + //Get SAMLEngine instance + STORKSAMLEngine engine = STORKSAMLEngine.getInstance("VIDP"); + Logger.debug("Starting generation of SAML response"); + if (response.isAuthnResponse()) + response.setSTORKAuthnResponse(engine.generateSTORKAuthnResponse(request.getStorkAuthnRequest(), response.getStorkAuthnResponse(), container.getRemoteAddress(), false)); + else + response.setSTORKAttrResponse(engine.generateSTORKAttrQueryResponse(request.getStorkAttrQueryRequest(), response.getStorkAttrQueryResponse(), container.getRemoteAddress(), "", false)); + + + //generateSAML Token + Logger.info("SAML response succesfully generated!"); + } catch (STORKSAMLEngineException e) { + Logger.error("Failed to generate STORK SAML Response", e); + throw new MOAIDException("stork.05", null); + } + + // preparing redirection for the client + try { + VelocityEngine velocityEngine = VelocityProvider.getClassPathVelocityEngine(); + Template template = velocityEngine.getTemplate("/resources/templates/stork2_postbinding_template.html"); + VelocityContext context = new VelocityContext(); + + byte[] blob; + if (request.isAttrRequest()) + blob = response.getStorkAttrQueryResponse().getTokenSaml(); + else + blob = response.getStorkAuthnResponse().getTokenSaml(); + + context.put("SAMLResponse", PEPSUtil.encodeSAMLToken(blob)); + Logger.debug("SAMLResponse original: " + new String(blob)); + + Logger.debug("Putting assertion consumer url as action: " + request.getAssertionConsumerServiceURL()); + context.put("action", request.getAssertionConsumerServiceURL()); + Logger.debug("Starting template merge"); + StringWriter writer = new StringWriter(); + + Logger.debug("Doing template merge"); + template.merge(context, writer); + Logger.debug("Template merge done"); + + Logger.debug("Sending html content: " + writer.getBuffer().toString()); + Logger.debug("Sending html content2 : " + new String(writer.getBuffer())); + + httpResp.getOutputStream().write(writer.getBuffer().toString().getBytes()); + + } catch (Exception e) { + Logger.error("Velocity error: " + e.getMessage()); } } + public boolean needAuthentication(IRequest req, HttpServletRequest httpReq, HttpServletResponse httpResp) { + + // authentication is not needed if we have authentication request from SP for citizen of configured PEPS country + if (req instanceof MOASTORKRequest) { + MOASTORKRequest moastorkRequest = (MOASTORKRequest) req; + if (moastorkRequest.getStorkAuthnRequest() != null) { + String citizenCountryCode = moastorkRequest.getStorkAuthnRequest().getCitizenCountryCode(); + // check if citizen country is configured in the system + try { + if (AuthConfigurationProvider.getInstance().getStorkConfig().getCpepsMap().containsKey(citizenCountryCode)) { + return false; + } + } catch (MOAIDException e) { + Logger.error("Could not initialize AuthConfigurationProvider"); + } + } + // authentication is not required if received authentication response + } else if (req instanceof MOASTORKResponse) { + return false; + } + return true; } |