/* * 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.attributeproviders; import java.io.StringWriter; 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 at.gv.egovernment.moa.id.auth.exception.MOAIDException; import at.gv.egovernment.moa.id.config.auth.OAAuthParameter; import at.gv.egovernment.moa.id.data.IAuthData; import at.gv.egovernment.moa.id.protocols.stork2.ExternalAttributeRequestRequiredException; import at.gv.egovernment.moa.id.protocols.stork2.MOASTORKRequest; import at.gv.egovernment.moa.id.protocols.stork2.UnsupportedAttributeException; import at.gv.egovernment.moa.id.util.HTTPUtils; import at.gv.egovernment.moa.id.util.VelocityProvider; import at.gv.egovernment.moa.logging.Logger; import at.gv.egovernment.moa.util.StringUtils; import eu.stork.peps.auth.commons.IPersonalAttributeList; import eu.stork.peps.auth.commons.PEPSUtil; import eu.stork.peps.auth.commons.PersonalAttribute; import eu.stork.peps.auth.commons.STORKAttrQueryRequest; import eu.stork.peps.auth.commons.STORKAttrQueryResponse; 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; /** * @author tlenz * */ public class PVPAuthenticationProvider extends AttributeProvider { private String destination = null; private MOASTORKRequest moastorkRequest = null; /** * @param attributes * @param attributes2 */ public PVPAuthenticationProvider(String url, String attributes) { super(attributes); this.destination = url; } /* (non-Javadoc) * @see at.gv.egovernment.moa.id.protocols.stork2.attributeproviders.AttributeProvider#acquire(eu.stork.peps.auth.commons.PersonalAttribute, java.lang.String, at.gv.egovernment.moa.id.data.IAuthData) */ @Override protected IPersonalAttributeList acquire(PersonalAttribute attribute, MOASTORKRequest moastorkRequest, IAuthData authData) throws UnsupportedAttributeException, ExternalAttributeRequestRequiredException, MOAIDException { this.moastorkRequest = moastorkRequest; // break if we cannot handle the requested attribute if (!attributes.contains(attribute.getName())) { Logger.info("Attribute " + attribute.getName() + " not supported by the provider: " + getAttrProviderName()); throw new UnsupportedAttributeException(); } Logger.info("Thrown external request by: " + getAttrProviderName()); throw new ExternalAttributeRequestRequiredException(this); } /* (non-Javadoc) * @see at.gv.egovernment.moa.id.protocols.stork2.attributeproviders.AttributeProvider#performRedirect(java.lang.String, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, at.gv.egovernment.moa.id.config.auth.OAAuthParameter) */ @Override public void performRedirect(String url, HttpServletRequest req, HttpServletResponse resp, OAAuthParameter oaParam) throws MOAIDException { String spSector = "Business"; String spInstitution = StringUtils.isEmpty(oaParam.getFriendlyName()) ? "UNKNOWN" : oaParam.getFriendlyName(); String spApplication = spInstitution; String spCountryCode = moastorkRequest.getSpCountry(); if ((spCountryCode == null) || (spCountryCode.length()<2)) { spCountryCode = oaParam.getTarget(); Logger.info("Setting spcountry target: " + oaParam.getTarget()); Logger.info("idlink ident " + oaParam.getIdentityLinkDomainIdentifier()); Logger.info("idlink type " + oaParam.getIdentityLinkDomainIdentifierType()); Logger.info("Setting spcountry target friendly : " + oaParam.getTargetFriendlyName()); Logger.info("Oatype : " + oaParam.getOaType()); Logger.info("puburl : " + oaParam.getPublicURLPrefix()); if ("STORK".equals(oaParam.getIdentityLinkDomainIdentifierType())) { spCountryCode = oaParam.getIdentityLinkDomainIdentifier().substring(oaParam.getIdentityLinkDomainIdentifier().length()-2); Logger.info("Set to " +spCountryCode); } } //generate AttrQueryRequest STORKAuthnRequest authRequest = new STORKAuthnRequest(); authRequest.setDestination(destination); authRequest.setAssertionConsumerServiceURL(url); authRequest.setIssuer(HTTPUtils.getBaseURL(req)); authRequest.setQaa(oaParam.getQaaLevel()); authRequest.setSpInstitution(spInstitution); authRequest.setCountry(spCountryCode); authRequest.setSpCountry(spCountryCode); authRequest.setSpApplication(spApplication); authRequest.setProviderName(spApplication); authRequest.setSpSector(spSector); authRequest.setPersonalAttributeList(moastorkRequest.getPersonalAttributeList()); authRequest.setCitizenCountryCode("AT"); authRequest.setQaa(oaParam.getQaaLevel()); if (authRequest.getQaa() == 0 ) { authRequest.setQaa(4); // workaround } Logger.info("STORK AttrRequest successfully assembled."); STORKSAMLEngine samlEngine = STORKSAMLEngine.getInstance("VIDP"); try { authRequest = samlEngine.generateSTORKAuthnRequest(authRequest); } catch (STORKSAMLEngineException e) { Logger.error("Could not sign STORK SAML AttrRequest.", e); throw new MOAIDException("stork.00", null); } Logger.info("STORK AttrRequest successfully signed!"); //validate AuthnRequest try { samlEngine.validateSTORKAuthnRequest(authRequest.getTokenSaml()); } catch (STORKSAMLEngineException e) { Logger.error("STORK SAML AuthnRequest not valid.", e); throw new MOAIDException("stork.01", null); } Logger.debug("STORK AuthnRequest successfully internally validated."); try { Logger.trace("Initialize VelocityEngine..."); VelocityEngine velocityEngine = VelocityProvider.getClassPathVelocityEngine(); Template template = velocityEngine.getTemplate("/resources/templates/saml2-post-binding-moa.vm"); VelocityContext context = new VelocityContext(); context.put("SAMLRequest", PEPSUtil.encodeSAMLToken(authRequest.getTokenSaml())); context.put("action", destination); StringWriter writer = new StringWriter(); template.merge(context, writer); resp.getOutputStream().write(writer.toString().getBytes("UTF-8")); } catch (Exception e) { Logger.error("Error sending STORK SAML AttrRequest.", e); throw new MOAIDException("stork.11", null); } Logger.info("STORK AttrRequest successfully rendered!"); } /* (non-Javadoc) * @see at.gv.egovernment.moa.id.protocols.stork2.attributeproviders.AttributeProvider#parse(javax.servlet.http.HttpServletRequest) */ @Override public IPersonalAttributeList parse(HttpServletRequest httpReq) throws UnsupportedAttributeException, MOAIDException { Logger.info(this.getClass().getSimpleName() + " tries to extract SAMLResponse out of HTTP Request"); //extract STORK Response from HTTP Request //Decodes SAML Response byte[] decSamlToken; try { decSamlToken = PEPSUtil.decodeSAMLToken(httpReq.getParameter("SAMLResponse")); } catch(NullPointerException e) { throw new UnsupportedAttributeException(); } //Get SAMLEngine instance STORKSAMLEngine engine = STORKSAMLEngine.getInstance("VIDP"); STORKAuthnResponse authnResponse = null; try { //validate SAML Token Logger.debug("Starting validation of SAML response"); authnResponse = engine.validateSTORKAuthnResponse(decSamlToken, (String) httpReq.getRemoteHost()); Logger.info("SAML response successfully verified!"); }catch(STORKSAMLEngineException e){ Logger.error("Failed to verify STORK SAML Response", e); throw new MOAIDException("stork.05", null); } return authnResponse.getPersonalAttributeList(); } /* (non-Javadoc) * @see at.gv.egovernment.moa.id.protocols.stork2.attributeproviders.AttributeProvider#getPriority() */ @Override public int getPriority() { return 1; } public String getAttrProviderName() { return this.getClass().getName(); } }