/******************************************************************************* * 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.stork2; import at.gv.egovernment.moa.id.auth.MOAIDAuthConstants; import at.gv.egovernment.moa.id.auth.exception.AuthenticationException; import at.gv.egovernment.moa.id.auth.exception.MOAIDException; import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProviderFactory; import at.gv.egovernment.moa.id.config.auth.OAAuthParameter; import at.gv.egovernment.moa.id.moduls.IAction; import at.gv.egovernment.moa.id.moduls.IModulInfo; import at.gv.egovernment.moa.id.moduls.IRequest; import at.gv.egovernment.moa.logging.Logger; import at.gv.egovernment.moa.util.MiscUtil; import eu.stork.peps.auth.commons.*; import eu.stork.peps.auth.engine.STORKSAMLEngine; import eu.stork.peps.exceptions.STORKSAMLEngineException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.util.HashMap; /** * Stork 2 Protocol Support * * @author bsuzic */ public class STORKProtocol extends MOAIDAuthConstants implements IModulInfo { public static final String NAME = STORKProtocol.class.getName(); public static final String PATH = "id_stork2"; public static final String AUTHENTICATIONREQUEST = "AuthenticationRequest"; public static final String ATTRIBUTE_COLLECTOR = "AttributeCollector"; public static final String MANDATERETRIEVALREQUEST = "MandateRetrievalRequest"; public static final String CONSENT_EVALUATOR = "ConsentEvaluator"; private static HashMap actions = new HashMap(); static { actions.put(AUTHENTICATIONREQUEST, new AuthenticationRequest()); actions.put(ATTRIBUTE_COLLECTOR, new AttributeCollector()); actions.put(CONSENT_EVALUATOR, new ConsentEvaluator()); actions.put(MANDATERETRIEVALREQUEST, new MandateRetrievalRequest()); } public String getName() { return NAME; } public String getPath() { return PATH; } public IAction getAction(String action) { return actions.get(action); } public STORKProtocol() { super(); } /* First request step - send it to BKU selection for user authentication. After the user credentials and other info are obtained, in the second step the request will be processed and the user redirected */ public IRequest preProcess(HttpServletRequest request, HttpServletResponse response, String action, String sessionId, String transactionId) throws MOAIDException { Logger.info("Starting preprocessing for Stork2 protocol"); Logger.debug("Request method: " + request.getMethod()); Logger.debug("Request content length: " + request.getContentLength()); Logger.debug("Initiating action: " + action); MOASTORKRequest STORK2Request = new MOASTORKRequest(request); MOASTORKResponse STORK2Response = new MOASTORKResponse(request); if (AttributeCollector.class.getSimpleName().equals(action) || ConsentEvaluator.class.getSimpleName().equals(action)) return STORK2Request; if (request.getParameter("SAMLResponse") != null) { // TODO check attribute collector //extract STORK Response from HTTP Request byte[] decSamlToken; try { decSamlToken = PEPSUtil.decodeSAMLToken(request.getParameter("SAMLResponse")); } catch (NullPointerException e) { if (request.getRemoteHost().contains("129.27.142")) { Logger.warn("Availability check by " + request.getRemoteHost() + " on URI: " + request.getRequestURI()); } else { Logger.error("Unable to retrieve STORK Request for host: " + request.getRemoteHost() + " and URI: " + request.getRequestURI(), e); } throw new MOAIDException("stork.04", null); } //Get SAMLEngine instance STORKSAMLEngine engine = STORKSAMLEngine.getInstance("VIDP"); STORKAuthnResponse authnResponse = null; // check if valid authn request is contained try { authnResponse = engine.validateSTORKAuthnResponse(decSamlToken, request.getRemoteAddr()); } catch (STORKSAMLEngineException ex) { Logger.error("Unable to validate Stork AuthenticationResponse: " + ex.getMessage()); } STORK2Response.setSTORKAuthnResponseToken(decSamlToken); return STORK2Response; } else if (request.getParameter("SAMLRequest") != null) { //extract STORK Response from HTTP Request byte[] decSamlToken; try { decSamlToken = PEPSUtil.decodeSAMLToken(request.getParameter("SAMLRequest")); } catch (NullPointerException e) { if (request.getRemoteHost().contains("129.27.142")) { Logger.warn("Availability check by " + request.getRemoteHost() + " on URI: " + request.getRequestURI()); } else { Logger.error("Unable to retrieve STORK Request for host: " + request.getRemoteHost() + " and URI: " + request.getRequestURI(), e); } throw new MOAIDException("stork.04", null); } //Get SAMLEngine instance STORKSAMLEngine engine = STORKSAMLEngine.getInstance("VIDP"); STORKAuthnRequest authnRequest = null; STORKAttrQueryRequest attrRequest = null; // check if valid authn request is contained try { authnRequest = engine.validateSTORKAuthnRequest(decSamlToken); } catch (STORKSAMLEngineException ex) { Logger.error("Unable to validate Stork AuthenticationRequest: " + ex.getMessage()); } catch (ClassCastException e) { // we do not have a authnRequest // check if a valid attr request is container try { attrRequest = engine.validateSTORKAttrQueryRequest(decSamlToken); } catch (STORKSAMLEngineException ex) { Logger.error("Unable to validate Stork AuthenticationRequest: " + ex.getMessage()); } } // if there is no authn or attr request, raise error if ((authnRequest == null) && (attrRequest == null)) { Logger.error("There is no authentication or attribute request contained."); throw new MOAIDException("stork.14", null); } // list attributes in the request try { for (PersonalAttribute personalAttribute : authnRequest.getPersonalAttributeList()) { Logger.debug("Personal attribute found in request: " + personalAttribute.getName() + " isRequired: " + personalAttribute.isRequired()); } } catch (Exception e) { Logger.error("Exception, attributes: " + e.getMessage()); } STORK2Request.setSTORKAuthnRequest(authnRequest); STORK2Request.setSTORKAttrRequest(attrRequest); //check if OA is instance of VIDP or STORKPVPGateway OAAuthParameter oaParam = AuthConfigurationProviderFactory.getInstance().getOnlineApplicationParameter(STORK2Request.getOAURL()); if (oaParam == null) throw new AuthenticationException("stork.12", new Object[]{STORK2Request.getOAURL()}); else { STORK2Request.setOnlineApplicationConfiguration(oaParam); if (oaParam.isSTORKPVPGateway()) { if (MiscUtil.isNotEmpty(oaParam.getSTORKPVPForwardEntity())) { Logger.info("Received request for STORK->PVP gateway. " + "Forward to PVP portal with entiyID " + oaParam.getSTORKPVPForwardEntity() + " ..." ); STORK2Request.setRequestedIDP(oaParam.getSTORKPVPForwardEntity()); } else { Logger.error("InterfederatedGateway configuration with ID " + STORK2Request.getOAURL() + " not configure a forward entityID."); throw new MOAIDException("", null); } } } return STORK2Request; } else { throw new MOAIDException("stork.14", null); // TODO Specify message } } public IAction canHandleRequest(HttpServletRequest request, HttpServletResponse response) { return null; } public boolean generateErrorMessage(Throwable e, HttpServletRequest request, HttpServletResponse response, IRequest protocolRequest) throws Throwable { return false; } public boolean validate(HttpServletRequest request, HttpServletResponse response, IRequest pending) { return false; } }