diff options
author | Thomas Lenz <tlenz@iaik.tugraz.at> | 2016-04-08 07:50:20 +0200 |
---|---|---|
committer | Thomas Lenz <tlenz@iaik.tugraz.at> | 2016-04-08 07:50:20 +0200 |
commit | 50c500dd107d88988cbee8207c91a16b321d6136 (patch) | |
tree | 6abd06e3f126866534e155e40c2f7e933b5357d3 /id/server/modules/moa-id-modules-saml1/src | |
parent | ec62813f4c0e8b3002d46f7bc315e7a27d720125 (diff) | |
parent | 41882a0c5601dda478c2749ac99c2087b864c912 (diff) | |
download | moa-id-spss-50c500dd107d88988cbee8207c91a16b321d6136.tar.gz moa-id-spss-50c500dd107d88988cbee8207c91a16b321d6136.tar.bz2 moa-id-spss-50c500dd107d88988cbee8207c91a16b321d6136.zip |
Merge tag 'MOA-ID-3.1.0' into development_preview
JoinUp Release
Diffstat (limited to 'id/server/modules/moa-id-modules-saml1/src')
12 files changed, 1361 insertions, 414 deletions
diff --git a/id/server/modules/moa-id-modules-saml1/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/GetArtifactAction.java b/id/server/modules/moa-id-modules-saml1/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/GetArtifactAction.java index d4e73690f..c421bf8cc 100644 --- a/id/server/modules/moa-id-modules-saml1/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/GetArtifactAction.java +++ b/id/server/modules/moa-id-modules-saml1/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/GetArtifactAction.java @@ -27,22 +27,29 @@ import java.util.List; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import at.gv.egovernment.moa.id.auth.MOAIDAuthConstants; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import at.gv.egovernment.moa.id.auth.data.AuthenticationSessionStorageConstants; import at.gv.egovernment.moa.id.auth.data.ExtendedSAMLAttribute; import at.gv.egovernment.moa.id.auth.exception.AuthenticationException; import at.gv.egovernment.moa.id.auth.servlet.RedirectServlet; -import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProviderFactory; -import at.gv.egovernment.moa.id.config.auth.OAAuthParameter; +import at.gv.egovernment.moa.id.commons.MOAIDAuthConstants; +import at.gv.egovernment.moa.id.commons.api.IOAAuthParameters; +import at.gv.egovernment.moa.id.commons.api.IRequest; import at.gv.egovernment.moa.id.data.IAuthData; 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.logging.Logger; import at.gv.egovernment.moa.util.URLEncoder; +import eu.eidas.auth.commons.IPersonalAttributeList; +@Service("SAML1_GetArtifactAction") public class GetArtifactAction implements IAction { + @Autowired private SAML1AuthenticationServer saml1server; + public SLOInformationInterface processRequest(IRequest req, HttpServletRequest httpReq, HttpServletResponse httpResp, IAuthData obj) throws AuthenticationException { @@ -65,14 +72,14 @@ public class GetArtifactAction implements IAction { } try { - OAAuthParameter oaParam = AuthConfigurationProviderFactory.getInstance() - .getOnlineApplicationParameter(oaURL); - - SAML1AuthenticationServer saml1server = SAML1AuthenticationServer.getInstace(); - + IOAAuthParameters oaParam = req.getOnlineApplicationConfiguration(); + // add other stork attributes to MOA assertion if available - if(null != authData.getStorkAttributes()) { - List<ExtendedSAMLAttribute> moaExtendedSAMLAttibutes = SAML1AuthenticationServer.addAdditionalSTORKAttributes(authData.getStorkAttributes()); + IPersonalAttributeList storkAttributes = authData.getGenericData( + AuthenticationSessionStorageConstants.STORK_ATTRIBUTELIST, + IPersonalAttributeList.class); + if(null != storkAttributes) { + List<ExtendedSAMLAttribute> moaExtendedSAMLAttibutes = saml1server.addAdditionalSTORKAttributes(storkAttributes); authData.getExtendedSAMLAttributesOA().addAll(moaExtendedSAMLAttibutes); Logger.info("MOA assertion assembled and SAML Artifact generated."); } @@ -83,7 +90,8 @@ public class GetArtifactAction implements IAction { String url = req.getAuthURL() + "/RedirectServlet"; url = addURLParameter(url, RedirectServlet.REDIRCT_PARAM_URL, URLEncoder.encode(oaURL, "UTF-8")); if (!oaParam.getBusinessService()) - url = addURLParameter(url, MOAIDAuthConstants.PARAM_TARGET, URLEncoder.encode(req.getTarget(), "UTF-8")); + url = addURLParameter(url, MOAIDAuthConstants.PARAM_TARGET, + URLEncoder.encode(req.getGenericData(SAML1Protocol.REQ_DATA_TARGET, String.class), "UTF-8")); url = addURLParameter(url, MOAIDAuthConstants.PARAM_SAMLARTIFACT, URLEncoder.encode(samlArtifactBase64, "UTF-8")); url = httpResp.encodeRedirectURL(url); @@ -95,7 +103,7 @@ public class GetArtifactAction implements IAction { String redirectURL = oaURL; if (!oaParam.getBusinessService()) { redirectURL = addURLParameter(redirectURL, MOAIDAuthConstants.PARAM_TARGET, - URLEncoder.encode(req.getTarget(), "UTF-8")); + URLEncoder.encode(req.getGenericData(SAML1Protocol.REQ_DATA_TARGET, String.class), "UTF-8")); } @@ -109,7 +117,7 @@ public class GetArtifactAction implements IAction { } SLOInformationInterface sloInformation = - new SLOInformationImpl(req.getAuthURL(), authData.getAssertionID(), null, null, req.requestedModule()); + new SLOInformationImpl(req.getAuthURL(), oaParam.getPublicURLPrefix(), authData.getAssertionID(), null, null, req.requestedModule()); return sloInformation; diff --git a/id/server/modules/moa-id-modules-saml1/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/GetAuthenticationDataService.java b/id/server/modules/moa-id-modules-saml1/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/GetAuthenticationDataService.java index 2b4aaf458..b01ea666d 100644 --- a/id/server/modules/moa-id-modules-saml1/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/GetAuthenticationDataService.java +++ b/id/server/modules/moa-id-modules-saml1/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/GetAuthenticationDataService.java @@ -46,19 +46,39 @@ package at.gv.egovernment.moa.id.protocols.saml1; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.StringWriter; import java.util.Calendar; -import org.apache.axis.AxisFault; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.TransformerException; + import org.apache.commons.lang3.StringEscapeUtils; +import org.apache.velocity.VelocityContext; +import org.apache.velocity.app.VelocityEngine; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; import org.w3c.dom.Element; import org.w3c.dom.NodeList; +import org.xml.sax.SAXException; import at.gv.egovernment.moa.id.auth.builder.SAMLResponseBuilder; import at.gv.egovernment.moa.id.auth.exception.AuthenticationException; -import at.gv.egovernment.moa.id.auth.exception.MOAIDException; +import at.gv.egovernment.moa.id.auth.frontend.velocity.VelocityProvider; +import at.gv.egovernment.moa.id.auth.servlet.AbstractController; +import at.gv.egovernment.moa.id.commons.api.exceptions.MOAIDException; +import at.gv.egovernment.moa.id.commons.utils.MOAIDMessageProvider; import at.gv.egovernment.moa.id.util.ErrorResponseUtils; -import at.gv.egovernment.moa.id.util.MOAIDMessageProvider; +import at.gv.egovernment.moa.id.util.HTTPUtils; import at.gv.egovernment.moa.id.util.Random; +import at.gv.egovernment.moa.logging.Logger; import at.gv.egovernment.moa.util.Constants; import at.gv.egovernment.moa.util.DOMUtils; import at.gv.egovernment.moa.util.DateTimeUtils; @@ -67,147 +87,262 @@ import at.gv.egovernment.moa.util.XPathUtils; /** * Web service for picking up authentication data created in the MOA-ID Auth component. * - * @author Paul Ivancsics - * @version $Id: GetAuthenticationDataService.java 1233 2012-01-26 21:59:33Z kstranacher $ - * @see at.gv.egovernment.moa.id.auth.AuthenticationServer#getAuthenticationData + * This getAssertion WebService implementations a hacked solution to integrate SAML1 into + * the new Spring based MOA-ID implementation. + * + * @deprecated + * It is too bad about the time to implement a better solution, + * since SAML1 is deprecated MOA-ID >= 2.0.0 + * + * @author tlenz */ -public class GetAuthenticationDataService implements Constants { +@Controller +public class GetAuthenticationDataService extends AbstractController implements Constants { - /** - * Constructor for GetAuthenticationDataService. - */ - public GetAuthenticationDataService() { - super(); - } + @Autowired private SAML1AuthenticationServer saml1AuthServer; + + private static final String PARAM_WSDL="wsdl"; + private static final String PARAM_XSD="xsd"; + + private static final String TEMPLATE_PLAIN_INFO="plain_info.vm"; + private static final String TEMPLATE_WSDL="wsdl/MOA-ID-1.x.vm"; + private static final String TEMPLATE_XSD="wsdl/MOA-SPSS-1.2.vm"; + private static final String TEMPLATE_SOAP_ERROR="soap_error.vm"; + private static final String TEMPLATE_SOAP_SUCCESS="soap_success.vm"; + + private static final String SERVICE_ENDPOINT = "/services/GetAuthenticationData"; + + private static final String CONTEXT_ENDPOINT = "endpoint"; + private static final String CONTEXT_ERROR = "error"; + + private static final String CONTEXT_SOAP_RESPONSEID = "responseID"; + private static final String CONTEXT_SOAP_REQUESTEID = "requestID"; + private static final String CONTEXT_SOAP_ISSUEINSTANT = "issueInstant"; + private static final String CONTEXT_SOAP_ERRORMESSAGE = "errorMsg"; + private static final String CONTEXT_SOAP_STATUSCODE = "statusCode"; + private static final String CONTEXT_SOAP_ASSERTION = "assertion"; + + @RequestMapping(value = "/services/GetAuthenticationData", method = {RequestMethod.POST}) + public void getAuthenticationData(HttpServletRequest req, HttpServletResponse resp) + throws IOException { + InputStream is = null; + VelocityContext context = new VelocityContext(); + try { + is = req.getInputStream(); + Element soapReq = DOMUtils.parseXmlNonValidating(is); - /** - * Takes a <code>lt;samlp:Request></code> containing a - * <code>SAML artifact</code> and returns the corresponding - * authentication data <code>lt;saml:Assertion></code> - * (obtained from the <code>AuthenticationServer</code>), - * enclosed in a <code>lt;samlp:Response></code>. - * <br/>Bad requests are mapped into various <code>lt;samlp:StatusCode></code>s, - * possibly containing enclosed sub-<code>lt;samlp:StatusCode></code>s. - * The status codes are defined in the SAML specification. - * - * @param requests request elements of type <code>lt;samlp:Request></code>; - * only 1 request element is allowed - * @return response element of type <code>lt;samlp:Response></code>, - * packed into an <code>Element[]</code> - * @throws AxisFault thrown when an error occurs in assembling the - * <code>lt;samlp:Response></code> - */ - public Element[] Request(Element[] requests) - throws AxisFault { - - Element request = requests[0]; - Element[] responses = new Element[1]; + //process request + Element soapResp = processRequest(soapReq); + + String respString = DOMUtils.serializeNode(soapResp, true); + + resp.setContentType("text/xml;charset=UTF-8"); + context.put(CONTEXT_SOAP_ASSERTION, respString); + evaluateTemplate(context, resp, TEMPLATE_SOAP_SUCCESS); + + } catch (ParserConfigurationException | SAXException | IOException | TransformerException e) { + Logger.error("SAML1 GetAuthenticationData receive a non-valid request.", e); + resp.setContentType("text/xml;charset=UTF-8"); + + context.put(CONTEXT_SOAP_ISSUEINSTANT, DateTimeUtils.buildDateTimeUTC(Calendar.getInstance())); + context.put(CONTEXT_SOAP_RESPONSEID, Random.nextRandom()); + context.put(CONTEXT_SOAP_STATUSCODE, "samlp:Requester"); + context.put(CONTEXT_SOAP_ERRORMESSAGE, e.getMessage()); + + evaluateTemplate(context, resp, TEMPLATE_SOAP_ERROR); + + } catch (SAML1AssertionResponseBuildException e) { + Logger.error("SAML1 GetAuthenticationData response build failed..", e); + resp.setContentType("text/xml;charset=UTF-8"); + + context.put(CONTEXT_SOAP_ISSUEINSTANT, e.getIssueInstant()); + context.put(CONTEXT_SOAP_REQUESTEID, e.getRequestID()); + context.put(CONTEXT_SOAP_RESPONSEID, e.getResponseID()); + context.put(CONTEXT_SOAP_STATUSCODE, "samlp:Responder"); + context.put(CONTEXT_SOAP_ERRORMESSAGE, e.getMessage()); + + evaluateTemplate(context, resp, TEMPLATE_SOAP_ERROR); + + } finally { + try { + if (is != null) + is.close(); + + } catch (Exception e) { + + } + } + } + + @RequestMapping(value = "/services/GetAuthenticationData", method = {RequestMethod.GET}) + public void getAuthenticationDataWSDL(HttpServletRequest req, HttpServletResponse resp) + throws Exception { + String wsdl_param = req.getParameter(PARAM_WSDL); + String xsd_param = req.getParameter(PARAM_XSD); + + String fullServiceEndPoint = HTTPUtils.extractAuthURLFromRequest(req) + SERVICE_ENDPOINT; + + VelocityContext context = new VelocityContext(); + context.put(CONTEXT_ENDPOINT, fullServiceEndPoint); + + if (wsdl_param != null) { + //print wsdl + resp.setContentType("text/xml;charset=UTF-8"); + evaluateTemplate(context, resp, TEMPLATE_WSDL); + + } else if (xsd_param != null){ + //print xsd + resp.setContentType("text/xml;charset=UTF-8"); + evaluateTemplate(context, resp, TEMPLATE_XSD); + + } else { + //print plain info + resp.setContentType("text/html;charset=UTF-8"); + evaluateTemplate(context, resp, TEMPLATE_PLAIN_INFO); + + } + + } + + private Element processRequest(Element soapReq) throws ParserConfigurationException, IOException, SAXException, TransformerException, SAML1AssertionResponseBuildException { String requestID = ""; String statusCode = ""; String subStatusCode = null; String statusMessageCode = null; String statusMessage = null; String samlAssertion = ""; - if (requests.length > 1) { - // more than 1 request given as parameter - statusCode = "samlp:Requester"; - subStatusCode = "samlp:TooManyResponses"; - statusMessageCode = "1201"; - } + Element responses; + + //select soap-body element + NodeList saml1ReqList = soapReq.getElementsByTagNameNS(soapReq.getNamespaceURI(), "Body");; + if (saml1ReqList.getLength() != 1) { + saml1ReqList = soapReq.getElementsByTagNameNS(soapReq.getNamespaceURI(), "body");; + if (saml1ReqList.getLength() != 1) { + throw new SAXException("No unique 'soap-env:Body' element."); + + } + } + + //get first child from body --> should be the SAML1 Request element + Element saml1Req; + if (saml1ReqList.item(0).getFirstChild() instanceof Element) + saml1Req = (Element) saml1ReqList.item(0).getFirstChild(); + else { - try { - DOMUtils.validateElement(request, ALL_SCHEMA_LOCATIONS, null); - NodeList samlArtifactList = XPathUtils.selectNodeList(request, "samlp:AssertionArtifact"); - if (samlArtifactList.getLength() == 0) { - // no SAML artifact given in request - statusCode = "samlp:Requester"; - statusMessageCode = "1202"; - } - else if (samlArtifactList.getLength() > 1) { - // too many SAML artifacts given in request - statusCode = "samlp:Requester"; - subStatusCode = "samlp:TooManyResponses"; - statusMessageCode = "1203"; - } + throw new SAXException("First child of 'soap-env:Body' element has a wrong type."); - else { - Element samlArtifactElem = (Element)samlArtifactList.item(0); - requestID = request.getAttribute("RequestID"); - String samlArtifact = DOMUtils.getText(samlArtifactElem); - SAML1AuthenticationServer saml1server = SAML1AuthenticationServer.getInstace(); + } + + //validate the SAML1 request element, which we selected above + DOMUtils.validateElement(saml1Req, ALL_SCHEMA_LOCATIONS, null); + + //parse inforamtion from SAML1 request + try { + NodeList samlArtifactList = XPathUtils.selectNodeList(saml1Req, "samlp:AssertionArtifact"); + if (samlArtifactList.getLength() == 0) { + // no SAML artifact given in request + statusCode = "samlp:Requester"; + statusMessageCode = "1202"; + + } else if (samlArtifactList.getLength() > 1) { + // too many SAML artifacts given in request + statusCode = "samlp:Requester"; + subStatusCode = "samlp:TooManyResponses"; + statusMessageCode = "1203"; + + } else { + Element samlArtifactElem = (Element)samlArtifactList.item(0); + requestID = saml1Req.getAttribute("RequestID"); + String samlArtifact = DOMUtils.getText(samlArtifactElem); + + try { + samlAssertion = saml1AuthServer.getSaml1AuthenticationData(samlArtifact); + + // success + statusCode = "samlp:Success"; + statusMessageCode = "1200"; + } catch (ClassCastException ex) { try { + Throwable error = saml1AuthServer.getErrorResponse(samlArtifact); + statusCode = "samlp:Responder"; + + ErrorResponseUtils errorUtils = ErrorResponseUtils.getInstance(); + + if (error instanceof MOAIDException) { + statusMessageCode = ((MOAIDException)error).getMessageId(); + statusMessage = StringEscapeUtils.escapeXml(((MOAIDException)error).getMessage()); - samlAssertion = saml1server.getSaml1AuthenticationData(samlArtifact); - - // success - statusCode = "samlp:Success"; - statusMessageCode = "1200"; - } - - catch (ClassCastException ex) { - - try { - Throwable error = saml1server.getErrorResponse(samlArtifact); - statusCode = "samlp:Responder"; - - ErrorResponseUtils errorUtils = ErrorResponseUtils.getInstance(); + } else { + statusMessage = StringEscapeUtils.escapeXml(error.getMessage()); - if (error instanceof MOAIDException) { - statusMessageCode = ((MOAIDException)error).getMessageId(); - statusMessage = StringEscapeUtils.escapeXml(((MOAIDException)error).getMessage()); - - } else { - statusMessage = StringEscapeUtils.escapeXml(error.getMessage()); - } - subStatusCode = errorUtils.getResponseErrorCode(error); - - } catch (Exception e) { - //no authentication data for given SAML artifact - statusCode = "samlp:Requester"; - subStatusCode = "samlp:ResourceNotRecognized"; - statusMessage = ex.toString(); - } - - } - - catch (AuthenticationException ex) { + } + subStatusCode = errorUtils.getResponseErrorCode(error); + + } catch (Exception e) { //no authentication data for given SAML artifact statusCode = "samlp:Requester"; subStatusCode = "samlp:ResourceNotRecognized"; statusMessage = ex.toString(); } + + } catch (AuthenticationException ex) { + //no authentication data for given SAML artifact + statusCode = "samlp:Requester"; + subStatusCode = "samlp:ResourceNotRecognized"; + statusMessage = ex.toString(); } } - catch (Throwable t) { - // invalid request format - statusCode = "samlp:Requester"; - statusMessageCode = "1204"; - } + + + } catch (Throwable t) { + // invalid request format + statusCode = "samlp:Requester"; + statusMessageCode = "1204"; + + } + + String responseID = Random.nextRandom(); + String issueInstant = DateTimeUtils.buildDateTimeUTC(Calendar.getInstance()); + + try { + if (statusMessage == null) + statusMessage = MOAIDMessageProvider.getInstance().getMessage(statusMessageCode, null); + responses = new SAMLResponseBuilder().build( + responseID, requestID, issueInstant, statusCode, subStatusCode, statusMessage, samlAssertion); + return responses; + + } catch (Throwable e) { + throw new SAML1AssertionResponseBuildException(responseID, issueInstant, + requestID, "1299", e.getMessage(), e); + + } } + + + private void evaluateTemplate(VelocityContext context, HttpServletResponse httpResp, String templateURL) throws IOException { + InputStream is = null; + try { + is = Thread.currentThread() + .getContextClassLoader() + .getResourceAsStream(templateURL); + + VelocityEngine engine = VelocityProvider.getClassPathVelocityEngine(); + BufferedReader reader = new BufferedReader(new InputStreamReader(is )); + StringWriter writer = new StringWriter(); + engine.evaluate(context, writer, "SAML1 GetAuthenticationData", reader); + httpResp.getOutputStream().write(writer.toString().getBytes("UTF-8")); + + } catch (Exception e) { + Logger.error("SAML1 GetAuthenticationData has an error:", e); + throw new IOException(e); + + } finally { + if (is != null) + is.close(); + + } - try { - String responseID = Random.nextRandom(); - String issueInstant = DateTimeUtils.buildDateTimeUTC(Calendar.getInstance()); - - if (statusMessage == null) - statusMessage = MOAIDMessageProvider.getInstance().getMessage(statusMessageCode, null); - responses[0] = new SAMLResponseBuilder().build( - responseID, requestID, issueInstant, statusCode, subStatusCode, statusMessage, samlAssertion); - - } - catch (MOAIDException e) { - AxisFault fault = AxisFault.makeFault(e); - fault.setFaultDetail(new Element[] { e.toErrorResponse()}); - throw fault; - } - catch (Throwable t) { - MOAIDException e = new MOAIDException("1299", null, t); - AxisFault fault = AxisFault.makeFault(e); - fault.setFaultDetail(new Element[] { e.toErrorResponse()}); - throw fault; - } - return responses; - } - + } } + diff --git a/id/server/modules/moa-id-modules-saml1/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/SAML1AssertionResponseBuildException.java b/id/server/modules/moa-id-modules-saml1/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/SAML1AssertionResponseBuildException.java new file mode 100644 index 000000000..0c06a94df --- /dev/null +++ b/id/server/modules/moa-id-modules-saml1/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/SAML1AssertionResponseBuildException.java @@ -0,0 +1,86 @@ +/* + * 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.saml1; + +/** + * @author tlenz + * + */ +public class SAML1AssertionResponseBuildException extends Exception { + + private static final long serialVersionUID = -394698807368683821L; + + private String responseID; + private String issueInstant; + private String requestID; + private String errorCode; + + /** + * @param responseID + * @param issueInstant + * @param requestID + * @param string + * @param message + */ + public SAML1AssertionResponseBuildException(String responseID, String issueInstant, String requestID, String errorCode, + String errorMsg, Throwable throwable) { + super(errorMsg, throwable); + + this.requestID = requestID; + this.issueInstant = issueInstant; + this.responseID = responseID; + this.errorCode = errorCode; + } + + /** + * @return the responseID + */ + public String getResponseID() { + return responseID; + } + + /** + * @return the issueInstant + */ + public String getIssueInstant() { + return issueInstant; + } + + /** + * @return the requestID + */ + public String getRequestID() { + return requestID; + } + + /** + * @return the errorCode + */ + public String getErrorCode() { + return errorCode; + } + + + + +} diff --git a/id/server/modules/moa-id-modules-saml1/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/SAML1AuthenticationServer.java b/id/server/modules/moa-id-modules-saml1/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/SAML1AuthenticationServer.java index eb869756e..0ec0d95a2 100644 --- a/id/server/modules/moa-id-modules-saml1/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/SAML1AuthenticationServer.java +++ b/id/server/modules/moa-id-modules-saml1/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/SAML1AuthenticationServer.java @@ -26,21 +26,25 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.List; import java.util.Vector; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBElement; +import javax.xml.bind.JAXBException; import javax.xml.bind.Marshaller; import javax.xml.namespace.QName; import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.TransformerException; import org.apache.commons.lang3.StringEscapeUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; import org.w3c.dom.Element; import org.xml.sax.SAXException; -import eu.stork.peps.auth.commons.IPersonalAttributeList; -import eu.stork.peps.auth.commons.PersonalAttribute; - +import at.gv.e_government.reference.namespace.mandates._20040701_.Mandate; +import at.gv.e_government.reference.namespace.mandates._20040701_.Mandator; import at.gv.egovernment.moa.id.auth.AuthenticationServer; import at.gv.egovernment.moa.id.auth.builder.AuthenticationDataAssertionBuilder; import at.gv.egovernment.moa.id.auth.builder.BPKBuilder; @@ -49,7 +53,6 @@ import at.gv.egovernment.moa.id.auth.builder.SAMLArtifactBuilder; import at.gv.egovernment.moa.id.auth.data.AuthenticationSession; import at.gv.egovernment.moa.id.auth.data.ExtendedSAMLAttribute; import at.gv.egovernment.moa.id.auth.data.ExtendedSAMLAttributeImpl; -import at.gv.egovernment.moa.id.auth.data.IdentityLink; import at.gv.egovernment.moa.id.auth.exception.AuthenticationException; import at.gv.egovernment.moa.id.auth.exception.BuildException; import at.gv.egovernment.moa.id.auth.exception.ParseException; @@ -57,14 +60,16 @@ import at.gv.egovernment.moa.id.auth.exception.ServiceException; import at.gv.egovernment.moa.id.auth.exception.ValidateException; import at.gv.egovernment.moa.id.auth.parser.SAMLArtifactParser; import at.gv.egovernment.moa.id.auth.validator.parep.ParepUtils; +import at.gv.egovernment.moa.id.commons.MOAIDAuthConstants; +import at.gv.egovernment.moa.id.commons.api.IOAAuthParameters; +import at.gv.egovernment.moa.id.commons.api.IRequest; +import at.gv.egovernment.moa.id.commons.api.data.SAML1ConfigurationParameters; +import at.gv.egovernment.moa.id.commons.api.exceptions.ConfigurationException; import at.gv.egovernment.moa.id.commons.db.ex.MOADatabaseException; -import at.gv.egovernment.moa.id.config.ConfigurationException; -import at.gv.egovernment.moa.id.config.auth.OAAuthParameter; -import at.gv.egovernment.moa.id.config.auth.data.SAML1ConfigurationParameters; import at.gv.egovernment.moa.id.data.AuthenticationData; -import at.gv.egovernment.moa.id.moduls.IRequest; -import at.gv.egovernment.moa.id.storage.AssertionStorage; -//import at.gv.egovernment.moa.id.util.IdentityLinkReSigner; +import at.gv.egovernment.moa.id.data.IAuthData; +import at.gv.egovernment.moa.id.protocols.pvp2x.PVPConstants; +import at.gv.egovernment.moa.id.storage.ITransactionStorage; import at.gv.egovernment.moa.id.util.Random; import at.gv.egovernment.moa.logging.Logger; import at.gv.egovernment.moa.util.Base64Utils; @@ -77,20 +82,14 @@ import at.gv.util.xsd.persondata.IdentificationType.Value; import at.gv.util.xsd.persondata.PersonNameType; import at.gv.util.xsd.persondata.PersonNameType.FamilyName; import at.gv.util.xsd.persondata.PhysicalPersonType; +import eu.eidas.auth.commons.IPersonalAttributeList; +import eu.eidas.auth.commons.PersonalAttribute; +//import at.gv.egovernment.moa.id.util.IdentityLinkReSigner; +@Service("SAML1AuthenticationServer") public class SAML1AuthenticationServer extends AuthenticationServer { - - private static SAML1AuthenticationServer instance; - - public static SAML1AuthenticationServer getInstace() { - if (instance == null) - instance = new SAML1AuthenticationServer(); - return instance; - } - - private static AssertionStorage authenticationDataStore = AssertionStorage.getInstance(); - + @Autowired private ITransactionStorage authenticationDataStore; /** * time out in milliseconds used by {@link cleanup} for authentication data @@ -108,20 +107,23 @@ public class SAML1AuthenticationServer extends AuthenticationServer { samlArtifact, ex.toString() }); } Throwable error = null; - synchronized (authenticationDataStore) { - try { - error = authenticationDataStore - .get(samlArtifact, Throwable.class); + try { + error = authenticationDataStore + .get(samlArtifact, Throwable.class); - authenticationDataStore.remove(samlArtifact); - - } catch (MOADatabaseException e) { + if (error == null) { Logger.error("Assertion not found for SAML Artifact: " + samlArtifact); throw new AuthenticationException("1206", new Object[] { samlArtifact }); + } - + + authenticationDataStore.remove(samlArtifact); + + } catch (MOADatabaseException e) { + Logger.error("Assertion not found for SAML Artifact: " + samlArtifact); + throw new AuthenticationException("1206", new Object[] { samlArtifact }); } - + return error; } @@ -130,7 +132,7 @@ public class SAML1AuthenticationServer extends AuthenticationServer { * @param iPersonalAttributeList STORK attribute list * @return */ - public static List<ExtendedSAMLAttribute> addAdditionalSTORKAttributes(IPersonalAttributeList iPersonalAttributeList) { + public List<ExtendedSAMLAttribute> addAdditionalSTORKAttributes(IPersonalAttributeList iPersonalAttributeList) { List<ExtendedSAMLAttribute> moaExtendedSAMLAttributeList = new Vector<ExtendedSAMLAttribute>(); if(null == iPersonalAttributeList) @@ -178,22 +180,24 @@ public class SAML1AuthenticationServer extends AuthenticationServer { throw new AuthenticationException("1205", new Object[] { samlArtifact, ex.toString() }); } - String authData = null; - synchronized (authenticationDataStore) { - // System.out.println("assertionHandle: " + assertionHandle); - - try { - authData = authenticationDataStore - .get(samlArtifact, String.class, authDataTimeOut); + String authData = null; + try { + authData = authenticationDataStore + .get(samlArtifact, String.class, authDataTimeOut); - } catch (MOADatabaseException e) { + if (authData == null) { Logger.error("Assertion not found for SAML Artifact: " + samlArtifact); throw new AuthenticationException("1206", new Object[] { samlArtifact }); - } - } + + } - authenticationDataStore.remove(samlArtifact); + } catch (MOADatabaseException e) { + Logger.error("Assertion not found for SAML Artifact: " + samlArtifact); + throw new AuthenticationException("1206", new Object[] { samlArtifact }); + } + + authenticationDataStore.remove(samlArtifact); Logger.debug("Assertion delivered for SAML Artifact: " + samlArtifact); return authData; @@ -211,7 +215,7 @@ public class SAML1AuthenticationServer extends AuthenticationServer { return samlArtifact; } - public String BuildSAMLArtifact(OAAuthParameter oaParam, + public String BuildSAMLArtifact(IOAAuthParameters oaParam, SAML1AuthenticationData authData, String sourceID) throws ConfigurationException, BuildException, AuthenticationException { @@ -265,15 +269,20 @@ public class SAML1AuthenticationServer extends AuthenticationServer { person.getIdentification().add(id ); Value value = new Value(); id.setValue(value ); - - id.setType(authData.getIdentificationType()); - //add baseID if it is requested and available - if ( MiscUtil.isNotEmpty(authData.getIdentificationValue()) && - saml1parameter.isProvideIdentityLink() ) + + if ( MiscUtil.isNotEmpty(authData.getIdentificationValue()) && + saml1parameter.isProvideIdentityLink() && !authData.isBusinessService()) { + //add baseID if it is requested and available and SP is publicService value.setValue(authData.getIdentificationValue()); - else - value.setValue(""); - + id.setType(authData.getIdentificationType()); + + } else { + //otherwise add bPK + value.setValue(authData.getBPK()); + id.setType(authData.getBPKType()); + + } + familyName.setValue(authData.getFamilyName()); familyName.setPrimary("undefined"); name.getGivenName().add(authData.getGivenName()); @@ -313,14 +322,15 @@ public class SAML1AuthenticationServer extends AuthenticationServer { } - String samlAssertion; + String samlAssertion; + + //add mandate info's if (authData.isUseMandate()) { List<ExtendedSAMLAttribute> oaAttributes = authData.getExtendedSAMLAttributesOA(); - //only provide full mandate if it is included. - //In case of federation only a short mandate could be include + //only provide full mandate if it is included. if (saml1parameter.isProvideFullMandatorData() - && authData.getMISMandate().isFullMandateIncluded()) { + && authData.getMISMandate() != null) { try { @@ -436,7 +446,7 @@ public class SAML1AuthenticationServer extends AuthenticationServer { } - private String generateMandateDate(OAAuthParameter oaParam, AuthenticationData authData + private String generateMandateDate(IOAAuthParameters oaParam, AuthenticationData authData ) throws AuthenticationException, BuildException, ParseException, ConfigurationException, ServiceException, ValidateException { @@ -445,33 +455,36 @@ public class SAML1AuthenticationServer extends AuthenticationServer { throw new AuthenticationException("auth.10", new Object[] { REQ_VERIFY_AUTH_BLOCK, PARAM_SESSIONID }); - IdentityLink tempIdentityLink = null; - + Element prPerson = null; + String identificationType = ""; + String identificationValue = ""; + Element mandate = authData.getMandate(); + if (mandate == null) { + //no full-mandate include + Logger.info("AuthData contains no full-mandate. Starting 'mandateDate' generation from PVP attributes ..."); + mandate = generateMandateDateFromPVPMandateAttributes(authData); + + } - if (authData.isUseMandate()) { - tempIdentityLink = new IdentityLink(); + if (mandate != null) { Element mandator = ParepUtils.extractMandator(mandate); String dateOfBirth = ""; - Element prPerson = null; String familyName = ""; String givenName = ""; - String identificationType = ""; - String identificationValue = ""; if (mandator != null) { boolean physical = ParepUtils.isPhysicalPerson(mandator); if (physical) { - familyName = ParepUtils.extractText(mandator, - "descendant-or-self::pr:Name/pr:FamilyName/text()"); - givenName = ParepUtils.extractText(mandator, - "descendant-or-self::pr:Name/pr:GivenName/text()"); - dateOfBirth = ParepUtils - .extractMandatorDateOfBirth(mandator); + familyName = ParepUtils.extractText(mandator, "descendant-or-self::pr:Name/pr:FamilyName/text()"); + givenName = ParepUtils.extractText(mandator, "descendant-or-self::pr:Name/pr:GivenName/text()"); + dateOfBirth = ParepUtils.extractMandatorDateOfBirth(mandator); + } else { familyName = ParepUtils.extractMandatorFullName(mandator); + } - identificationType = ParepUtils.getIdentification(mandator, - "Type"); + + identificationType = ParepUtils.getIdentification(mandator, "Type"); identificationValue = ParepUtils.extractMandatorWbpk(mandator); prPerson = ParepUtils.extractPrPersonOfMandate(mandate); @@ -498,33 +511,19 @@ public class SAML1AuthenticationServer extends AuthenticationServer { ParepUtils .HideStammZahlen(prPerson, true, null, null, true); } - - tempIdentityLink.setDateOfBirth(dateOfBirth); - tempIdentityLink.setFamilyName(familyName); - tempIdentityLink.setGivenName(givenName); - tempIdentityLink.setIdentificationType(identificationType); - tempIdentityLink.setIdentificationValue(identificationValue); - tempIdentityLink.setPrPerson(prPerson); - try { - tempIdentityLink.setSamlAssertion(authData.getIdentityLink() - .getSamlAssertion()); - } catch (Exception e) { - throw new ValidateException("validator.64", null); - } - } - + } - - Element mandatePerson = tempIdentityLink.getPrPerson(); - - String mandateData = null; - try { + + if (prPerson == null) { + Logger.warn("Mandates are enabled, but no mandate-information is found in authData."); + throw new AuthenticationException("auth.16", new Object[] { "Mandates are enabled, but no mandate information is included" }); + } + + try { boolean provideStammzahl = oaParam.getSAML1Parameter().isProvideStammzahl(); - - String oatargetType; - + String oatargetType; if(oaParam.getBusinessService()) { if (oaParam.getIdentityLinkDomainIdentifier().startsWith(AuthenticationSession.REGISTERANDORDNR_PREFIX_)) oatargetType = oaParam.getIdentityLinkDomainIdentifier(); @@ -533,64 +532,166 @@ public class SAML1AuthenticationServer extends AuthenticationServer { } else { oatargetType = AuthenticationSession.TARGET_PREFIX_ + oaParam.getTarget(); + } - Element prIdentification = (Element) mandatePerson - .getElementsByTagNameNS(Constants.PD_NS_URI, - "Identification").item(0); + Element prIdentification = (Element) prPerson. + getElementsByTagNameNS(Constants.PD_NS_URI,"Identification").item(0); - if (!oatargetType.equals(tempIdentityLink.getIdentificationType())) { - - String isPrPerson = mandatePerson.getAttribute("xsi:type"); + if (!oatargetType.equals(identificationType)) { + String isPrPerson = prPerson.getAttribute("xsi:type"); if (!StringUtils.isEmpty(isPrPerson)) { if (isPrPerson.equalsIgnoreCase("pr:PhysicalPerson")) { - String baseid = getBaseId(mandatePerson); - Element identificationBpK = createIdentificationBPK(mandatePerson, - baseid, oaParam.getTarget()); - - if (!provideStammzahl) { - prIdentification.getFirstChild().setTextContent(""); + + String baseid = getBaseId(prPerson); + Element identificationBpK; + if (MiscUtil.isNotEmpty(baseid)) { + identificationBpK = createIdentificationBPK(prPerson, baseid, oaParam.getTarget()); + + if (!provideStammzahl) { + prIdentification.getFirstChild().setTextContent(""); + } + + prPerson.insertBefore(identificationBpK, + prIdentification); + + } else { + Logger.info("No baseID included. --> Build 'MandateDate' without baseID"); + } + + - mandatePerson.insertBefore(identificationBpK, - prIdentification); + } } } else { - -// Element identificationBpK = mandatePerson.getOwnerDocument() -// .createElementNS(Constants.PD_NS_URI, "Identification"); -// Element valueBpK = mandatePerson.getOwnerDocument().createElementNS( -// Constants.PD_NS_URI, "Value"); -// -// valueBpK.appendChild(mandatePerson.getOwnerDocument().createTextNode( -// tempIdentityLink.getIdentificationValue())); -// Element typeBpK = mandatePerson.getOwnerDocument().createElementNS( -// Constants.PD_NS_URI, "Type"); -// typeBpK.appendChild(mandatePerson.getOwnerDocument().createTextNode( -// "urn:publicid:gv.at:cdid+bpk")); -// identificationBpK.appendChild(valueBpK); -// identificationBpK.appendChild(typeBpK); -// -// mandatePerson.insertBefore(identificationBpK, prIdentification); + ; } - - mandateData = DOMUtils.serializeNode(mandatePerson); + return DOMUtils.serializeNode(prPerson); } catch (TransformerException e1) { - throw new AuthenticationException("auth.16", - new Object[] { GET_MIS_SESSIONID }); + throw new AuthenticationException("auth.16", new Object[] { GET_MIS_SESSIONID }); } catch (IOException e1) { - throw new AuthenticationException("auth.16", - new Object[] { GET_MIS_SESSIONID }); + throw new AuthenticationException("auth.16", new Object[] { GET_MIS_SESSIONID }); } - return mandateData; } + private Element generateMandateDateFromPVPMandateAttributes(IAuthData authdata) throws BuildException { + String legalSourcePin = authdata.getGenericData(PVPConstants.MANDATE_LEG_PER_SOURCE_PIN_NAME, String.class); + String legalSourceType = authdata.getGenericData(PVPConstants.MANDATE_LEG_PER_SOURCE_PIN_TYPE_NAME, String.class); + String legalCommonName = authdata.getGenericData(PVPConstants.MANDATE_LEG_PER_FULL_NAME_NAME, String.class); + + String natSourcePin = authdata.getGenericData(PVPConstants.MANDATE_NAT_PER_SOURCE_PIN_NAME, String.class); + String natSourcePinType = authdata.getGenericData(PVPConstants.MANDATE_NAT_PER_SOURCE_PIN_TYPE_NAME, String.class); + String natbPK = authdata.getGenericData(PVPConstants.MANDATE_NAT_PER_BPK_NAME, String.class); + + String natGivenName = authdata.getGenericData(PVPConstants.MANDATE_NAT_PER_GIVEN_NAME_NAME, String.class); + String natFamilyName = authdata.getGenericData(PVPConstants.MANDATE_NAT_PER_FAMILY_NAME_NAME, String.class); + String natDateOfBirth = authdata.getGenericData(PVPConstants.MANDATE_NAT_PER_BIRTHDATE_NAME, String.class); + + Mandate mandateObject = new Mandate(); + Mandator mandator = new Mandator(); + mandateObject.setMandator(mandator); + + if (MiscUtil.isNotEmpty(legalCommonName) && MiscUtil.isNotEmpty(legalSourceType) + && MiscUtil.isNotEmpty(legalSourcePin)) { + Logger.debug("Build 'mandateDate' element for legal person ..."); + at.gv.e_government.reference.namespace.persondata._20020228_.CorporateBodyType legalperson = + new at.gv.e_government.reference.namespace.persondata._20020228_.CorporateBodyType(); + at.gv.e_government.reference.namespace.persondata._20020228_.IdentificationType legalID = + new at.gv.e_government.reference.namespace.persondata._20020228_.IdentificationType(); + at.gv.e_government.reference.namespace.persondata._20020228_.IdentificationType.Value idvalue = + new at.gv.e_government.reference.namespace.persondata._20020228_.IdentificationType.Value(); + + legalID.setValue(idvalue ); + legalperson.getIdentification().add(legalID ); + mandator.setCorporateBody(legalperson); + legalperson.setFullName(legalCommonName); + legalID.setType(legalSourceType); + idvalue.setValue(legalSourcePin); + + } else if (MiscUtil.isNotEmpty(natFamilyName) && MiscUtil.isNotEmpty(natGivenName) && MiscUtil.isNotEmpty(natDateOfBirth) + && (MiscUtil.isNotEmpty(natSourcePin) || MiscUtil.isNotEmpty(natbPK))){ + Logger.debug("Build 'mandateDate' element for natural person ..."); + at.gv.e_government.reference.namespace.persondata._20020228_.PhysicalPersonType physPerson = + new at.gv.e_government.reference.namespace.persondata._20020228_.PhysicalPersonType(); + at.gv.e_government.reference.namespace.persondata._20020228_.PersonNameType persName = + new at.gv.e_government.reference.namespace.persondata._20020228_.PersonNameType(); + at.gv.e_government.reference.namespace.persondata._20020228_.PersonNameType.FamilyName familyName = + new at.gv.e_government.reference.namespace.persondata._20020228_.PersonNameType.FamilyName(); + at.gv.e_government.reference.namespace.persondata._20020228_.IdentificationType persID = + new at.gv.e_government.reference.namespace.persondata._20020228_.IdentificationType(); + at.gv.e_government.reference.namespace.persondata._20020228_.IdentificationType.Value idValue = + new at.gv.e_government.reference.namespace.persondata._20020228_.IdentificationType.Value(); + + physPerson.setName(persName ); + persName.getFamilyName().add(familyName ); + physPerson.getIdentification().add(persID ); + persID.setValue(idValue ); + mandator.setPhysicalPerson(physPerson); + + String[] pvp2GivenName = natGivenName.split(" "); + for(int i=0; i<pvp2GivenName.length; i++) + persName.getGivenName().add(pvp2GivenName[i]); + + familyName.setValue(natFamilyName); + physPerson.setDateOfBirth(natDateOfBirth); + + if (MiscUtil.isNotEmpty(natSourcePin)) { + persID.setType(Constants.URN_PREFIX_BASEID); + idValue.setValue(natSourcePin); + + } else { + String[] pvp2bPK = natbPK.split(":"); + if (pvp2bPK.length == 2) { + idValue.setValue(pvp2bPK[1]); + Pattern pattern = Pattern.compile(MOAIDAuthConstants.REGEX_PATTERN_TARGET); + Matcher matcher = pattern.matcher(pvp2bPK[0]); + if (matcher.matches()) + persID.setType(Constants.URN_PREFIX_CDID + "+" + pvp2bPK[0]); + + //TODO: maybe change to this, because original SAML1 response has + // target Constants.URN_PREFIX_BPK + //persID.setType(Constants.URN_PREFIX_BPK); + + + else + persID.setType(Constants.URN_PREFIX_WBPK + "+" + pvp2bPK[0]); + + } else { + Logger.warn("Receive mandator bPK from federation with an unsupported format. " + natbPK); + throw new BuildException("auth.16", new Object[]{"Receive mandator bPK from federation with an unsupported format."}); + + } + } + + } else { + Logger.error("mandateDate' elemente could not generated. AuthData contains not all PVP-attributes which are necessary."); + throw new BuildException("auth.16", new Object[]{"'mandateDate' elemente could not generated. AuthData contains not all PVP-attributes which are necessary."}); + + } + + try { + JAXBContext jc = JAXBContext.newInstance("at.gv.e_government.reference.namespace.mandates._20040701_"); + Marshaller m = jc.createMarshaller(); + ByteArrayOutputStream stream = new ByteArrayOutputStream(); + m.marshal(mandateObject, stream); + stream.close(); + + return DOMUtils.parseDocument(new String(stream.toByteArray(), "UTF-8"), false, null, null).getDocumentElement(); + + } catch (JAXBException | IOException | SAXException | ParserConfigurationException e) { + Logger.error("Failed to parse short mandate", e); + throw new BuildException("auth.16", new Object[]{"Failed to parse 'mandateDate element'"}, e); + + } + + } @@ -617,11 +718,11 @@ public class SAML1AuthenticationServer extends AuthenticationServer { new Object[] { samlArtifact }); parser.parseAssertionHandle(); - synchronized (authenticationDataStore) { + //synchronized (authenticationDataStore) { Logger.debug("Assertion stored for SAML Artifact: " + samlArtifact); authenticationDataStore.put(samlArtifact, samlAssertion); - } + //} } catch (AuthenticationException ex) { throw ex; diff --git a/id/server/modules/moa-id-modules-saml1/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/SAML1Protocol.java b/id/server/modules/moa-id-modules-saml1/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/SAML1Protocol.java index 6573270e4..37d66d29b 100644 --- a/id/server/modules/moa-id-modules-saml1/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/SAML1Protocol.java +++ b/id/server/modules/moa-id-modules-saml1/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/SAML1Protocol.java @@ -22,37 +22,52 @@ *******************************************************************************/ package at.gv.egovernment.moa.id.protocols.saml1; +import java.io.IOException; import java.util.Arrays; -import java.util.HashMap; import java.util.List; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.lang.StringEscapeUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; import at.gv.egovernment.moa.id.advancedlogging.MOAIDEventConstants; -import at.gv.egovernment.moa.id.advancedlogging.MOAReversionLogger; -import at.gv.egovernment.moa.id.auth.MOAIDAuthConstants; import at.gv.egovernment.moa.id.auth.exception.InvalidProtocolRequestException; -import at.gv.egovernment.moa.id.auth.exception.MOAIDException; import at.gv.egovernment.moa.id.auth.exception.ProtocolNotActiveException; import at.gv.egovernment.moa.id.auth.exception.WrongParametersException; import at.gv.egovernment.moa.id.auth.servlet.RedirectServlet; +import at.gv.egovernment.moa.id.commons.api.IOAAuthParameters; +import at.gv.egovernment.moa.id.commons.api.IRequest; +import at.gv.egovernment.moa.id.commons.api.data.SAML1ConfigurationParameters; +import at.gv.egovernment.moa.id.commons.api.exceptions.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.config.auth.data.SAML1ConfigurationParameters; -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.id.protocols.AbstractAuthProtocolModulController; import at.gv.egovernment.moa.id.protocols.pvp2x.PVPConstants; import at.gv.egovernment.moa.id.util.ParamValidatorUtils; import at.gv.egovernment.moa.logging.Logger; import at.gv.egovernment.moa.util.MiscUtil; import at.gv.egovernment.moa.util.URLEncoder; -public class SAML1Protocol extends MOAIDAuthConstants implements IModulInfo { +/** + * SAML1 authentication protocol implementation + * + * @deprecated + * @author tlenz + * + */ + +@Controller +public class SAML1Protocol extends AbstractAuthProtocolModulController { + @Autowired private SAML1AuthenticationServer saml1AuthServer; + + public static final String REQ_DATA_SOURCEID = "saml1_sourceID"; + public static final String REQ_DATA_TARGET = "saml1_target"; + public static final String NAME = SAML1Protocol.class.getName(); public static final String PATH = "id_saml1"; @@ -72,24 +87,6 @@ public class SAML1Protocol extends MOAIDAuthConstants implements IModulInfo { PVPConstants.EID_SOURCE_PIN_TYPE_NAME }); - private static HashMap<String, IAction> actions = new HashMap<String, IAction>(); - - static { - - actions.put(GETARTIFACT, new GetArtifactAction()); - - instance = new SAML1Protocol(); - } - - private static SAML1Protocol instance = null; - - public static SAML1Protocol getInstance() { - if (instance == null) { - instance = new SAML1Protocol(); - } - return instance; - } - public String getName() { return NAME; } @@ -98,92 +95,135 @@ public class SAML1Protocol extends MOAIDAuthConstants implements IModulInfo { return PATH; } - public IRequest preProcess(HttpServletRequest request, - HttpServletResponse response, String action, - String sessionId, String transactionId) throws MOAIDException { - SAML1RequestImpl config = new SAML1RequestImpl(request); - + + @RequestMapping(value = "/StartAuthentication", method = {RequestMethod.POST, RequestMethod.GET}) + public void SAML1AuthnRequest(HttpServletRequest req, HttpServletResponse resp) throws MOAIDException, IOException { if (!AuthConfigurationProviderFactory.getInstance().getAllowedProtocols().isSAML1Active()) { Logger.info("SAML1 is deaktivated!"); throw new ProtocolNotActiveException("auth.22", new Object[] { "SAML 1" }); } - - String oaURL = (String) request.getParameter(PARAM_OA); - //oaURL = StringEscapeUtils.escapeHtml(oaURL); - String target = (String) request.getParameter(PARAM_TARGET); - target = StringEscapeUtils.escapeHtml(target); - - String sourceID = request.getParameter(PARAM_SOURCEID); - sourceID = StringEscapeUtils.escapeHtml(sourceID); - - //the target parameter is used to define the OA in SAML1 standard - if (target != null && target.startsWith("http")) { - oaURL = target; - target = null; - } + SAML1RequestImpl pendingReq = applicationContext.getBean(SAML1RequestImpl.class); + pendingReq.initialize(req); + pendingReq.setModule(NAME); + + revisionsLogger.logEvent(MOAIDEventConstants.SESSION_CREATED, pendingReq.getUniqueSessionIdentifier()); + revisionsLogger.logEvent(MOAIDEventConstants.TRANSACTION_CREATED, pendingReq.getUniqueTransactionIdentifier()); + revisionsLogger.logEvent( + pendingReq.getUniqueSessionIdentifier(), + pendingReq.getUniqueTransactionIdentifier(), + MOAIDEventConstants.TRANSACTION_IP, + req.getRemoteAddr()); - if (MiscUtil.isEmpty(oaURL)) { - Logger.info("Receive SAML1 request with no OA parameter. Authentication STOPPED!"); - throw new WrongParametersException("StartAuthentication", PARAM_OA, - "auth.12"); + //preProcess SAML1 Request + preProcess(req, resp, pendingReq); - } - - if (!ParamValidatorUtils.isValidOA(oaURL)) - throw new WrongParametersException("StartAuthentication", PARAM_OA, - "auth.12"); - - config.setOAURL(oaURL); - - Logger.info("Dispatch SAML1 Request: OAURL=" + oaURL); - - if (!ParamValidatorUtils.isValidSourceID(sourceID)) - throw new WrongParametersException("StartAuthentication", PARAM_SOURCEID, "auth.12"); - - - //load Target only from OA config - OAAuthParameter oaParam = AuthConfigurationProviderFactory.getInstance() - .getOnlineApplicationParameter(oaURL); - - if (oaParam == null) - throw new InvalidProtocolRequestException("auth.00", - new Object[] { null }); + performAuthentication(req, resp, pendingReq); + return; - SAML1ConfigurationParameters saml1 = oaParam.getSAML1Parameter(); - if (saml1 == null || !(saml1.isIsActive() != null && saml1.isIsActive()) ) { - Logger.info("Online-Application " + oaURL + " can not use SAML1 for authentication."); - throw new InvalidProtocolRequestException("auth.00", - new Object[] { null }); - } - config.setOnlineApplicationConfiguration(oaParam); - config.setSourceID(sourceID); - - MOAReversionLogger.getInstance().logEvent(sessionId, transactionId, MOAIDEventConstants.AUTHPROTOCOL_SAML1_AUTHNREQUEST); - - if (MiscUtil.isNotEmpty(target)) - config.setTarget(target); - - else - config.setTarget(oaParam.getTarget()); + } + + + public void preProcess(HttpServletRequest request, + HttpServletResponse response, SAML1RequestImpl pendingRequest) throws MOAIDException { + try { + String oaURL = (String) request.getParameter(PARAM_OA); + //oaURL = StringEscapeUtils.escapeHtml(oaURL); + + String target = (String) request.getParameter(PARAM_TARGET); + target = StringEscapeUtils.escapeHtml(target); + + String sourceID = request.getParameter(PARAM_SOURCEID); + sourceID = StringEscapeUtils.escapeHtml(sourceID); + + //the target parameter is used to define the OA in SAML1 standard + if (target != null && target.startsWith("http")) { + oaURL = target; + target = null; + } + + if (MiscUtil.isEmpty(oaURL)) { + Logger.info("Receive SAML1 request with no OA parameter. Authentication STOPPED!"); + throw new WrongParametersException("StartAuthentication", PARAM_OA, + "auth.12"); + + } + + if (!ParamValidatorUtils.isValidOA(oaURL)) + throw new WrongParametersException("StartAuthentication", PARAM_OA, + "auth.12"); + + pendingRequest.setOAURL(oaURL); + + Logger.info("Dispatch SAML1 Request: OAURL=" + oaURL); + + if (!ParamValidatorUtils.isValidSourceID(sourceID)) + throw new WrongParametersException("StartAuthentication", PARAM_SOURCEID, "auth.12"); + + + //load Target only from OA config + IOAAuthParameters oaParam = authConfig.getOnlineApplicationParameter(oaURL); + + if (oaParam == null) + throw new InvalidProtocolRequestException("auth.00", + new Object[] { null }); + + SAML1ConfigurationParameters saml1 = oaParam.getSAML1Parameter(); + if (saml1 == null || !(saml1.isIsActive() != null && saml1.isIsActive()) ) { + Logger.info("Online-Application " + oaURL + " can not use SAML1 for authentication."); + throw new InvalidProtocolRequestException("auth.00", + new Object[] { null }); + } + pendingRequest.setOnlineApplicationConfiguration(oaParam); + + //check and set SourceID + if (oaParam.getSAML1Parameter() != null && + MiscUtil.isNotEmpty(oaParam.getSAML1Parameter().getSourceID())) { + pendingRequest.setSourceID(oaParam.getSAML1Parameter().getSourceID()); + + } else + pendingRequest.setSourceID(sourceID); + + revisionsLogger.logEvent(pendingRequest, MOAIDEventConstants.AUTHPROTOCOL_SAML1_AUTHNREQUEST); + + if (MiscUtil.isNotEmpty(target)) { + pendingRequest.setGenericDataToSession(REQ_DATA_TARGET, target); + pendingRequest.setTarget(target); - return config; + } + else { + pendingRequest.setGenericDataToSession(REQ_DATA_TARGET, oaParam.getTarget()); + pendingRequest.setTarget(oaParam.getTarget()); + + } + + //AuthnRequest needs authentication + pendingRequest.setNeedAuthentication(true); + + //set protocol action, which should be executed after authentication + pendingRequest.setAction(GetArtifactAction.class.getName()); + + } catch (WrongParametersException e) { + throw new InvalidProtocolRequestException(e.getMessageId(), e.getParameters()); + + } catch (InvalidProtocolRequestException e) { + throw e; + + } + } public boolean generateErrorMessage(Throwable e, HttpServletRequest request, HttpServletResponse response, IRequest protocolRequest) throws Throwable{ - - OAAuthParameter oa = AuthConfigurationProviderFactory.getInstance().getOnlineApplicationParameter(protocolRequest.getOAURL()); - if (!oa.getSAML1Parameter().isProvideAllErrors()) + if (!protocolRequest.getOnlineApplicationConfiguration().getSAML1Parameter().isProvideAllErrors()) return false; - else { - SAML1AuthenticationServer saml1authentication = SAML1AuthenticationServer.getInstace(); - String samlArtifactBase64 = saml1authentication.BuildErrorAssertion(e, protocolRequest); + else { + String samlArtifactBase64 = saml1AuthServer.BuildErrorAssertion(e, protocolRequest); String url = protocolRequest.getAuthURL() + "/RedirectServlet"; url = addURLParameter(url, RedirectServlet.REDIRCT_PARAM_URL, URLEncoder.encode(protocolRequest.getOAURL(), "UTF-8")); @@ -199,15 +239,6 @@ public class SAML1Protocol extends MOAIDAuthConstants implements IModulInfo { } } - public IAction getAction(String action) { - return actions.get(action); - } - - public IAction canHandleRequest(HttpServletRequest request, - HttpServletResponse response) { - return null; - } - public boolean validate(HttpServletRequest request, HttpServletResponse response, IRequest pending) { diff --git a/id/server/modules/moa-id-modules-saml1/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/SAML1RequestImpl.java b/id/server/modules/moa-id-modules-saml1/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/SAML1RequestImpl.java index 3da7cab80..42fafc01e 100644 --- a/id/server/modules/moa-id-modules-saml1/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/SAML1RequestImpl.java +++ b/id/server/modules/moa-id-modules-saml1/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/SAML1RequestImpl.java @@ -23,41 +23,30 @@ package at.gv.egovernment.moa.id.protocols.saml1; import java.util.ArrayList; +import java.util.Collection; import java.util.List; -import javax.servlet.http.HttpServletRequest; +import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; -import org.opensaml.saml2.core.Attribute; - -import at.gv.egovernment.moa.id.config.ConfigurationException; -import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProviderFactory; -import at.gv.egovernment.moa.id.config.auth.OAAuthParameter; -import at.gv.egovernment.moa.id.config.auth.data.SAML1ConfigurationParameters; +import at.gv.egovernment.moa.id.commons.api.data.SAML1ConfigurationParameters; import at.gv.egovernment.moa.id.moduls.RequestImpl; import at.gv.egovernment.moa.id.protocols.pvp2x.PVPConstants; -import at.gv.egovernment.moa.id.protocols.pvp2x.builder.AttributQueryBuilder; -import at.gv.egovernment.moa.logging.Logger; /** * @author tlenz * */ +@Component("SAML1RequestImpl") +@Scope(value = BeanDefinition.SCOPE_PROTOTYPE) public class SAML1RequestImpl extends RequestImpl { - - /** - * @param req - * @throws ConfigurationException - */ - public SAML1RequestImpl(HttpServletRequest req) - throws ConfigurationException { - super(req); - - } private static final long serialVersionUID = -4961979968425683115L; private String sourceID = null; - + private String target = null; + /** * @return the sourceID */ @@ -72,36 +61,44 @@ public class SAML1RequestImpl extends RequestImpl { this.sourceID = sourceID; } + + + /** + * @return the target + */ + public String getTarget() { + return target; + } + + /** + * @param target the target to set + */ + public void setTarget(String target) { + this.target = target; + } + /* (non-Javadoc) * @see at.gv.egovernment.moa.id.moduls.RequestImpl#getRequestedAttributes() */ @Override - public List<Attribute> getRequestedAttributes() { + public Collection<String> getRequestedAttributes() { List<String> reqAttr = new ArrayList<String>(); reqAttr.addAll(SAML1Protocol.DEFAULTREQUESTEDATTRFORINTERFEDERATION); - try { - OAAuthParameter oa = AuthConfigurationProviderFactory.getInstance().getOnlineApplicationParameter(getOAURL()); - SAML1ConfigurationParameters saml1 = oa.getSAML1Parameter(); - if (saml1 != null) { - if (saml1.isProvideAUTHBlock()) - reqAttr.add(PVPConstants.EID_AUTH_BLOCK_NAME); - - if (saml1.isProvideCertificate()) - reqAttr.add(PVPConstants.EID_SIGNER_CERTIFICATE_NAME); - - if (saml1.isProvideFullMandatorData()) - reqAttr.add(PVPConstants.MANDATE_FULL_MANDATE_NAME); - } - - return AttributQueryBuilder.buildSAML2AttributeList(oa, reqAttr.iterator()); + SAML1ConfigurationParameters saml1 = this.getOnlineApplicationConfiguration().getSAML1Parameter(); + if (saml1 != null) { + if (saml1.isProvideAUTHBlock()) + reqAttr.add(PVPConstants.EID_AUTH_BLOCK_NAME); + + if (saml1.isProvideCertificate()) + reqAttr.add(PVPConstants.EID_SIGNER_CERTIFICATE_NAME); - } catch (ConfigurationException e) { - Logger.error("Load configuration for OA " + getOAURL() + " FAILED", e); - return null; + if (saml1.isProvideFullMandatorData()) + reqAttr.add(PVPConstants.MANDATE_FULL_MANDATE_NAME); } - + + return reqAttr; } diff --git a/id/server/modules/moa-id-modules-saml1/src/main/resources/META-INF/services/at.gv.egovernment.moa.id.moduls.IModulInfo b/id/server/modules/moa-id-modules-saml1/src/main/resources/META-INF/services/at.gv.egovernment.moa.id.moduls.IModulInfo deleted file mode 100644 index 5bff0dbc2..000000000 --- a/id/server/modules/moa-id-modules-saml1/src/main/resources/META-INF/services/at.gv.egovernment.moa.id.moduls.IModulInfo +++ /dev/null @@ -1 +0,0 @@ -at.gv.egovernment.moa.id.protocols.saml1.SAML1Protocol
\ No newline at end of file diff --git a/id/server/modules/moa-id-modules-saml1/src/main/resources/plain_info.vm b/id/server/modules/moa-id-modules-saml1/src/main/resources/plain_info.vm new file mode 100644 index 000000000..dfc11820f --- /dev/null +++ b/id/server/modules/moa-id-modules-saml1/src/main/resources/plain_info.vm @@ -0,0 +1,14 @@ +<html> +<head> +<meta content="text/html; charset=utf-8" http-equiv="Content-Type"> +</head> +<body> +<h1>GetAuthenticationData</h1> +<p>Hi there, this is an Web service!</p> +#if($error) + <i>Your request has an error: $error</i> +#else + <i>Perhaps there will be a form for invoking the service here...</i> +#end +</body> +</html> diff --git a/id/server/modules/moa-id-modules-saml1/src/main/resources/soap_error.vm b/id/server/modules/moa-id-modules-saml1/src/main/resources/soap_error.vm new file mode 100644 index 000000000..65945e2de --- /dev/null +++ b/id/server/modules/moa-id-modules-saml1/src/main/resources/soap_error.vm @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="UTF-8"?> +<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + <soapenv:Body><samlp:Response #if($requestID) InResponseTo="$requestID" #end IssueInstant="$issueInstant" MajorVersion="1" MinorVersion="0" ResponseID="$responseID" xmlns:saml="urn:oasis:names:tc:SAML:1.0:assertion" xmlns:samlp="urn:oasis:names:tc:SAML:1.0:protocol"> <samlp:Status> <samlp:StatusCode Value="$statusCode"/> <samlp:StatusMessage>$errorMsg</samlp:StatusMessage> </samlp:Status> </samlp:Response> </soapenv:Body> +</soapenv:Envelope>
\ No newline at end of file diff --git a/id/server/modules/moa-id-modules-saml1/src/main/resources/soap_success.vm b/id/server/modules/moa-id-modules-saml1/src/main/resources/soap_success.vm new file mode 100644 index 000000000..7dad2c259 --- /dev/null +++ b/id/server/modules/moa-id-modules-saml1/src/main/resources/soap_success.vm @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="UTF-8"?> +<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + <soapenv:Body>$assertion</soapenv:Body> +</soapenv:Envelope>
\ No newline at end of file diff --git a/id/server/modules/moa-id-modules-saml1/src/main/resources/wsdl/MOA-ID-1.x.vm b/id/server/modules/moa-id-modules-saml1/src/main/resources/wsdl/MOA-ID-1.x.vm new file mode 100644 index 000000000..74be59723 --- /dev/null +++ b/id/server/modules/moa-id-modules-saml1/src/main/resources/wsdl/MOA-ID-1.x.vm @@ -0,0 +1,40 @@ +<?xml version="1.0" encoding="UTF-8"?> +<definitions name="MOA" targetNamespace="http://reference.e-government.gv.at/namespace/moa/20020822#" xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="http://reference.e-government.gv.at/namespace/moa/20020822#" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:samlp="urn:oasis:names:tc:SAML:1.0:protocol" xmlns:moa="http://reference.e-government.gv.at/namespace/moa/20020822#" xmlns:xsd="http://www.w3.org/1999/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://schemas.xmlsoap.org/wsdl/ http://schemas.xmlsoap.org/wsdl/"> + <import namespace="http://reference.e-government.gv.at/namespace/moa/20020822#" location="$endpoint?xsd"/> + <message name="GetAuthenticationDataInput"> + <part name="body" element="samlp:Request"/> + </message> + <message name="GetAuthenticationDataOutput"> + <part name="body" element="samlp:Response"/> + </message> + <message name="MOAFault"> + <part name="body" element="moa:ErrorResponse"/> + </message> + <portType name="IdentificationPortType"> + <operation name="getAuthenticationData"> + <input message="tns:GetAuthenticationDataInput"/> + <output message="tns:GetAuthenticationDataOutput"/> + <fault name="MOAFault" message="tns:MOAFault"/> + </operation> + </portType> + <binding name="IdentificationBinding" type="tns:IdentificationPortType" xsi:schemaLocation="http://schemas.xmlsoap.org/wsdl/soap/ http://schemas.xmlsoap.org/wsdl/soap/"> + <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/> + <operation name="getAuthenticationData"> + <soap:operation soapAction="urn:GetAuthenticationDataAction"/> + <input> + <soap:body use="literal" namespace="http://reference.e-government.gv.at/namespace/moa/20020822#"/> + </input> + <output> + <soap:body use="literal" namespace="http://reference.e-government.gv.at/namespace/moa/20020822#"/> + </output> + <fault name="MOAFault"> + <soap:fault name="MOAFault" use="literal" namespace="http://reference.e-government.gv.at/namespace/moa/20020822#"/> + </fault> + </operation> + </binding> + <service name="GetAuthenticationDataService"> + <port name="IdentificationPort" binding="tns:IdentificationBinding"> + <soap:address location="$endpoint"/> + </port> + </service> +</definitions> diff --git a/id/server/modules/moa-id-modules-saml1/src/main/resources/wsdl/MOA-SPSS-1.2.vm b/id/server/modules/moa-id-modules-saml1/src/main/resources/wsdl/MOA-SPSS-1.2.vm new file mode 100644 index 000000000..4c86626a0 --- /dev/null +++ b/id/server/modules/moa-id-modules-saml1/src/main/resources/wsdl/MOA-SPSS-1.2.vm @@ -0,0 +1,528 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- MOA SP/SS 1.2 Schema --> +<xsd:schema + targetNamespace="http://reference.e-government.gv.at/namespace/moa/20020822#" + xmlns:dsig="http://www.w3.org/2000/09/xmldsig#" xmlns:xsd="http://www.w3.org/2001/XMLSchema" + xmlns="http://reference.e-government.gv.at/namespace/moa/20020822#" + elementFormDefault="qualified" attributeFormDefault="unqualified" + version="1.2"> + <xsd:import namespace="http://www.w3.org/2000/09/xmldsig#" + schemaLocation="http://www.w3.org/TR/xmldsig-core/xmldsig-core-schema.xsd" /> + <xsd:import namespace="http://www.w3.org/XML/1998/namespace" + schemaLocation="http://www.w3.org/2001/xml.xsd" /> + <!--########## Create XML Signature ### --> + <!--### Create XML Signature Request ### --> + <xsd:element name="CreateXMLSignatureRequest"> + <xsd:complexType> + <xsd:complexContent> + <xsd:extension base="CreateXMLSignatureRequestType" /> + </xsd:complexContent> + </xsd:complexType> + </xsd:element> + <xsd:complexType name="CreateXMLSignatureRequestType"> + <xsd:sequence> + <xsd:element name="KeyIdentifier" type="KeyIdentifierType" /> + <xsd:element name="SingleSignatureInfo" maxOccurs="unbounded"> + <xsd:annotation> + <xsd:documentation>Ermöglichung der Stapelsignatur durch + wiederholte Angabe dieses Elements</xsd:documentation> + </xsd:annotation> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="DataObjectInfo" maxOccurs="unbounded"> + <xsd:complexType> + <xsd:complexContent> + <xsd:extension base="DataObjectInfoType"> + <xsd:attribute name="ChildOfManifest" type="xsd:boolean" + use="optional" default="false" /> + </xsd:extension> + </xsd:complexContent> + </xsd:complexType> + </xsd:element> + <xsd:element name="CreateSignatureInfo" minOccurs="0"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="CreateSignatureEnvironment" + type="ContentOptionalRefType" /> + <xsd:choice> + <xsd:annotation> + <xsd:documentation>Auswahl: Entweder explizite Angabe des + Signaturorts sowie ggf. sinnvoller Supplements im Zshg. mit + der Signaturumgebung, oder Verweis auf ein benanntes Profil + </xsd:documentation> + </xsd:annotation> + <xsd:element ref="CreateSignatureEnvironmentProfile" /> + <xsd:element name="CreateSignatureEnvironmentProfileID" + type="ProfileIdentifierType" /> + </xsd:choice> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + </xsd:sequence> + <xsd:attribute name="SecurityLayerConformity" type="xsd:boolean" + use="optional" default="true" /> + </xsd:complexType> + </xsd:element> + </xsd:sequence> + </xsd:complexType> + <!--### Create XML Signature Response ### --> + <xsd:complexType name="CreateXMLSignatureResponseType"> + <xsd:choice maxOccurs="unbounded"> + <xsd:annotation> + <xsd:documentation>Kardinalität 1..oo erlaubt die Antwort auf eine + Stapelsignatur-Anfrage</xsd:documentation> + </xsd:annotation> + <xsd:element name="SignatureEnvironment"> + <xsd:annotation> + <xsd:documentation>Resultat, falls die Signaturerstellung + erfolgreich war</xsd:documentation> + </xsd:annotation> + <xsd:complexType> + <xsd:sequence> + <xsd:any namespace="##any" processContents="lax" /> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + <xsd:element ref="ErrorResponse" /> + </xsd:choice> + </xsd:complexType> + <xsd:element name="CreateXMLSignatureResponse" type="CreateXMLSignatureResponseType" /> + <!--########## Verify CMS Signature ### --> + <!--### Verifiy CMS Signature Request ### --> + <xsd:element name="VerifyCMSSignatureRequest"> + <xsd:complexType> + <xsd:complexContent> + <xsd:extension base="VerifyCMSSignatureRequestType"> + <xsd:attribute name="Signatories" type="SignatoriesType" + use="optional" default="1" /> + </xsd:extension> + </xsd:complexContent> + </xsd:complexType> + </xsd:element> + <xsd:complexType name="VerifyCMSSignatureRequestType"> + <xsd:sequence> + <xsd:element name="DateTime" type="xsd:dateTime" + minOccurs="0" /> + <xsd:element name="CMSSignature" type="xsd:base64Binary" /> + <xsd:element name="DataObject" type="CMSDataObjectOptionalMetaType" + minOccurs="0" /> + <xsd:element name="TrustProfileID"> + <xsd:annotation> + <xsd:documentation>mit diesem Profil wird eine Menge von + vertrauenswürdigen Wurzelzertifikaten spezifiziert + </xsd:documentation> + </xsd:annotation> + </xsd:element> + </xsd:sequence> + </xsd:complexType> + <!--### Verify CMS Signature Response ### --> + <xsd:element name="VerifyCMSSignatureResponse" type="VerifyCMSSignatureResponseType" /> + <xsd:complexType name="VerifyCMSSignatureResponseType"> + <xsd:sequence maxOccurs="unbounded"> + <xsd:element name="SignerInfo" type="dsig:KeyInfoType"> + <xsd:annotation> + <xsd:documentation>only ds:X509Data and RetrievalMethod is + supported; QualifiedCertificate is included as + X509Data/any;publicAuthority is included as X509Data/any + </xsd:documentation> + </xsd:annotation> + </xsd:element> + <xsd:element name="SignatureCheck" type="CheckResultType" /> + <xsd:element name="CertificateCheck" type="CheckResultType" /> + </xsd:sequence> + </xsd:complexType> + <!--########## Verify XML Signature ### --> + <!--### Verify XML Signature Request ### --> + <xsd:element name="VerifyXMLSignatureRequest" type="VerifyXMLSignatureRequestType" /> + <xsd:complexType name="VerifyXMLSignatureRequestType"> + <xsd:sequence> + <xsd:element name="DateTime" type="xsd:dateTime" + minOccurs="0" /> + <xsd:element name="VerifySignatureInfo"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="VerifySignatureEnvironment" type="ContentOptionalRefType" /> + <xsd:element name="VerifySignatureLocation" type="xsd:token" /> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + <xsd:choice minOccurs="0" maxOccurs="unbounded"> + <xsd:element ref="SupplementProfile" /> + <xsd:element name="SupplementProfileID" type="xsd:string" /> + </xsd:choice> + <xsd:element name="SignatureManifestCheckParams" + minOccurs="0"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="ReferenceInfo" type="VerifyTransformsDataType" + maxOccurs="unbounded"> + <xsd:annotation> + <xsd:documentation>Pro dsig:Reference-Element in der zu + überprüfenden XML-Signatur muss hier ein ReferenceInfo-Element + erscheinen. Die Reihenfolge der einzelnen ReferenceInfo + Elemente entspricht jener der dsig:Reference Elemente in der + XML-Signatur.</xsd:documentation> + </xsd:annotation> + </xsd:element> + </xsd:sequence> + <xsd:attribute name="ReturnReferenceInputData" type="xsd:boolean" + use="optional" default="true" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="ReturnHashInputData" minOccurs="0" /> + <xsd:element name="TrustProfileID"> + <xsd:annotation> + <xsd:documentation>mit diesem Profil wird eine Menge von + vertrauenswürdigen Wurzelzertifikaten spezifiziert + </xsd:documentation> + </xsd:annotation> + </xsd:element> + </xsd:sequence> + </xsd:complexType> + <!--### Verify XML Signature Response ### --> + <xsd:element name="VerifyXMLSignatureResponse" type="VerifyXMLSignatureResponseType" /> + <xsd:complexType name="VerifyXMLSignatureResponseType"> + <xsd:sequence> + <xsd:element name="SignerInfo" type="dsig:KeyInfoType"> + <xsd:annotation> + <xsd:documentation>only ds:X509Data and ds:RetrievalMethod is + supported; QualifiedCertificate is included as X509Data/any; + PublicAuthority is included as X509Data/any</xsd:documentation> + </xsd:annotation> + </xsd:element> + <xsd:element name="HashInputData" type="ContentExLocRefBaseType" + minOccurs="0" maxOccurs="unbounded" /> + <xsd:element name="ReferenceInputData" type="ContentExLocRefBaseType" + minOccurs="0" maxOccurs="unbounded" /> + <xsd:element name="SignatureCheck" type="ReferencesCheckResultType" /> + <xsd:element name="SignatureManifestCheck" type="ReferencesCheckResultType" + minOccurs="0" /> + <xsd:element name="XMLDSIGManifestCheck" type="ManifestRefsCheckResultType" + minOccurs="0" maxOccurs="unbounded" /> + <xsd:element name="CertificateCheck" type="CheckResultType" /> + </xsd:sequence> + </xsd:complexType> + <xsd:simpleType name="ProfileIdentifierType"> + <xsd:restriction base="xsd:token" /> + </xsd:simpleType> + <xsd:complexType name="MetaInfoType"> + <xsd:sequence> + <xsd:element name="MimeType" type="MimeTypeType" /> + <xsd:element name="Description" type="xsd:anyURI" + minOccurs="0" /> + <xsd:any namespace="##other" minOccurs="0" maxOccurs="unbounded" /> + </xsd:sequence> + </xsd:complexType> + <xsd:complexType name="FinalDataMetaInfoType"> + <xsd:complexContent> + <xsd:extension base="MetaInfoType"> + <xsd:sequence> + <xsd:element name="Type" type="xsd:anyURI" minOccurs="0" /> + </xsd:sequence> + </xsd:extension> + </xsd:complexContent> + </xsd:complexType> + <xsd:complexType name="DataObjectInfoType"> + <xsd:sequence> + <xsd:element name="DataObject"> + <xsd:complexType> + <xsd:complexContent> + <xsd:extension base="ContentOptionalRefType" /> + </xsd:complexContent> + </xsd:complexType> + </xsd:element> + <xsd:choice> + <xsd:annotation> + <xsd:documentation>Auswahl: Entweder explizite Angabe EINER + Transformationskette inklusive ggf. sinnvoller Supplements oder + Verweis auf ein benanntes Profil</xsd:documentation> + </xsd:annotation> + <xsd:element ref="CreateTransformsInfoProfile" /> + <xsd:element name="CreateTransformsInfoProfileID" type="ProfileIdentifierType" /> + </xsd:choice> + </xsd:sequence> + <xsd:attribute name="Structure" use="required"> + <xsd:simpleType> + <xsd:restriction base="xsd:string"> + <xsd:enumeration value="detached" /> + <xsd:enumeration value="enveloping" /> + </xsd:restriction> + </xsd:simpleType> + </xsd:attribute> + </xsd:complexType> + <xsd:complexType name="TransformsInfoType"> + <xsd:sequence> + <xsd:element ref="dsig:Transforms" minOccurs="0" /> + <xsd:element name="FinalDataMetaInfo" type="FinalDataMetaInfoType" /> + </xsd:sequence> + </xsd:complexType> + <xsd:complexType name="XMLDataObjectAssociationType"> + <xsd:sequence> + <xsd:element name="MetaInfo" type="MetaInfoType" + minOccurs="0" /> + <xsd:element name="Content" type="ContentRequiredRefType" /> + </xsd:sequence> + </xsd:complexType> + <xsd:complexType name="CMSDataObjectOptionalMetaType"> + <xsd:sequence> + <xsd:element name="MetaInfo" type="MetaInfoType" + minOccurs="0" /> + <xsd:element name="Content" type="CMSContentBaseType" /> + </xsd:sequence> + </xsd:complexType> + <xsd:complexType name="CMSContentBaseType"> + <xsd:complexContent> + <xsd:restriction base="ContentOptionalRefType"> + <xsd:choice minOccurs="0"> + <xsd:element name="Base64Content" type="xsd:base64Binary" /> + </xsd:choice> + </xsd:restriction> + </xsd:complexContent> + </xsd:complexType> + <xsd:complexType name="CheckResultType"> + <xsd:sequence> + <xsd:element name="Code" type="xsd:nonNegativeInteger" /> + <xsd:element name="Info" type="AnyChildrenType" + minOccurs="0" /> + </xsd:sequence> + </xsd:complexType> + <xsd:complexType name="ReferencesCheckResultType"> + <xsd:complexContent> + <xsd:restriction base="CheckResultType"> + <xsd:sequence> + <xsd:element name="Code" type="xsd:nonNegativeInteger" /> + <xsd:element name="Info" type="ReferencesCheckResultInfoType" + minOccurs="0" /> + </xsd:sequence> + </xsd:restriction> + </xsd:complexContent> + </xsd:complexType> + <xsd:complexType name="ReferencesCheckResultInfoType" + mixed="true"> + <xsd:complexContent mixed="true"> + <xsd:restriction base="AnyChildrenType"> + <xsd:sequence> + <xsd:any namespace="##other" processContents="lax" + minOccurs="0" maxOccurs="unbounded" /> + <xsd:element name="FailedReference" type="xsd:positiveInteger" + minOccurs="0" maxOccurs="unbounded" /> + </xsd:sequence> + </xsd:restriction> + </xsd:complexContent> + </xsd:complexType> + <xsd:complexType name="ManifestRefsCheckResultType"> + <xsd:complexContent> + <xsd:restriction base="CheckResultType"> + <xsd:sequence> + <xsd:element name="Code" type="xsd:nonNegativeInteger" /> + <xsd:element name="Info" type="ManifestRefsCheckResultInfoType" /> + </xsd:sequence> + </xsd:restriction> + </xsd:complexContent> + </xsd:complexType> + <xsd:complexType name="ManifestRefsCheckResultInfoType" + mixed="true"> + <xsd:complexContent mixed="true"> + <xsd:restriction base="AnyChildrenType"> + <xsd:sequence> + <xsd:any namespace="##other" processContents="lax" + minOccurs="0" maxOccurs="unbounded" /> + <xsd:element name="FailedReference" type="xsd:positiveInteger" + minOccurs="0" maxOccurs="unbounded" /> + <xsd:element name="ReferringSigReference" type="xsd:positiveInteger" /> + </xsd:sequence> + </xsd:restriction> + </xsd:complexContent> + </xsd:complexType> + <!--########## Error Response ### --> + <xsd:element name="ErrorResponse" type="ErrorResponseType"> + <xsd:annotation> + <xsd:documentation>Resultat, falls die Signaturerstellung gescheitert + ist</xsd:documentation> + </xsd:annotation> + </xsd:element> + <xsd:complexType name="ErrorResponseType"> + <xsd:sequence> + <xsd:element name="ErrorCode" type="xsd:integer" /> + <xsd:element name="Info" type="xsd:string" /> + </xsd:sequence> + </xsd:complexType> + <!--########## Auxiliary Types ### --> + <xsd:simpleType name="KeyIdentifierType"> + <xsd:restriction base="xsd:string" /> + </xsd:simpleType> + <xsd:simpleType name="KeyStorageType"> + <xsd:restriction base="xsd:string"> + <xsd:enumeration value="Software" /> + <xsd:enumeration value="Hardware" /> + </xsd:restriction> + </xsd:simpleType> + <xsd:simpleType name="MimeTypeType"> + <xsd:restriction base="xsd:token" /> + </xsd:simpleType> + <xsd:complexType name="AnyChildrenType" mixed="true"> + <xsd:sequence> + <xsd:any namespace="##any" processContents="lax" minOccurs="0" + maxOccurs="unbounded" /> + </xsd:sequence> + </xsd:complexType> + <xsd:complexType name="XMLContentType" mixed="true"> + <xsd:complexContent mixed="true"> + <xsd:extension base="AnyChildrenType"> + <xsd:attribute ref="xml:space" use="optional" /> + </xsd:extension> + </xsd:complexContent> + </xsd:complexType> + <xsd:complexType name="ContentBaseType"> + <xsd:choice minOccurs="0"> + <xsd:element name="Base64Content" type="xsd:base64Binary" /> + <xsd:element name="XMLContent" type="XMLContentType" /> + <xsd:element name="LocRefContent" type="xsd:anyURI" /> + </xsd:choice> + </xsd:complexType> + <xsd:complexType name="ContentExLocRefBaseType"> + <xsd:complexContent> + <xsd:restriction base="ContentBaseType"> + <xsd:choice minOccurs="0"> + <xsd:element name="Base64Content" type="xsd:base64Binary" /> + <xsd:element name="XMLContent" type="XMLContentType" /> + </xsd:choice> + </xsd:restriction> + </xsd:complexContent> + </xsd:complexType> + <xsd:complexType name="ContentOptionalRefType"> + <xsd:complexContent> + <xsd:extension base="ContentBaseType"> + <xsd:attribute name="Reference" type="xsd:anyURI" use="optional" /> + </xsd:extension> + </xsd:complexContent> + </xsd:complexType> + <xsd:complexType name="ContentRequiredRefType"> + <xsd:complexContent> + <xsd:restriction base="ContentOptionalRefType"> + <xsd:choice minOccurs="0"> + <xsd:element name="Base64Content" type="xsd:base64Binary" /> + <xsd:element name="XMLContent" type="XMLContentType" /> + <xsd:element name="LocRefContent" type="xsd:anyURI" /> + </xsd:choice> + <xsd:attribute name="Reference" type="xsd:anyURI" use="required" /> + </xsd:restriction> + </xsd:complexContent> + </xsd:complexType> + <xsd:complexType name="VerifyTransformsDataType"> + <xsd:choice maxOccurs="unbounded"> + <xsd:annotation> + <xsd:documentation>Ein oder mehrere Transformationswege können von + der Applikation an MOA mitgeteilt werden. Die zu prüfende Signatur + hat zumindest einem dieser Transformationswege zu entsprechen. Die + Angabe kann explizit oder als Profilbezeichner erfolgen. + </xsd:documentation> + </xsd:annotation> + <xsd:element ref="VerifyTransformsInfoProfile" /> + <xsd:element name="VerifyTransformsInfoProfileID" type="xsd:string"> + <xsd:annotation> + <xsd:documentation>Profilbezeichner für einen Transformationsweg + </xsd:documentation> + </xsd:annotation> + </xsd:element> + </xsd:choice> + </xsd:complexType> + <xsd:element name="QualifiedCertificate" /> + <xsd:element name="PublicAuthority" type="PublicAuthorityType" /> + <xsd:complexType name="PublicAuthorityType"> + <xsd:sequence> + <xsd:element name="Code" type="xsd:string" minOccurs="0" /> + </xsd:sequence> + </xsd:complexType> + <xsd:simpleType name="SignatoriesType"> + <xsd:union memberTypes="AllSignatoriesType"> + <xsd:simpleType> + <xsd:list itemType="xsd:positiveInteger" /> + </xsd:simpleType> + </xsd:union> + </xsd:simpleType> + <xsd:simpleType name="AllSignatoriesType"> + <xsd:restriction base="xsd:string"> + <xsd:enumeration value="all" /> + </xsd:restriction> + </xsd:simpleType> + <xsd:complexType name="CreateSignatureLocationType"> + <xsd:simpleContent> + <xsd:extension base="xsd:token"> + <xsd:attribute name="Index" type="xsd:nonNegativeInteger" + use="required" /> + </xsd:extension> + </xsd:simpleContent> + </xsd:complexType> + <xsd:complexType name="TransformParameterType"> + <xsd:choice minOccurs="0"> + <xsd:annotation> + <xsd:documentation>Die Angabe des Transformationsparameters + (explizit oder als Hashwert) kann unterlassen werden, wenn die + Applikation von der Unveränderlichkeit des Inhalts der in + "Transformationsparamter", Attribut "URI" angegebenen URI ausgehen + kann.</xsd:documentation> + </xsd:annotation> + <xsd:element name="Base64Content" type="xsd:base64Binary"> + <xsd:annotation> + <xsd:documentation>Der Transformationsparameter explizit angegeben. + </xsd:documentation> + </xsd:annotation> + </xsd:element> + <xsd:element name="Hash"> + <xsd:annotation> + <xsd:documentation>Der Hashwert des Transformationsparameters. + </xsd:documentation> + </xsd:annotation> + <xsd:complexType> + <xsd:sequence> + <xsd:element ref="dsig:DigestMethod" /> + <xsd:element ref="dsig:DigestValue" /> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + </xsd:choice> + <xsd:attribute name="URI" type="xsd:anyURI" use="required" /> + </xsd:complexType> + <xsd:element name="CreateSignatureEnvironmentProfile"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="CreateSignatureLocation" type="CreateSignatureLocationType" /> + <xsd:element name="Supplement" type="XMLDataObjectAssociationType" + minOccurs="0" maxOccurs="unbounded" /> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + <xsd:element name="VerifyTransformsInfoProfile"> + <xsd:annotation> + <xsd:documentation>Explizite Angabe des Transformationswegs + </xsd:documentation> + </xsd:annotation> + <xsd:complexType> + <xsd:sequence> + <xsd:element ref="dsig:Transforms" minOccurs="0" /> + <xsd:element name="TransformParameter" type="TransformParameterType" + minOccurs="0" maxOccurs="unbounded"> + <xsd:annotation> + <xsd:documentation>Alle impliziten Transformationsparameter, die + zum Durchlaufen der oben angeführten Transformationskette bekannt + sein müssen, müssen hier angeführt werden. Das Attribut "URI" + bezeichnet den Transformationsparameter in exakt jener Weise, wie + er in der zu überprüfenden Signatur gebraucht wird. + </xsd:documentation> + </xsd:annotation> + </xsd:element> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + <xsd:element name="Supplement" type="XMLDataObjectAssociationType" /> + <xsd:element name="SupplementProfile" type="XMLDataObjectAssociationType" /> + <xsd:element name="CreateTransformsInfoProfile"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="CreateTransformsInfo" type="TransformsInfoType" /> + <xsd:element ref="Supplement" minOccurs="0" maxOccurs="unbounded" /> + </xsd:sequence> + </xsd:complexType> + </xsd:element> +</xsd:schema> |