/******************************************************************************* * Copyright 2014 Federal Chancellery Austria * MOA-ID has been developed in a cooperation between BRZ, the Federal * Chancellery Austria - ICT staff unit, and Graz University of Technology. * * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by * the European Commission - subsequent versions of the EUPL (the "Licence"); * You may not use this work except in compliance with the Licence. * You may obtain a copy of the Licence at: * http://www.osor.eu/eupl/ * * Unless required by applicable law or agreed to in writing, software * distributed under the Licence is distributed on an "AS IS" basis, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the Licence for the specific language governing permissions and * limitations under the Licence. * * This product combines work with different licenses. See the "NOTICE" text * file for details on the various modules and licenses. * The "NOTICE" text file is part of the distribution. Any derivative works * that you distribute must include a readable copy of the "NOTICE" text file. *******************************************************************************/ package at.gv.egovernment.moa.id.protocols.eidas; import java.io.StringWriter; import java.text.SimpleDateFormat; import java.util.Map.Entry; import at.gv.egovernment.moa.id.auth.builder.BPKBuilder; import at.gv.egovernment.moa.id.auth.exception.MOAIDException; import at.gv.egovernment.moa.id.auth.modules.eidas.Constants; import at.gv.egovernment.moa.id.auth.modules.eidas.engine.MOAeIDASChainingMetadataProvider; import at.gv.egovernment.moa.id.auth.modules.eidas.engine.MOAeIDASMetadataProviderDecorator; import at.gv.egovernment.moa.id.auth.modules.eidas.utils.MOAPersonalAttributeList; import at.gv.egovernment.moa.id.auth.modules.eidas.utils.SAMLEngineUtils; import at.gv.egovernment.moa.id.config.auth.AuthConfiguration; import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProviderFactory; import at.gv.egovernment.moa.id.data.IAuthData; 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.util.VelocityProvider; import at.gv.egovernment.moa.logging.Logger; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.velocity.Template; import org.apache.velocity.VelocityContext; import org.apache.velocity.app.VelocityEngine; import eu.eidas.auth.commons.EIDASAuthnResponse; import eu.eidas.auth.commons.EIDASStatusCode; import eu.eidas.auth.commons.EIDASUtil; import eu.eidas.auth.commons.PersonalAttribute; import eu.eidas.auth.engine.EIDASSAMLEngine; import eu.eidas.auth.engine.metadata.MetadataUtil; /** * Second request step - after authentication of the user is done and moasession obtained, * process request and forward the user further to PEPS and/or other entities * * @author bsuzic */ public class AuthenticationRequest implements IAction { @Override public SLOInformationInterface processRequest(IRequest req, HttpServletRequest httpReq, HttpServletResponse httpResp, IAuthData authData) throws MOAIDException { EIDASData eidasRequest; if(req instanceof EIDASData) eidasRequest = (EIDASData) req; else throw new MOAIDException("got wrong IRequest type. is: {}, should be: {}", new String[] {req.getClass().toString(), EIDASData.class.toString()}); // gather attributes MOAPersonalAttributeList resultingAttributeList = (MOAPersonalAttributeList) eidasRequest.getEidasRequestedAttributes().clone(); for(Entry current : resultingAttributeList.entrySet()) { String newValue = ""; // TODO make use of proper builder switch(current.getKey()) { case Constants.eIDAS_ATTR_DATEOFBIRTH: newValue = new SimpleDateFormat("YYYY-MM-dd").format(authData.getDateOfBirth()); break; case Constants.eIDAS_ATTR_CURRENTFAMILYNAME: newValue = authData.getFamilyName();break; case Constants.eIDAS_ATTR_CURRENTGIVENNAME: newValue = authData.getGivenName();break; case Constants.eIDAS_ATTR_PERSONALIDENTIFIER: newValue = new BPKBuilder().buildStorkeIdentifier(authData.getIdentificationType(), authData.getIdentificationValue(), eidasRequest.getTarget()); break; } if("".equals(newValue)) current.getValue().setStatus(EIDASStatusCode.STATUS_NOT_AVAILABLE.toString()); else { current.getValue().getValue().clear(); current.getValue().getValue().add(newValue); current.getValue().setStatus(EIDASStatusCode.STATUS_AVAILABLE.toString()); } } // construct eIDaS response EIDASAuthnResponse response = new EIDASAuthnResponse(); response.setPersonalAttributeList(resultingAttributeList); // - create metadata url AuthConfiguration config = AuthConfigurationProviderFactory.getInstance(); String pubURLPrefix = config.getPublicURLPrefix(); String metadata_url = pubURLPrefix + Constants.eIDAS_HTTP_ENDPOINT_METADATA; response.setIssuer(metadata_url); response.setAssuranceLevel(authData.getEIDASQAALevel()); String token = null; try { EIDASSAMLEngine engine = SAMLEngineUtils.createSAMLEngine(); // check if we have the destination available, supply it if not if(null == eidasRequest.getEidasRequest().getAssertionConsumerServiceURL()) { String assertionConsumerUrl = MetadataUtil.getAssertionUrlFromMetadata( new MOAeIDASMetadataProviderDecorator(MOAeIDASChainingMetadataProvider.getInstance()), engine, eidasRequest.getEidasRequest()); eidasRequest.getEidasRequest().setAssertionConsumerServiceURL(assertionConsumerUrl); } response = engine.generateEIDASAuthnResponse(eidasRequest.getEidasRequest(), response, eidasRequest.getRemoteAddress(), true); token = EIDASUtil.encodeSAMLToken(response.getTokenSaml()); } catch(Exception e) { e.printStackTrace(); } // send the response try { VelocityEngine velocityEngine = VelocityProvider.getClassPathVelocityEngine(); Template template = velocityEngine.getTemplate("/resources/templates/stork2_postbinding_template.html"); VelocityContext context = new VelocityContext(); context.put("SAMLResponse", token); Logger.debug("SAMLResponse original: " + token); Logger.debug("Putting assertion consumer url as action: " + eidasRequest.getEidasRequest().getAssertionConsumerServiceURL()); context.put("action", eidasRequest.getEidasRequest().getAssertionConsumerServiceURL()); Logger.trace("Starting template merge"); StringWriter writer = new StringWriter(); Logger.trace("Doing template merge"); template.merge(context, writer); Logger.trace("Template merge done"); Logger.trace("Sending html content: " + writer.getBuffer().toString()); Logger.trace("Sending html content2 : " + new String(writer.getBuffer())); httpResp.getOutputStream().write(writer.getBuffer().toString().getBytes("UTF-8")); } catch (Exception e) { Logger.error("Velocity error: " + e.getMessage()); } return null; } @Override public boolean needAuthentication(IRequest req, HttpServletRequest httpReq, HttpServletResponse httpResp) { return true; } @Override public String getDefaultActionName() { // TODO Auto-generated method stub return null; } }