diff options
| author | Bojan Suzic <bojan.suzic@iaik.tugraz.at> | 2014-02-25 19:01:11 +0100 | 
|---|---|---|
| committer | Bojan Suzic <bojan.suzic@iaik.tugraz.at> | 2014-02-25 19:01:11 +0100 | 
| commit | 8d438e785622695d55dbff05f8383447ff4eb251 (patch) | |
| tree | 91d5de425541d908a675865c69d759afe6429831 /id/server | |
| parent | e352ed4ac809c333ebbba3421f8cb1857850535b (diff) | |
| parent | 26404cedff0e60969c98d7a7cab30f8e7eda9ea6 (diff) | |
| download | moa-id-spss-8d438e785622695d55dbff05f8383447ff4eb251.tar.gz moa-id-spss-8d438e785622695d55dbff05f8383447ff4eb251.tar.bz2 moa-id-spss-8d438e785622695d55dbff05f8383447ff4eb251.zip | |
Merge branch 'ap' into moa2_0_tlenz_bs_3
Conflicts:
	id/ConfigWebTool/src/main/java/at/gv/egovernment/moa/id/configuration/data/oa/OASTORKConfig.java
	id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/stork/STORKConfig.java
	id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/AuthenticationRequest.java
Diffstat (limited to 'id/server')
16 files changed, 721 insertions, 14 deletions
| diff --git a/id/server/auth/src/main/webapp/WEB-INF/urlrewrite.xml b/id/server/auth/src/main/webapp/WEB-INF/urlrewrite.xml index b63d413d0..59d6d6cce 100644 --- a/id/server/auth/src/main/webapp/WEB-INF/urlrewrite.xml +++ b/id/server/auth/src/main/webapp/WEB-INF/urlrewrite.xml @@ -57,6 +57,10 @@          <to type="forward">/dispatcher?mod=id_stork2&action=AuthenticationRequest&%{query-string}</to>      </rule>      <rule match-type="regex"> +        <from>^/stork2/ResumeAuthentication$</from> +        <to type="forward">/dispatcher?mod=id_stork2&action=AttributeCollector&%{query-string}</to> +    </rule> +    <rule match-type="regex">          <from>^/stork2/SendPEPSAuthnRequest$</from>          <to type="forward">/dispatcher?mod=id_stork2&action=AuthenticationRequest&%{query-string}</to>      </rule> diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/auth/OAAuthParameter.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/auth/OAAuthParameter.java index 8e7ca0779..d1de20c4d 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/auth/OAAuthParameter.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/auth/OAAuthParameter.java @@ -51,6 +51,7 @@ import java.util.HashMap;  import java.util.List;  import java.util.Map; +import at.gv.egovernment.moa.id.commons.db.dao.config.AttributeProviderPlugin;  import at.gv.egovernment.moa.id.commons.db.dao.config.AuthComponentOA;  import at.gv.egovernment.moa.id.commons.db.dao.config.BKUSelectionCustomizationType;  import at.gv.egovernment.moa.id.commons.db.dao.config.BKUURLS; @@ -66,6 +67,7 @@ import at.gv.egovernment.moa.id.commons.db.dao.config.TemplatesType;  import at.gv.egovernment.moa.id.commons.db.dao.config.TransformsInfoType;  import at.gv.egovernment.moa.id.config.ConfigurationUtils;  import at.gv.egovernment.moa.id.config.OAParameter; +import at.gv.egovernment.moa.id.protocols.stork2.AttributeProvider;  import at.gv.egovernment.moa.id.util.FormBuildUtils;  import at.gv.egovernment.moa.logging.Logger;  import at.gv.egovernment.moa.util.MiscUtil; @@ -348,6 +350,9 @@ public List<OAStorkAttribute> getRequestedAttributes() {  	return oa_auth.getOASTORK().getOAAttributes();  } +public List<AttributeProviderPlugin> getStorkAPs() { +	return oa_auth.getOASTORK().getAttributeProviders(); +}  public byte[] getBKUSelectionTemplate() { diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/stork/STORKConfig.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/stork/STORKConfig.java index f79fd6e17..4dec2c32e 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/stork/STORKConfig.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/stork/STORKConfig.java @@ -25,6 +25,7 @@   */
  package at.gv.egovernment.moa.id.config.stork;
 +import java.io.IOException;
  import java.net.MalformedURLException;
  import java.net.URL;
  import java.util.ArrayList;
 @@ -33,10 +34,15 @@ import java.util.List;  import java.util.Map;
  import java.util.Properties;
 +import at.gv.egovernment.moa.id.commons.db.dao.config.SAMLSigningParameter;
  import at.gv.egovernment.moa.id.commons.db.dao.config.STORK;
  import at.gv.egovernment.moa.id.commons.db.dao.config.StorkAttribute;
  import at.gv.egovernment.moa.logging.Logger;
  import at.gv.egovernment.moa.util.StringUtils;
 +import org.opensaml.ws.message.encoder.MessageEncodingException;
 +import org.xml.sax.SAXException;
 +
 +import javax.xml.parsers.ParserConfigurationException;
  /**
   * Encapsulates several STORK configuration parameters according MOA configuration
 @@ -59,7 +65,8 @@ public class STORKConfig {  		this.props = props;
  		//create CPEPS map
 -		List<at.gv.egovernment.moa.id.commons.db.dao.config.CPEPS> cpeps = null;
 +		//List<at.gv.egovernment.moa.id.commons.db.dao.config.CPEPS> cpeps = stork.getCPEPS();
 +        List<at.gv.egovernment.moa.id.commons.db.dao.config.CPEPS> cpeps = new ArrayList<at.gv.egovernment.moa.id.commons.db.dao.config.CPEPS>();   // TODO Change this
          try {
              cpeps = stork.getCPEPS();
 @@ -82,20 +89,26 @@ public class STORKConfig {  							+ cpep.getCountryCode() + " has an invalid URL and is ignored.");
  				}
  			}
 +            /*catch (ParserConfigurationException e) {
 +				Logger.warn("Error in MOA-ID Configuration. CPEP entry for country " 
 +						+ cpep.getCountryCode() + " has an invalid Attribute and is ignored.");
 +			} catch (SAXException e) {
 +				Logger.warn("Error in MOA-ID Configuration. CPEP entry for country " 
 +						+ cpep.getCountryCode() + " has an invalid Attribute and is ignored.");
 +			} catch (IOException e) {
 +				Logger.warn("Error in MOA-ID Configuration. CPEP entry for country " 
 +						+ cpep.getCountryCode() + " has an invalid Attribute and is ignored.");
 +			} catch (MessageEncodingException e) {
 +				Logger.warn("Error in MOA-ID Configuration. CPEP entry for country " 
 +						+ cpep.getCountryCode() + " has an invalid Attribute and is ignored.");
 +			}*/
  		}
 -
  		attr = new ArrayList<StorkAttribute>();
 -
 -        try {
 -        if (stork.getAttributes() != null) {
 +		if (stork.getAttributes() != null) {
  			for(StorkAttribute current : stork.getAttributes()) {
  				attr.add(current);
  			}
  		}
 -        } catch (NullPointerException ex) {
 -            Logger.error("Attributes not configured!");
 -
 -        }
  	}
 diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/AttributeCollector.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/AttributeCollector.java new file mode 100644 index 000000000..08244ab38 --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/AttributeCollector.java @@ -0,0 +1,196 @@ +package at.gv.egovernment.moa.id.protocols.stork2; + +import java.util.ArrayList; +import java.util.List; + +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.moduls.IAction; +import at.gv.egovernment.moa.id.moduls.IRequest; +import at.gv.egovernment.moa.id.storage.AssertionStorage; +import at.gv.egovernment.moa.logging.Logger; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.opensaml.common.impl.SecureRandomIdentifierGenerator; + +import eu.stork.peps.auth.commons.IPersonalAttributeList; +import eu.stork.peps.auth.commons.PersonalAttribute; + +/** + * the AttributeCollector Action tries to get all requested attributes from a set of {@link AttributeProvider} Plugins. + * The class is called whenever the {@link AuthenticationRequest} Action is invoked and checks for missing attributes. + * Furthermore, the class can handle direct posts. That is when the class triggers an attribute query which needs user + * interaction, redirect to another portal, etc. The redirect will hit here and the class can continue to fetch attributes. + *  + * TODO how do we treat mandatory and optional attributes? + *  + */ +public class AttributeCollector implements IAction { +	 +	/** The Constant ARTIFACT_ID. */ +	private static final String ARTIFACT_ID = "artifactId"; +	 +    /* (non-Javadoc) +     * @see at.gv.egovernment.moa.id.moduls.IAction#processRequest(at.gv.egovernment.moa.id.moduls.IRequest, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, at.gv.egovernment.moa.id.auth.data.AuthenticationSession) +     */ +    public String processRequest(IRequest req, HttpServletRequest httpReq, HttpServletResponse httpResp, AuthenticationSession moasession) throws MOAIDException { + +		// read configuration parameters of OA +		OAAuthParameter oaParam = AuthConfigurationProvider.getInstance().getOnlineApplicationParameter(moasession.getPublicOAURLPrefix()); +		if (oaParam == null) +			throw new AuthenticationException("stork.12", new Object[] { moasession.getPublicOAURLPrefix() }); + +    	// find the attribute provider plugin that can handle the response +		IPersonalAttributeList newAttributes = null; +		for (AttributeProvider current : AttributeProviderFactory.getConfiguredPlugins(oaParam.getStorkAPs())) +			try { +				newAttributes = current.parse(httpReq); +			} catch (UnsupportedAttributeException e1) { +				// the current provider cannot find anything familiar within the +				// provided httpreq. Try the next one. +			} + +		if (null == newAttributes) { +			// we do not have a provider which is capable of fetching something +			// from the received httpreq. +			// TODO should we continue with the next attribute? +			Logger.error("No attribute could be retrieved from the response the attribute provider gave us."); +			throw new MOAIDException("stork.11", null); +		} + +    	// - fetch the container +		String artifactId = (String) httpReq.getAttribute(ARTIFACT_ID); +		DataContainer container; +		try { +			container = AssertionStorage.getInstance().get(artifactId, DataContainer.class); +		} catch (MOADatabaseException e) { +			Logger.error("Error fetching incomplete Stork response from temporary storage. Most likely a timeout occured.", e); +			throw new MOAIDException("stork.11", null); +		} + +    	// - insert the embedded attribute(s) into the container +		for(PersonalAttribute current : newAttributes) +			container.getResponse().getPersonalAttributeList().add(current); +    	 +    	// see if we need some more attributes +    	return processRequest(container, httpReq, httpResp, oaParam); +    } +     +    /** +     * Checks if there are missing attributes and tries to fetch them. If there are no more attribute to fetch, +     * this very method creates and sends the protocol result to the asking S-PEPS. +     * +     * @param container the {@link DataContainer} representing the status of the overall query. +     * @return the string +     * @throws MOAIDException  +     */ +    public String processRequest(DataContainer container, HttpServletRequest request, HttpServletResponse response, OAAuthParameter oaParam) throws MOAIDException { +    	// check if there are attributes we need to fetch +    	IPersonalAttributeList requestAttributeList = container.getRequest().getPersonalAttributeList(); +    	IPersonalAttributeList responseAttributeList = container.getResponse().getPersonalAttributeList(); +    	List<PersonalAttribute> missingAttributes = new ArrayList<PersonalAttribute>(); +    	for(PersonalAttribute current : requestAttributeList) +    		if(!responseAttributeList.containsKey(current)) +    			missingAttributes.add(current); +    	 +    	try { +	    	// for each attribute still missing +	    	for(PersonalAttribute currentAttribute : missingAttributes) { +	    	// - check if we can find a suitable AttributeProvider Plugin +				for (AttributeProvider currentProvider : AttributeProviderFactory.getConfiguredPlugins(oaParam.getStorkAPs())) { +					try { +						// - hand over control to the suitable plugin +						IPersonalAttributeList aquiredAttributes = currentProvider.acquire(currentAttribute); + +						// - add the aquired attribute to the container +						for(PersonalAttribute current : aquiredAttributes) +							container.getResponse().getPersonalAttributeList().add(current); +					} catch(UnsupportedAttributeException e) { +						// ok, try the next attributeprovider +					} +	 +	    		} +	    	} +		} catch (ExternalAttributeRequestRequiredException e) { +			// the attribute request is ongoing and requires an external service. +			try { +				// memorize the container again +				// - generate new key +				String newArtifactId = new SecureRandomIdentifierGenerator() +						.generateIdentifier();                                       /* +            Logger.debug("STORK QAA 2 :" + ((STORKAuthnRequestDEL) req).getStorkAuthnRequest().getQAALevel()); +            StartAuthResponse startAuthResponse = getStartAuthResponse(((STORKAuthnRequestDEL) req).getStorkAuthnRequest()); + +            HttpSession httpSession = httpReq.getSession(); +            httpSession.setAttribute("STORKSessionID", "12345"); +            httpResp.setStatus(startAuthResponse.getHttpStatusCode()); +            try { +                ServletOutputStream os = httpResp.getOutputStream(); +                String html = new String(startAuthResponse.getContent()); + + +                if (html.contains("<![CDATA[")) { +                    Logger.info("-------- content contains <![CDATA[-----------------"); +                    Logger.info("-------- content contains html -----------------"); +                    Logger.info("HTML : " + html); +                    int beginIndex = html.indexOf("<![CDATA["); +                    int endIndex = html.indexOf("]]>"); +                    html = html.substring(beginIndex + 9, endIndex); +                    startAuthResponse.setContent(html.getBytes()); +                } +                Logger.info("HTML : " + html); + +                os.write(startAuthResponse.getContent()); +                Logger.info("Response sent to client"); +            } catch (IOException e) { +                Logger.error("ERROR MOA"); +                throw new MOAIDException("error response sending", new Object[]{}); +            } +            //httpSession.setAttribute("CCC", ccc); + +          */ +        } + + +        //httpResp.setStatus(200); +        //VPEPSInboundPostHandler + +				// - put container in temporary store. +				AssertionStorage.getInstance().put(newArtifactId, container); + +				// add container-key to redirect embedded within the return URL +				e.getAp().performRedirect(AuthConfigurationProvider.getInstance().getPublicURLPrefix() + "?" + ARTIFACT_ID + "=" + newArtifactId, container.getRequest().getCitizenCountryCode(), request, response, oaParam); +			} catch (Exception e1) { +				// TODO should we return the response as is to the PEPS? +				Logger.error("Error putting incomplete Stork response into temporary storage", e); +				throw new MOAIDException("stork.11", null); +			} + +			return "12345"; // TODO what to do here? +		} +    	// build response +    	// done +    	return "12345"; // AssertionId +    } + +    /* (non-Javadoc) +     * @see at.gv.egovernment.moa.id.moduls.IAction#needAuthentication(at.gv.egovernment.moa.id.moduls.IRequest, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) +     */ +    public boolean needAuthentication(IRequest req, HttpServletRequest httpReq, HttpServletResponse httpResp) { +    	// this action does not need any authentication. The authentication is already done by the preceding AuthenticationRequest-Action. +        return false; +    } + +    /* (non-Javadoc) +     * @see at.gv.egovernment.moa.id.moduls.IAction#getDefaultActionName() +     */ +    public String getDefaultActionName() { +        return STORKProtocol.ATTRIBUTE_COLLECTOR; +    } +} diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/AttributeProvider.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/AttributeProvider.java new file mode 100644 index 000000000..adf57d77b --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/AttributeProvider.java @@ -0,0 +1,52 @@ +package at.gv.egovernment.moa.id.protocols.stork2; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import at.gv.egovernment.moa.id.auth.exception.MOAIDException; +import at.gv.egovernment.moa.id.config.auth.OAAuthParameter; + +import eu.stork.peps.auth.commons.IPersonalAttributeList; +import eu.stork.peps.auth.commons.PersonalAttribute; + +/** + * An {@link AttributeProvider} can fetch a set of stork attributes. It might complete the query within one method call, + * but might also need to redirect to another webservice to accomplish its task. + */ +public interface AttributeProvider { +	 +	/** +	 * Acquire the specified attribute. Returns {@code null} when attribute retrieval is in progress, but requires for +	 * for redirecting the user to an external service. Use {@link AttributeProvider#parse(HttpServletRequest)} to parse +	 * the response. +	 * +	 * @param attributes the list of attributes to be acquired +	 * @return the personal attribute +	 * @throws UnsupportedAttributeException the unsupported attribute exception +	 * @throws ExternalAttributeRequestRequiredException an attribute request to an external service has to be done +	 */ +	public IPersonalAttributeList acquire(PersonalAttribute attributes) throws UnsupportedAttributeException, ExternalAttributeRequestRequiredException; + +	/** +	 * Perform redirect. +	 * +	 * @param url the return URL ending with ?artifactId=... +	 * @param citizenCountyCode the citizen county code +	 * @param req the request we got from the S-PEPS and for which we have to ask our APs +	 * @param resp the response to the preceding request +	 * @param oaParam the oa param +	 * @throws MOAIDException  +	 */ +	public void performRedirect(String url, String citizenCountyCode, HttpServletRequest req, HttpServletResponse resp, OAAuthParameter oaParam) throws MOAIDException; +	 +	/** +	 * Parses the response we got from the external attribute provider. +	 * +	 * @param httpReq the http req +	 * @return a list of attributes +	 * @throws UnsupportedAttributeException if the provider cannot find anything familiar in the provided httpReq +	 * @throws MOAIDException if something went wrong +	 */ +	public IPersonalAttributeList parse(HttpServletRequest httpReq) throws UnsupportedAttributeException, MOAIDException; + +} diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/AttributeProviderFactory.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/AttributeProviderFactory.java new file mode 100644 index 000000000..98d354e8a --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/AttributeProviderFactory.java @@ -0,0 +1,57 @@ +package at.gv.egovernment.moa.id.protocols.stork2; + +import java.util.ArrayList; +import java.util.List; + +import at.gv.egovernment.moa.id.commons.db.dao.config.AttributeProviderPlugin; + +/** + * A factory for creating AttributeProvider objects. + */ +public class AttributeProviderFactory { + +	/** +	 * Gets the available plugins. +	 *  +	 * @return the available plugins +	 */ +	public static List<String> getAvailablePlugins() { +		List<String> result = new ArrayList<String>(); +		result.add("StorkAttributeRequestProvider"); + +		return result; +	} + +	/** +	 * Creates an AttributeProvider object for the given shortname. Returns +	 * {@code null} if there is no such provider available. +	 *  +	 * @param shortname +	 *            the simpleName for the providers class +	 * @return the attribute provider +	 */ +	public static AttributeProvider create(String shortname, String url) { +		switch (shortname) { +		case "StorkAttributeRequestProvider": +			return new StorkAttributeRequestProvider(url); +		default: +			return null; +		} +	} + +	/** +	 * Gets fresh instances of the configured plugins. +	 * +	 * @param configuredAPs the configured a ps +	 * @return the configured plugins +	 */ +	public static List<AttributeProvider> getConfiguredPlugins( +			List<AttributeProviderPlugin> configuredAPs) { +		 +		List<AttributeProvider> result = new ArrayList<AttributeProvider>(); +		for(AttributeProviderPlugin current : configuredAPs) +			result.add(create(current.getName(), current.getUrl())); +		 +		return result; +	} +} 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 446d942ab..d742d72ef 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 @@ -5,6 +5,7 @@ import at.gv.egovernment.moa.id.auth.exception.MOAIDException;  import at.gv.egovernment.moa.id.auth.stork.VelocityProvider;  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.logging.Logger;  import edu.emory.mathcs.backport.java.util.Collections;  import eu.stork.peps.auth.commons.*; @@ -15,12 +16,18 @@ import org.apache.velocity.Template;  import org.apache.velocity.VelocityContext;  import org.apache.velocity.app.VelocityEngine;  import org.apache.velocity.runtime.RuntimeConstants; - +import org.opensaml.xml.util.Base64; +import org.opensaml.xml.util.XMLHelper; +import javax.servlet.ServletOutputStream;  import javax.servlet.http.HttpServletRequest;  import javax.servlet.http.HttpServletResponse;  import javax.servlet.http.HttpSession; -import java.io.*; -import java.util.ArrayList; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStreamWriter; +import java.io.Writer; +import java.util.HashMap; +import eu.stork.peps.auth.engine.SAMLEngine;  /** @@ -90,6 +97,21 @@ public class AuthenticationRequest implements IAction {          //httpResp.setStatus(200);          //VPEPSInboundPostHandler +         +        // create fresh container +        DataContainer container = new DataContainer(); +         +        // - fill in the request we extracted above +        container.setRequest(request); +         +        // - fill in the partial response created above +        container.setResponse(response); +         +        // - memorize the target url were we have to return the result +        container.setTarget(target); +         +        // see if we need to fetch further attributes +        return (new AttributeCollector()).processRequest(container);          STORKAuthnResponse authnResponse = new STORKAuthnResponse(); @@ -244,7 +266,7 @@ public class AuthenticationRequest implements IAction {      //    moaAttributeProvider.populateAttribute(attributeList, "dateOfBirth"); -        return attributeList; +        return authResponse;      }      public String getDefaultActionName() { diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/DataContainer.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/DataContainer.java new file mode 100644 index 000000000..40c827ef8 --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/DataContainer.java @@ -0,0 +1,79 @@ +package at.gv.egovernment.moa.id.protocols.stork2; + +import java.io.Serializable; + +import eu.stork.peps.auth.commons.STORKAuthnRequest; +import eu.stork.peps.auth.commons.STORKAuthnResponse; + +// TODO: Auto-generated Javadoc +/** + * Holds info about an ongoing but yet incomplete stork authnrequest process. + */ +public class DataContainer implements Serializable { +	 +	/** The Constant serialVersionUID. */ +	private static final long serialVersionUID = -8765997480582363012L; + +	/** The incoming request. */ +	private STORKAuthnRequest request; +	 +	/** The yet incomplete response. */ +	private STORKAuthnResponse response; +	 +	/** The target. */ +	private String target; +	 +	/** +	 * Gets the request. +	 * +	 * @return the request +	 */ +	public STORKAuthnRequest getRequest() { +		return request; +	} + +	/** +	 * Sets the request. +	 * +	 * @param request the new request +	 */ +	public void setRequest(STORKAuthnRequest request) { +		this.request = request; +	} + +	/** +	 * Gets the response. +	 * +	 * @return the response +	 */ +	public STORKAuthnResponse getResponse() { +		return response; +	} + +	/** +	 * Sets the response. +	 * +	 * @param response the new response +	 */ +	public void setResponse(STORKAuthnResponse response) { +		this.response = response; +	} + +	/** +	 * Gets the target. +	 * +	 * @return the target +	 */ +	public String getTarget() { +		return target; +	} + +	/** +	 * Sets the target. +	 * +	 * @param target the new target +	 */ +	public void setTarget(String target) { +		this.target = target; +	} +} diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/DemoNoRedirectAttributeProvider.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/DemoNoRedirectAttributeProvider.java new file mode 100644 index 000000000..e6f340c77 --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/DemoNoRedirectAttributeProvider.java @@ -0,0 +1,48 @@ +package at.gv.egovernment.moa.id.protocols.stork2; + +import java.util.ArrayList; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import at.gv.egovernment.moa.id.config.auth.OAAuthParameter; + +import eu.stork.peps.auth.commons.IPersonalAttributeList; +import eu.stork.peps.auth.commons.PersonalAttribute; +import eu.stork.peps.auth.commons.PersonalAttributeList; + +/** + * Just a simple demoprovider who can fetch any attribute you ask him. + */ +public class DemoNoRedirectAttributeProvider implements AttributeProvider { + +	/* (non-Javadoc) +	 * @see at.gv.egovernment.moa.id.protocols.stork2.AttributeProvider#acquire(java.lang.String) +	 */ +	@Override +	public IPersonalAttributeList acquire(PersonalAttribute attributeName) +			throws UnsupportedAttributeException { +		PersonalAttributeList requestedAttributes = new PersonalAttributeList(1); +		requestedAttributes.add(new PersonalAttribute("sepp", true, new ArrayList<String>(), "")); +		return requestedAttributes; +	} + +	/* (non-Javadoc) +	 * @see at.gv.egovernment.moa.id.protocols.stork2.AttributeProvider#parse(javax.servlet.http.HttpServletRequest) +	 */ +	@Override +	public IPersonalAttributeList parse(HttpServletRequest httpReq) { +		// TODO Auto-generated method stub +		return null; +	} + +	/* (non-Javadoc) +	 * @see at.gv.egovernment.moa.id.protocols.stork2.AttributeProvider#performRedirect(java.lang.String, java.lang.String, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) +	 */ +	@Override +	public void performRedirect(String url, String citizenCountyCode, +			HttpServletRequest req, HttpServletResponse resp, OAAuthParameter oaParam) { +		// we should not get here +	} + +} diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/DemoRedirectAttributeProvider.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/DemoRedirectAttributeProvider.java new file mode 100644 index 000000000..5d4336149 --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/DemoRedirectAttributeProvider.java @@ -0,0 +1,48 @@ +package at.gv.egovernment.moa.id.protocols.stork2; + +import java.util.ArrayList; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import at.gv.egovernment.moa.id.config.auth.OAAuthParameter; + +import eu.stork.peps.auth.commons.IPersonalAttributeList; +import eu.stork.peps.auth.commons.PersonalAttribute; +import eu.stork.peps.auth.commons.PersonalAttributeList; + +/** + * Just a simple demoprovider who can fetch any attribute you ask him. + */ +public class DemoRedirectAttributeProvider implements AttributeProvider { + +	/* (non-Javadoc) +	 * @see at.gv.egovernment.moa.id.protocols.stork2.AttributeProvider#acquire(java.lang.String) +	 */ +	@Override +	public IPersonalAttributeList acquire(PersonalAttribute attributeName) +			throws UnsupportedAttributeException, ExternalAttributeRequestRequiredException { +		throw new ExternalAttributeRequestRequiredException(this); +	} + +	/* (non-Javadoc) +	 * @see at.gv.egovernment.moa.id.protocols.stork2.AttributeProvider#parse(javax.servlet.http.HttpServletRequest) +	 */ +	@Override +	public IPersonalAttributeList parse(HttpServletRequest httpReq) { +		PersonalAttributeList requestedAttributes = new PersonalAttributeList(1); +		requestedAttributes.add(new PersonalAttribute("sepp", true, new ArrayList<String>(), "")); +		return requestedAttributes; +	} + +	/* (non-Javadoc) +	 * @see at.gv.egovernment.moa.id.protocols.stork2.AttributeProvider#performRedirect(java.lang.String, java.lang.String, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) +	 */ +	@Override +	public void performRedirect(String url, String citizenCountyCode, +			HttpServletRequest req, HttpServletResponse resp, OAAuthParameter oaParam) { +		// we should not get here + +	} + +} diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/ExternalAttributeRequestRequiredException.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/ExternalAttributeRequestRequiredException.java new file mode 100644 index 000000000..29b09487b --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/ExternalAttributeRequestRequiredException.java @@ -0,0 +1,14 @@ +package at.gv.egovernment.moa.id.protocols.stork2; + +public class ExternalAttributeRequestRequiredException extends Exception { +	private AttributeProvider ap; + +	public ExternalAttributeRequestRequiredException(AttributeProvider provider) { +		ap = provider; +	} + +	public AttributeProvider getAp() { +		return ap; +	} + +} diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/STORKProtocol.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/STORKProtocol.java index 3d7852c4b..502925a2a 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/STORKProtocol.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/STORKProtocol.java @@ -34,12 +34,14 @@ public class STORKProtocol implements IModulInfo, MOAIDAuthConstants {      public static final String PATH = "id_stork2";      public static final String AUTHENTICATIONREQUEST = "AuthenticationRequest"; +	public static final String ATTRIBUTE_COLLECTOR = "AttributeCollector";      private static HashMap<String, IAction> actions = new HashMap<String, IAction>();      static {          actions.put(AUTHENTICATIONREQUEST, new AuthenticationRequest()); +        actions.put(ATTRIBUTE_COLLECTOR, new AttributeCollector());          instance = new STORKProtocol();      } diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/StorkAttributeRequestProvider.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/StorkAttributeRequestProvider.java new file mode 100644 index 000000000..3c689cac9 --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/StorkAttributeRequestProvider.java @@ -0,0 +1,147 @@ +package at.gv.egovernment.moa.id.protocols.stork2; + +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.auth.stork.VelocityProvider; +import at.gv.egovernment.moa.id.config.auth.OAAuthParameter; +import at.gv.egovernment.moa.id.util.HTTPUtils; +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.PersonalAttributeList; +import eu.stork.peps.auth.commons.STORKAttrQueryRequest; +import eu.stork.peps.auth.commons.STORKAttrQueryResponse; +import eu.stork.peps.auth.engine.STORKSAMLEngine; +import eu.stork.peps.exceptions.STORKSAMLEngineException; + +/** + * creates a STORK attribute request for a configurable set of attributes + */ +public class StorkAttributeRequestProvider implements AttributeProvider { + +	private PersonalAttributeList requestedAttributes; +	 +	/** The destination. */ +	private String destination; +	 +	/** +	 * Instantiates a new stork attribute request provider. +	 * +	 * @param apUrl the AP location +	 */ +	public StorkAttributeRequestProvider(String apUrl) { +		destination = apUrl; +	} + +	/* (non-Javadoc) +	 * @see at.gv.egovernment.moa.id.protocols.stork2.AttributeProvider#acquire(java.lang.String) +	 */ +	@Override +	public IPersonalAttributeList acquire(PersonalAttribute attribute) +			throws UnsupportedAttributeException, ExternalAttributeRequestRequiredException { +		requestedAttributes = new PersonalAttributeList(1); +		requestedAttributes.add(attribute); +		throw new ExternalAttributeRequestRequiredException(this); +	} + +	/* (non-Javadoc) +	 * @see at.gv.egovernment.moa.id.protocols.stork2.AttributeProvider#parse(javax.servlet.http.HttpServletRequest) +	 */ +	@Override +	public IPersonalAttributeList parse(HttpServletRequest httpReq) throws MOAIDException, UnsupportedAttributeException { +		Logger.debug("Beginning 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"); + +		STORKAttrQueryResponse attrResponse = null; +		try { +			//validate SAML Token +			Logger.debug("Starting validation of SAML response"); +			attrResponse = engine.validateSTORKAttrQueryResponse(decSamlToken, (String) httpReq.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); +		} +		 +		return attrResponse.getPersonalAttributeList(); +	} + +	/* (non-Javadoc) +	 * @see at.gv.egovernment.moa.id.protocols.stork2.AttributeProvider#performRedirect(java.lang.String) +	 */ +	@Override +	public void performRedirect(String url, String citizenCountryCode, HttpServletRequest req, HttpServletResponse resp, OAAuthParameter oaParam) throws MOAIDException { +		 +    	String spSector = "Business"; +    	String spInstitution = StringUtils.isEmpty(oaParam.getFriendlyName()) ? "UNKNOWN" : oaParam.getFriendlyName(); +    	String spApplication = spInstitution; +    	String spCountry = "AT"; + +    	//generate AuthnRquest +    	STORKAttrQueryRequest attributeRequest = new STORKAttrQueryRequest(); +    	attributeRequest.setDestination(destination); +    	attributeRequest.setAssertionConsumerServiceURL(url); +    	attributeRequest.setIssuer(HTTPUtils.getBaseURL(req)); +    	attributeRequest.setQaa(oaParam.getQaaLevel()); +    	attributeRequest.setSpInstitution(spInstitution); +    	attributeRequest.setCountry(spCountry); +    	attributeRequest.setSpApplication(spApplication); +    	attributeRequest.setSpSector(spSector); +    	attributeRequest.setPersonalAttributeList(requestedAttributes); + +    	attributeRequest.setCitizenCountryCode(citizenCountryCode); + + +    	Logger.debug("STORK AttrRequest succesfully assembled."); + +    	STORKSAMLEngine samlEngine = STORKSAMLEngine.getInstance("VIDP"); +    	try { +    		attributeRequest = samlEngine.generateSTORKAttrQueryRequest(attributeRequest); +    	} catch (STORKSAMLEngineException e) { +			Logger.error("Could not sign STORK SAML AttrRequest.", e); +			throw new MOAIDException("stork.00", null); +		} + +		Logger.info("STORK AttrRequest successfully signed!"); +		 +		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(attributeRequest.getTokenSaml())); +			context.put("action", destination); + +			StringWriter writer = new StringWriter(); +			template.merge(context, writer); + +			resp.getOutputStream().write(writer.toString().getBytes()); +		} catch (Exception e) { +			Logger.error("Error sending STORK SAML AttrRequest.", e); +			throw new MOAIDException("stork.11", null); +		} +	} + +} diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/UnsupportedAttributeException.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/UnsupportedAttributeException.java new file mode 100644 index 000000000..9447c079f --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/UnsupportedAttributeException.java @@ -0,0 +1,7 @@ +package at.gv.egovernment.moa.id.protocols.stork2; + +public class UnsupportedAttributeException extends Exception { + +	private static final long serialVersionUID = -7720066381435378111L; + +} diff --git a/id/server/idserverlib/src/main/resources/resources/properties/id_messages_de.properties b/id/server/idserverlib/src/main/resources/resources/properties/id_messages_de.properties index 2559d3d18..0e252e981 100644 --- a/id/server/idserverlib/src/main/resources/resources/properties/id_messages_de.properties +++ b/id/server/idserverlib/src/main/resources/resources/properties/id_messages_de.properties @@ -205,6 +205,8 @@ stork.07=Es existiert kein STORK AuthnRequest f\u00FCr diese STORK Response  stork.08=STORK SAML Assertion Validierung fehlgeschlagen
  stork.09=Fehler beim \u00FCberpr\u00FCfen der STORK B\u00FCrgerInnen Signatur
  stork.10=Fehler in der Verbindung zum SZR-Gateway
 +stork.11=Fehler beim Sammeln von StorkAttributen
 +stork.12=Konnte keine VIDP Konfiguration finden
  pvp2.00={0} ist kein gueltiger consumer service index
  pvp2.01=Fehler beim kodieren der PVP2 Antwort
 diff --git a/id/server/moa-id-commons/src/main/resources/config/moaid_config_2.0.xsd b/id/server/moa-id-commons/src/main/resources/config/moaid_config_2.0.xsd index e6705dbb8..d20ec1c68 100644 --- a/id/server/moa-id-commons/src/main/resources/config/moaid_config_2.0.xsd +++ b/id/server/moa-id-commons/src/main/resources/config/moaid_config_2.0.xsd @@ -49,7 +49,7 @@  			<xsd:extension base="xsd:string"/>  		</xsd:simpleContent>  	</xsd:complexType> -	<xsd:element name="AbstractSimpleIdentification" type="StorkAttribute"> +	<xsd:element name="AbstractSimpleIdentification" type="AttributeProviderPlugin">  		<xsd:annotation>  			<xsd:documentation>possibility to include common austrian primary  				keys in human readable way, english translation not available @@ -884,6 +884,8 @@  				<xsd:element name="StorkLogonEnabled" type="xsd:boolean"/>  				<xsd:element ref="Qaa" minOccurs="0" maxOccurs="1"/>  				<xsd:element ref="OAAttributes" minOccurs="0" maxOccurs="unbounded"/> +				<xsd:element name="VidpEnabled" type="xsd:boolean"></xsd:element> +				<xsd:element ref="AttributeProviders" maxOccurs="unbounded" minOccurs="0"></xsd:element>  			</xsd:sequence>  		</xsd:complexType>  	</xsd:element> @@ -950,6 +952,15 @@  			<xsd:element name="OnlyMandateLoginAllowed" type="xsd:boolean" default="false" minOccurs="0" maxOccurs="1"/>  		</xsd:sequence>  	</xsd:complexType> + +    	<xsd:complexType name="AttributeProviderPlugin"> +    		<xsd:sequence> +    			<xsd:element name="name" type="xsd:string"></xsd:element> +    			<xsd:element name="url" type="xsd:anyURI"></xsd:element> + 		</xsd:sequence> +	</xsd:complexType> +     +	<xsd:element name="AttributeProviders" type="AttributeProviderPlugin"></xsd:element>  	<xsd:element name="Attributes" type="StorkAttribute"/>  	<xsd:element name="Qaa" type="QualityAuthenticationAssuranceLevelType"/>  	<xsd:complexType name="OAStorkAttribute"> | 
