diff options
author | Thomas Lenz <tlenz@iaik.tugraz.at> | 2021-12-20 15:54:56 +0100 |
---|---|---|
committer | Thomas Lenz <tlenz@iaik.tugraz.at> | 2021-12-20 15:54:56 +0100 |
commit | 506ab3232b2c237a1d83c9e970dccdb9445d5d81 (patch) | |
tree | 3c94a1a8b4849bdcdbe56d12d0dd7b2e964b234f /id/oa | |
parent | fc0385dbeee71f1ce18783ef1c7a4d06288fdb0d (diff) | |
parent | 600369d4ffa753716a9572824de7a96a04cb05a7 (diff) | |
download | moa-id-spss-506ab3232b2c237a1d83c9e970dccdb9445d5d81.tar.gz moa-id-spss-506ab3232b2c237a1d83c9e970dccdb9445d5d81.tar.bz2 moa-id-spss-506ab3232b2c237a1d83c9e970dccdb9445d5d81.zip |
Diffstat (limited to 'id/oa')
9 files changed, 1232 insertions, 1179 deletions
diff --git a/id/oa/pom.xml b/id/oa/pom.xml index 1522121d2..658dab494 100644 --- a/id/oa/pom.xml +++ b/id/oa/pom.xml @@ -4,7 +4,7 @@ <parent> <groupId>MOA</groupId> <artifactId>id</artifactId> - <version>4.1.5</version> + <version>4.2.0</version> </parent> <modelVersion>4.0.0</modelVersion> @@ -19,7 +19,7 @@ </properties> <build> - <finalName>oa</finalName> + <finalName>moa-id-oa</finalName> <plugins> <!-- <plugin> <groupId>org.codehaus.mojo</groupId> @@ -43,8 +43,8 @@ <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> - <source>1.7</source> - <target>1.7</target> + <source>1.8</source> + <target>1.8</target> </configuration> </plugin> </plugins> @@ -98,10 +98,18 @@ <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> </dependency> - <dependency> - <groupId>org.slf4j</groupId> - <artifactId>slf4j-log4j12</artifactId> - </dependency> + <dependency> + <groupId>org.apache.logging.log4j</groupId> + <artifactId>log4j-1.2-api</artifactId> + </dependency> + <dependency> + <groupId>org.apache.logging.log4j</groupId> + <artifactId>log4j-to-slf4j</artifactId> + </dependency> + <dependency> + <groupId>ch.qos.logback</groupId> + <artifactId>logback-classic</artifactId> + </dependency> <dependency> <groupId>MOA.id.server</groupId> diff --git a/id/oa/src/main/java/at/gv/egovernment/moa/id/demoOA/Configuration.java b/id/oa/src/main/java/at/gv/egovernment/moa/id/demoOA/Configuration.java index 07edb250d..5db37d2f7 100644 --- a/id/oa/src/main/java/at/gv/egovernment/moa/id/demoOA/Configuration.java +++ b/id/oa/src/main/java/at/gv/egovernment/moa/id/demoOA/Configuration.java @@ -35,7 +35,6 @@ import java.util.Timer; import javax.servlet.http.HttpServletRequest; import org.apache.commons.httpclient.HttpClient; -import org.apache.log4j.Logger; import org.opensaml.DefaultBootstrap; import org.opensaml.saml2.metadata.provider.HTTPMetadataProvider; import org.opensaml.xml.parse.BasicParserPool; @@ -45,11 +44,10 @@ import at.gv.egovernment.moa.id.demoOA.exception.ConfigurationException; import at.gv.egovernment.moa.id.demoOA.utils.MetaDataVerificationFilter; import at.gv.egovernment.moa.util.MiscUtil; import iaik.x509.X509Certificate; +import lombok.extern.slf4j.Slf4j; - +@Slf4j public class Configuration { - - private static final Logger log = Logger.getLogger(Configuration.class); private Properties props; private static final String SYSTEM_PROP_CONFIG = "moa.id.demoOA"; diff --git a/id/oa/src/main/java/at/gv/egovernment/moa/id/demoOA/servlet/pvp2/Authenticate.java b/id/oa/src/main/java/at/gv/egovernment/moa/id/demoOA/servlet/pvp2/Authenticate.java index d4c67cfae..040ec330c 100644 --- a/id/oa/src/main/java/at/gv/egovernment/moa/id/demoOA/servlet/pvp2/Authenticate.java +++ b/id/oa/src/main/java/at/gv/egovernment/moa/id/demoOA/servlet/pvp2/Authenticate.java @@ -48,12 +48,10 @@ import org.opensaml.common.impl.SecureRandomIdentifierGenerator; import org.opensaml.common.xml.SAMLConstants; import org.opensaml.saml2.binding.encoding.HTTPPostEncoder; import org.opensaml.saml2.binding.encoding.HTTPRedirectDeflateEncoder; -import org.opensaml.saml2.common.Extensions; import org.opensaml.saml2.core.AuthnContextClassRef; import org.opensaml.saml2.core.AuthnContextComparisonTypeEnumeration; import org.opensaml.saml2.core.AuthnRequest; import org.opensaml.saml2.core.Issuer; -import org.opensaml.saml2.core.NameID; import org.opensaml.saml2.core.NameIDPolicy; import org.opensaml.saml2.core.NameIDType; import org.opensaml.saml2.core.RequestedAuthnContext; @@ -64,12 +62,10 @@ import org.opensaml.saml2.metadata.SingleSignOnService; import org.opensaml.saml2.metadata.impl.SingleSignOnServiceBuilder; import org.opensaml.saml2.metadata.provider.HTTPMetadataProvider; import org.opensaml.ws.transport.http.HttpServletResponseAdapter; -import org.opensaml.xml.XMLObject; import org.opensaml.xml.io.Marshaller; import org.opensaml.xml.io.MarshallingException; import org.opensaml.xml.io.Unmarshaller; import org.opensaml.xml.io.UnmarshallingException; -import org.opensaml.xml.schema.XSAny; import org.opensaml.xml.security.x509.KeyStoreX509CredentialAdapter; import org.opensaml.xml.security.x509.X509Credential; import org.opensaml.xml.signature.Signature; @@ -82,296 +78,299 @@ import org.xml.sax.SAXException; import at.gv.egiz.eaaf.core.api.data.EAAFConstants; import at.gv.egiz.eaaf.core.impl.utils.DOMUtils; -import at.gv.egiz.eaaf.core.impl.utils.EAAFDomEntityResolver; import at.gv.egovernment.moa.id.demoOA.Configuration; import at.gv.egovernment.moa.id.demoOA.exception.ConfigurationException; import at.gv.egovernment.moa.id.demoOA.utils.SAML2Utils; import at.gv.egovernment.moa.util.MiscUtil; - - /** * Servlet implementation class Authenticate */ public class Authenticate extends HttpServlet { - private static final long serialVersionUID = 1L; - - private static final Logger log = LoggerFactory - .getLogger(Authenticate.class); - - /** - * @see HttpServlet#HttpServlet() - */ - public Authenticate() { - super(); - DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); - factory.setNamespaceAware(true); - try { - builder = factory.newDocumentBuilder(); - - } catch (ParserConfigurationException e) { - log.warn("PVP2 AuthenticationServlet can not be initialized.", e); - } - } - - DocumentBuilder builder; - - - //generate AuthenticationRequest - protected void process(HttpServletRequest request, - HttpServletResponse response, Map<String,String> legacyParameter) throws ServletException, IOException { - try { - - Configuration config = Configuration.getInstance(); - config.initializePVP2Login(); - - AuthnRequest authReq = SAML2Utils - .createSAMLObject(AuthnRequest.class); - SecureRandomIdentifierGenerator gen = new SecureRandomIdentifierGenerator(); - authReq.setID(gen.generateIdentifier()); - - String relayState = String.valueOf(RandomUtils.nextLong()); - - if (config.useRedirectBindingResponse()) - authReq.setAssertionConsumerServiceIndex(1); - else - authReq.setAssertionConsumerServiceIndex(0); - - authReq.setAttributeConsumingServiceIndex(0); - - authReq.setIssueInstant(new DateTime()); + private static final long serialVersionUID = 1L; + + private static final Logger log = LoggerFactory + .getLogger(Authenticate.class); + + /** + * @see HttpServlet#HttpServlet() + */ + public Authenticate() { + super(); + final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + factory.setNamespaceAware(true); + try { + builder = factory.newDocumentBuilder(); + + } catch (final ParserConfigurationException e) { + log.warn("PVP2 AuthenticationServlet can not be initialized.", e); + } + } + + DocumentBuilder builder; + + // generate AuthenticationRequest + protected void process(HttpServletRequest request, + HttpServletResponse response, Map<String, String> legacyParameter) throws ServletException, + IOException { + try { + + final Configuration config = Configuration.getInstance(); + config.initializePVP2Login(); + + AuthnRequest authReq = SAML2Utils + .createSAMLObject(AuthnRequest.class); + final SecureRandomIdentifierGenerator gen = new SecureRandomIdentifierGenerator(); + authReq.setID(gen.generateIdentifier()); + + final String relayState = String.valueOf(RandomUtils.nextLong()); + + if (config.useRedirectBindingResponse()) { + authReq.setAssertionConsumerServiceIndex(1); + } else { + authReq.setAssertionConsumerServiceIndex(0); + } + + authReq.setAttributeConsumingServiceIndex(0); + + authReq.setIssueInstant(new DateTime()); // Subject subject = SAML2Utils.createSAMLObject(Subject.class); // NameID name = SAML2Utils.createSAMLObject(NameID.class); - Issuer issuer = SAML2Utils.createSAMLObject(Issuer.class); - - String serviceURL = config.getPublicUrlPreFix(request); - if (!serviceURL.endsWith("/")) - serviceURL = serviceURL + "/"; - //name.setValue(serviceURL); - issuer.setValue(serviceURL); - + final Issuer issuer = SAML2Utils.createSAMLObject(Issuer.class); + + String serviceURL = config.getPublicUrlPreFix(request); + if (!serviceURL.endsWith("/")) { + serviceURL = serviceURL + "/"; + } + // name.setValue(serviceURL); + issuer.setValue(serviceURL); + // subject.setNameID(name); // authReq.setSubject(subject); - issuer.setFormat(NameIDType.ENTITY); - authReq.setIssuer(issuer); - - if (config.setNameIdPolicy()) { - NameIDPolicy policy = SAML2Utils.createSAMLObject(NameIDPolicy.class); - policy.setAllowCreate(true); - policy.setFormat(NameID.PERSISTENT); - authReq.setNameIDPolicy(policy); - } - - String entityname = config.getPVP2IDPMetadataEntityName(); - if (MiscUtil.isEmpty(entityname)) { - log.info("No IDP EntityName configurated"); - throw new ConfigurationException("No IDP EntityName configurated"); - } - - //get IDP metadata from metadataprovider - HTTPMetadataProvider idpmetadata = config.getMetaDataProvier(); - EntityDescriptor idpEntity = idpmetadata.getEntityDescriptor(entityname); - if (idpEntity == null) { - log.info("IDP EntityName is not found in IDP Metadata"); - throw new ConfigurationException("IDP EntityName is not found in IDP Metadata"); - } - - //select authentication-service url from metadata - SingleSignOnService redirectEndpoint = null; - for (SingleSignOnService sss : - idpEntity.getIDPSSODescriptor(SAMLConstants.SAML20P_NS).getSingleSignOnServices()) { - - //Get the service address for the binding you wish to use - if (sss.getBinding().equals(SAMLConstants.SAML2_POST_BINDING_URI) && !config.useRedirectBindingRequest()) { - redirectEndpoint = sss; - } - - //Get the service address for the binding you wish to use - if (sss.getBinding().equals(SAMLConstants.SAML2_REDIRECT_BINDING_URI) && config.useRedirectBindingRequest()) { - redirectEndpoint = sss; - } - - } - - if (redirectEndpoint == null) { - log.warn("Can not find valid EndPoint for SAML2 response"); - throw new ConfigurationException("Can not find valid EndPoint for SAML2 response"); - - } - - authReq.setDestination(redirectEndpoint.getLocation()); - - //authReq.setDestination("http://test.test.test"); - - if (config.setAuthnContextClassRef()) { - RequestedAuthnContext reqAuthContext = - SAML2Utils.createSAMLObject(RequestedAuthnContext.class); - AuthnContextClassRef authnClassRef = - SAML2Utils.createSAMLObject(AuthnContextClassRef.class); - - if (MiscUtil.isNotEmpty(config.getAuthnContextClassRefValue())) { - authnClassRef.setAuthnContextClassRef(config.getAuthnContextClassRefValue()); - - } else { - authnClassRef.setAuthnContextClassRef("http://www.stork.gov.eu/1.0/citizenQAALevel/4"); - - } - - reqAuthContext.setComparison(AuthnContextComparisonTypeEnumeration.MINIMUM); - reqAuthContext.getAuthnContextClassRefs().add(authnClassRef); - authReq.setRequestedAuthnContext(reqAuthContext); - } - - if (StringUtils.isNotEmpty(config.getScopeRequesterId())) { - Scoping scope = SAML2Utils.createSAMLObject(Scoping.class); - RequesterID requesterId = SAML2Utils.createSAMLObject(RequesterID.class); - requesterId.setRequesterID(config.getScopeRequesterId()); - scope.getRequesterIDs().add(requesterId ); - authReq.setScoping(scope ); - - } - - if (config.isEidasProxySimulatorEnabled()) { - authReq = injectEidasMsProxyAttributes(request, authReq); - - } - - - //sign authentication request - KeyStore keyStore = config.getPVP2KeyStore(); - X509Credential authcredential = new KeyStoreX509CredentialAdapter( - keyStore, - config.getPVP2KeystoreAuthRequestKeyAlias(), - config.getPVP2KeystoreAuthRequestKeyPassword().toCharArray()); - - Signature signer = SAML2Utils.createSAMLObject(Signature.class); - signer.setSignatureAlgorithm(SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA1); - signer.setCanonicalizationAlgorithm(SignatureConstants.ALGO_ID_C14N_EXCL_OMIT_COMMENTS); - signer.setSigningCredential(authcredential); - authReq.setSignature(signer); - - - if (!config.useRedirectBindingRequest()) { - //generate Http-POST Binding message - VelocityEngine engine = new VelocityEngine(); - engine.setProperty(RuntimeConstants.ENCODING_DEFAULT, "UTF-8"); - engine.setProperty(RuntimeConstants.OUTPUT_ENCODING, "UTF-8"); - engine.setProperty(RuntimeConstants.ENCODING_DEFAULT, "UTF-8"); - engine.setProperty(RuntimeConstants.RESOURCE_LOADER, "classpath"); - engine.setProperty("classpath.resource.loader.class", - "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader"); - engine.setProperty(RuntimeConstants.RUNTIME_LOG_LOGSYSTEM_CLASS, - "org.apache.velocity.runtime.log.SimpleLog4JLogSystem"); - engine.init(); - - HTTPPostEncoder encoder = new HTTPPostEncoder(engine, - "templates/pvp_postbinding_template.html"); - HttpServletResponseAdapter responseAdapter = new HttpServletResponseAdapter( - response, true); - BasicSAMLMessageContext<SAMLObject, SAMLObject, SAMLObject> context = new BasicSAMLMessageContext<SAMLObject, SAMLObject, SAMLObject>(); - SingleSignOnService service = new SingleSignOnServiceBuilder() - .buildObject(); - service.setBinding("urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"); - service.setLocation(redirectEndpoint.getLocation());; - context.setOutboundSAMLMessageSigningCredential(authcredential); - context.setPeerEntityEndpoint(service); - context.setOutboundSAMLMessage(authReq); - context.setOutboundMessageTransport(responseAdapter); - context.setRelayState(relayState); - encoder.encode(context); - - } else { - //generate Redirect Binding message - HTTPRedirectDeflateEncoder encoder = new HTTPRedirectDeflateEncoder(); - HttpServletResponseAdapter responseAdapter = new HttpServletResponseAdapter( - response, true); - BasicSAMLMessageContext<SAMLObject, SAMLObject, SAMLObject> context = new BasicSAMLMessageContext<SAMLObject, SAMLObject, SAMLObject>(); - SingleSignOnService service = new SingleSignOnServiceBuilder() - .buildObject(); - service.setBinding(SAMLConstants.SAML2_REDIRECT_BINDING_URI); - service.setLocation(redirectEndpoint.getLocation()); - context.setOutboundSAMLMessageSigningCredential(authcredential); - context.setPeerEntityEndpoint(service); - context.setOutboundSAMLMessage(authReq); - context.setOutboundMessageTransport(responseAdapter); - context.setRelayState(relayState); - encoder.encode(context); - - } - - } catch (Exception e) { - log.warn("Authentication Request can not be generated", e); - throw new ServletException("Authentication Request can not be generated.", e); - } - } - - - private AuthnRequest injectEidasMsProxyAttributes(HttpServletRequest request, AuthnRequest authReq) - throws SAXException, IOException, ParserConfigurationException, MarshallingException, UnmarshallingException { - - //build extension from template - String xmlTemplate = IOUtils.toString( - Authenticate.class.getResourceAsStream("/templates/reqAttributes.xml"), - StandardCharsets.UTF_8); - - String target = EAAFConstants.URN_PREFIX_EIDAS + "AT+" + getParameterOrDefault(request, "eidasCountry", "DE"); - String loa = EAAFConstants.EIDAS_LOA_PREFIX + getParameterOrDefault(request, "loa", "high"); - String eidasConnector = "https://simple.test/" + getParameterOrDefault(request, "eidasIdPostfix", "test"); - String xmlString = MessageFormat.format(xmlTemplate, target, loa, eidasConnector); + issuer.setFormat(NameIDType.ENTITY); + authReq.setIssuer(issuer); + + if (config.setNameIdPolicy()) { + final NameIDPolicy policy = SAML2Utils.createSAMLObject(NameIDPolicy.class); + policy.setAllowCreate(true); + policy.setFormat(NameIDType.PERSISTENT); + authReq.setNameIDPolicy(policy); + } + + final String entityname = config.getPVP2IDPMetadataEntityName(); + if (MiscUtil.isEmpty(entityname)) { + log.info("No IDP EntityName configurated"); + throw new ConfigurationException("No IDP EntityName configurated"); + } + + // get IDP metadata from metadataprovider + final HTTPMetadataProvider idpmetadata = config.getMetaDataProvier(); + final EntityDescriptor idpEntity = idpmetadata.getEntityDescriptor(entityname); + if (idpEntity == null) { + log.info("IDP EntityName is not found in IDP Metadata"); + throw new ConfigurationException("IDP EntityName is not found in IDP Metadata"); + } + + // select authentication-service url from metadata + SingleSignOnService redirectEndpoint = null; + for (final SingleSignOnService sss : idpEntity.getIDPSSODescriptor(SAMLConstants.SAML20P_NS) + .getSingleSignOnServices()) { + + // Get the service address for the binding you wish to use + if (sss.getBinding().equals(SAMLConstants.SAML2_POST_BINDING_URI) && !config + .useRedirectBindingRequest()) { + redirectEndpoint = sss; + } + + // Get the service address for the binding you wish to use + if (sss.getBinding().equals(SAMLConstants.SAML2_REDIRECT_BINDING_URI) && config + .useRedirectBindingRequest()) { + redirectEndpoint = sss; + } + + } + + if (redirectEndpoint == null) { + log.warn("Can not find valid EndPoint for SAML2 response"); + throw new ConfigurationException("Can not find valid EndPoint for SAML2 response"); + + } + + authReq.setDestination(redirectEndpoint.getLocation()); + + // authReq.setDestination("http://test.test.test"); + + if (config.setAuthnContextClassRef()) { + final RequestedAuthnContext reqAuthContext = + SAML2Utils.createSAMLObject(RequestedAuthnContext.class); + final AuthnContextClassRef authnClassRef = + SAML2Utils.createSAMLObject(AuthnContextClassRef.class); + + if (MiscUtil.isNotEmpty(config.getAuthnContextClassRefValue())) { + authnClassRef.setAuthnContextClassRef(config.getAuthnContextClassRefValue()); + + } else { + authnClassRef.setAuthnContextClassRef("http://www.stork.gov.eu/1.0/citizenQAALevel/4"); + + } + + reqAuthContext.setComparison(AuthnContextComparisonTypeEnumeration.MINIMUM); + reqAuthContext.getAuthnContextClassRefs().add(authnClassRef); + authReq.setRequestedAuthnContext(reqAuthContext); + } + + if (StringUtils.isNotEmpty(config.getScopeRequesterId())) { + final Scoping scope = SAML2Utils.createSAMLObject(Scoping.class); + final RequesterID requesterId = SAML2Utils.createSAMLObject(RequesterID.class); + requesterId.setRequesterID(config.getScopeRequesterId()); + scope.getRequesterIDs().add(requesterId); + authReq.setScoping(scope); + + } + + if (config.isEidasProxySimulatorEnabled()) { + authReq = injectEidasMsProxyAttributes(request, authReq); + + } + + // sign authentication request + final KeyStore keyStore = config.getPVP2KeyStore(); + final X509Credential authcredential = new KeyStoreX509CredentialAdapter( + keyStore, + config.getPVP2KeystoreAuthRequestKeyAlias(), + config.getPVP2KeystoreAuthRequestKeyPassword().toCharArray()); + + final Signature signer = SAML2Utils.createSAMLObject(Signature.class); + signer.setSignatureAlgorithm(SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA1); + signer.setCanonicalizationAlgorithm(SignatureConstants.ALGO_ID_C14N_EXCL_OMIT_COMMENTS); + signer.setSigningCredential(authcredential); + authReq.setSignature(signer); + + if (!config.useRedirectBindingRequest()) { + // generate Http-POST Binding message + final VelocityEngine engine = new VelocityEngine(); + engine.setProperty(RuntimeConstants.ENCODING_DEFAULT, "UTF-8"); + engine.setProperty(RuntimeConstants.OUTPUT_ENCODING, "UTF-8"); + engine.setProperty(RuntimeConstants.ENCODING_DEFAULT, "UTF-8"); + engine.setProperty(RuntimeConstants.RESOURCE_LOADER, "classpath"); + engine.setProperty("classpath.resource.loader.class", + "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader"); + engine.setProperty(RuntimeConstants.RUNTIME_LOG_LOGSYSTEM_CLASS, + "org.apache.velocity.runtime.log.SimpleLog4JLogSystem"); + engine.init(); + + final HTTPPostEncoder encoder = new HTTPPostEncoder(engine, + "templates/pvp_postbinding_template.html"); + final HttpServletResponseAdapter responseAdapter = new HttpServletResponseAdapter( + response, true); + final BasicSAMLMessageContext<SAMLObject, SAMLObject, SAMLObject> context = + new BasicSAMLMessageContext<>(); + final SingleSignOnService service = new SingleSignOnServiceBuilder() + .buildObject(); + service.setBinding("urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"); + service.setLocation(redirectEndpoint.getLocation()); + context.setOutboundSAMLMessageSigningCredential(authcredential); + context.setPeerEntityEndpoint(service); + context.setOutboundSAMLMessage(authReq); + context.setOutboundMessageTransport(responseAdapter); + context.setRelayState(relayState); + encoder.encode(context); + + } else { + // generate Redirect Binding message + final HTTPRedirectDeflateEncoder encoder = new HTTPRedirectDeflateEncoder(); + final HttpServletResponseAdapter responseAdapter = new HttpServletResponseAdapter( + response, true); + final BasicSAMLMessageContext<SAMLObject, SAMLObject, SAMLObject> context = + new BasicSAMLMessageContext<>(); + final SingleSignOnService service = new SingleSignOnServiceBuilder() + .buildObject(); + service.setBinding(SAMLConstants.SAML2_REDIRECT_BINDING_URI); + service.setLocation(redirectEndpoint.getLocation()); + context.setOutboundSAMLMessageSigningCredential(authcredential); + context.setPeerEntityEndpoint(service); + context.setOutboundSAMLMessage(authReq); + context.setOutboundMessageTransport(responseAdapter); + context.setRelayState(relayState); + encoder.encode(context); + + } + + } catch (final Exception e) { + log.warn("Authentication Request can not be generated", e); + throw new ServletException("Authentication Request can not be generated.", e); + } + } + + private AuthnRequest injectEidasMsProxyAttributes(HttpServletRequest request, AuthnRequest authReq) + throws SAXException, IOException, ParserConfigurationException, MarshallingException, + UnmarshallingException { + + // build extension from template + final String xmlTemplate = IOUtils.toString( + Authenticate.class.getResourceAsStream("/templates/reqAttributes.xml"), + StandardCharsets.UTF_8); + + final String target = EAAFConstants.URN_PREFIX_EIDAS + "AT+" + getParameterOrDefault(request, + "eidasCountry", "DE"); + final String loa = EAAFConstants.EIDAS_LOA_PREFIX + getParameterOrDefault(request, "loa", "high"); + final String eidasConnector = "https://simple.test/" + getParameterOrDefault(request, "eidasIdPostfix", + "test"); + final String xmlString = MessageFormat.format(xmlTemplate, target, loa, eidasConnector); log.debug("Formated requested attributes: " + xmlString); - - Document extension = DOMUtils.parseDocument(xmlString, false, null, null); - - - //marshalle, inject, and unmarshalle request to set extension - //TODO: find better solution, be it is good enough for a first simple test + + final Document extension = DOMUtils.parseDocument(xmlString, false, null, null); + + // marshalle, inject, and unmarshalle request to set extension + // TODO: find better solution, be it is good enough for a first simple test DocumentBuilder builder; - DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); builder = factory.newDocumentBuilder(); - Document document = builder.newDocument(); - Marshaller out = org.opensaml.Configuration.getMarshallerFactory().getMarshaller(authReq); + final Document document = builder.newDocument(); + final Marshaller out = org.opensaml.xml.Configuration.getMarshallerFactory().getMarshaller(authReq); out.marshall(authReq, document); - - Node extElement = document.importNode(extension.getDocumentElement(), true); - //document.getDocumentElement().appendChild(extElement); + + final Node extElement = document.importNode(extension.getDocumentElement(), true); + // document.getDocumentElement().appendChild(extElement); document.getDocumentElement().insertBefore(extElement, document.getChildNodes().item(2)); - - Unmarshaller in = org.opensaml.Configuration.getUnmarshallerFactory().getUnmarshaller(document.getDocumentElement()); + + final Unmarshaller in = org.opensaml.xml.Configuration.getUnmarshallerFactory().getUnmarshaller(document + .getDocumentElement()); return (AuthnRequest) in.unmarshall(document.getDocumentElement()); - + } - - + private String getParameterOrDefault(HttpServletRequest request, String paramName, String defaultValue) { - String reqParam = request.getParameter(paramName); + final String reqParam = request.getParameter(paramName); if (MiscUtil.isEmpty(reqParam)) { return defaultValue; - + } else { return reqParam; - + } - + } + /** + * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse + * response) + */ + @Override + protected void doGet(HttpServletRequest request, + HttpServletResponse response) throws ServletException, IOException { + + process(request, response, null); + } /** - * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse - * response) - */ - protected void doGet(HttpServletRequest request, - HttpServletResponse response) throws ServletException, IOException { - - process(request, response, null); - } - - /** - * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse - * response) - */ - protected void doPost(HttpServletRequest request, - HttpServletResponse response) throws ServletException, IOException { - process(request, response, null); - } + * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse + * response) + */ + @Override + protected void doPost(HttpServletRequest request, + HttpServletResponse response) throws ServletException, IOException { + process(request, response, null); + } } diff --git a/id/oa/src/main/java/at/gv/egovernment/moa/id/demoOA/servlet/pvp2/BuildMetadata.java b/id/oa/src/main/java/at/gv/egovernment/moa/id/demoOA/servlet/pvp2/BuildMetadata.java index d28f94fd6..005291082 100644 --- a/id/oa/src/main/java/at/gv/egovernment/moa/id/demoOA/servlet/pvp2/BuildMetadata.java +++ b/id/oa/src/main/java/at/gv/egovernment/moa/id/demoOA/servlet/pvp2/BuildMetadata.java @@ -42,7 +42,6 @@ import javax.xml.transform.TransformerFactoryConfigurationError; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; -import org.apache.log4j.Logger; import org.joda.time.DateTime; import org.opensaml.common.impl.SecureRandomIdentifierGenerator; import org.opensaml.common.xml.SAMLConstants; @@ -75,267 +74,263 @@ import at.gv.egovernment.moa.id.demoOA.exception.ConfigurationException; import at.gv.egovernment.moa.id.demoOA.utils.AttributeListBuilder; import at.gv.egovernment.moa.id.demoOA.utils.SAML2Utils; import at.gv.egovernment.moa.util.MiscUtil; +import lombok.extern.slf4j.Slf4j; - +@Slf4j public class BuildMetadata extends HttpServlet { - Logger log = Logger.getLogger(BuildMetadata.class); - - private static final long serialVersionUID = 1L; - - private static final int VALIDUNTIL_IN_HOURS = 24; - - /** - * @see HttpServlet#HttpServlet() - */ - public BuildMetadata() { - super(); - } - - protected static Signature getSignature(Credential credentials) { - Signature signer = SAML2Utils.createSAMLObject(Signature.class); - signer.setSignatureAlgorithm(SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA256); - signer.setCanonicalizationAlgorithm(SignatureConstants.ALGO_ID_C14N_EXCL_OMIT_COMMENTS); - signer.setSigningCredential(credentials); - return signer; - } - - /** - * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse - * response) - */ - protected void doGet(HttpServletRequest request, - HttpServletResponse response) throws ServletException, IOException { - try { - Configuration config = Configuration.getInstance(); - - SecureRandomIdentifierGenerator idGen = new SecureRandomIdentifierGenerator(); - - EntitiesDescriptor spEntitiesDescriptor = SAML2Utils. - createSAMLObject(EntitiesDescriptor.class); - - DateTime date = new DateTime(); - spEntitiesDescriptor.setValidUntil(date.plusHours(VALIDUNTIL_IN_HOURS)); - - String name = config.getPVP2MetadataEntitiesName(); - if (MiscUtil.isEmpty(name)) { - log.info("NO Metadata EntitiesName configurated"); - throw new ConfigurationException("NO Metadata EntitiesName configurated"); - } - - spEntitiesDescriptor.setName(name); - spEntitiesDescriptor.setID(idGen.generateIdentifier()); - - //set period of validity for metadata information - DateTime validUntil = new DateTime(); - spEntitiesDescriptor.setValidUntil(validUntil.plusDays(7)); - - - EntityDescriptor spEntityDescriptor = SAML2Utils - .createSAMLObject(EntityDescriptor.class); - - spEntityDescriptor.setValidUntil(date.plusDays(VALIDUNTIL_IN_HOURS)); - - spEntitiesDescriptor.getEntityDescriptors().add(spEntityDescriptor); - - //set OA-ID (PublicURL Prefix) as identifier - String serviceURL = config.getPublicUrlPreFix(request); - if (!serviceURL.endsWith("/")) - serviceURL = serviceURL + "/"; - - log.debug("Set OnlineApplicationURL to " + serviceURL); - spEntityDescriptor.setEntityID(serviceURL); - - SPSSODescriptor spSSODescriptor = SAML2Utils - .createSAMLObject(SPSSODescriptor.class); - - spSSODescriptor.setAuthnRequestsSigned(true); - spSSODescriptor.setWantAssertionsSigned(true); - - X509KeyInfoGeneratorFactory keyInfoFactory = new X509KeyInfoGeneratorFactory(); - keyInfoFactory.setEmitEntityCertificate(true); - KeyInfoGenerator keyInfoGenerator = keyInfoFactory.newInstance(); - - - KeyStore keyStore = config.getPVP2KeyStore(); - - X509Credential signingcredential = new KeyStoreX509CredentialAdapter( - keyStore, - config.getPVP2KeystoreMetadataKeyAlias(), - config.getPVP2KeystoreMetadataKeyPassword().toCharArray()); - - - log.debug("Set Metadata key information"); - //Set MetaData Signing key - KeyDescriptor entitiesSignKeyDescriptor = SAML2Utils - .createSAMLObject(KeyDescriptor.class); - entitiesSignKeyDescriptor.setUse(UsageType.SIGNING); - entitiesSignKeyDescriptor.setKeyInfo(keyInfoGenerator.generate(signingcredential)); - Signature entitiesSignature = getSignature(signingcredential); - spEntitiesDescriptor.setSignature(entitiesSignature); - - - //Set AuthRequest Signing certificate - X509Credential authcredential = new KeyStoreX509CredentialAdapter( - keyStore, - config.getPVP2KeystoreAuthRequestKeyAlias(), - config.getPVP2KeystoreAuthRequestKeyPassword().toCharArray()); - KeyDescriptor signKeyDescriptor = SAML2Utils - .createSAMLObject(KeyDescriptor.class); - - signKeyDescriptor.setUse(UsageType.SIGNING); - signKeyDescriptor.setKeyInfo(keyInfoGenerator.generate(authcredential)); - - spSSODescriptor.getKeyDescriptors().add(signKeyDescriptor); - - - //set AuthRequest encryption certificate - if (MiscUtil.isNotEmpty(config.getPVP2KeystoreAuthRequestEncryptionKeyAlias()) || - MiscUtil.isNotEmpty(config.getPVP2KeystoreAuthRequestEncryptionKeyPassword())) { - X509Credential authEncCredential = new KeyStoreX509CredentialAdapter( - keyStore, - config.getPVP2KeystoreAuthRequestEncryptionKeyAlias(), - config.getPVP2KeystoreAuthRequestEncryptionKeyPassword().toCharArray()); - KeyDescriptor encryKeyDescriptor = SAML2Utils - .createSAMLObject(KeyDescriptor.class); - encryKeyDescriptor.setUse(UsageType.ENCRYPTION); - encryKeyDescriptor.setKeyInfo(keyInfoGenerator.generate(authEncCredential)); - - //set encryption methode + + private static final long serialVersionUID = 1L; + + private static final int VALIDUNTIL_IN_HOURS = 24; + + /** + * @see HttpServlet#HttpServlet() + */ + public BuildMetadata() { + super(); + } + + protected static Signature getSignature(Credential credentials) { + final Signature signer = SAML2Utils.createSAMLObject(Signature.class); + signer.setSignatureAlgorithm(SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA256); + signer.setCanonicalizationAlgorithm(SignatureConstants.ALGO_ID_C14N_EXCL_OMIT_COMMENTS); + signer.setSigningCredential(credentials); + return signer; + } + + /** + * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse + * response) + */ + @Override + protected void doGet(HttpServletRequest request, + HttpServletResponse response) throws ServletException, IOException { + try { + final Configuration config = Configuration.getInstance(); + + final SecureRandomIdentifierGenerator idGen = new SecureRandomIdentifierGenerator(); + + final EntitiesDescriptor spEntitiesDescriptor = SAML2Utils.createSAMLObject(EntitiesDescriptor.class); + + final DateTime date = new DateTime(); + spEntitiesDescriptor.setValidUntil(date.plusHours(VALIDUNTIL_IN_HOURS)); + + final String name = config.getPVP2MetadataEntitiesName(); + if (MiscUtil.isEmpty(name)) { + log.info("NO Metadata EntitiesName configurated"); + throw new ConfigurationException("NO Metadata EntitiesName configurated"); + } + + spEntitiesDescriptor.setName(name); + spEntitiesDescriptor.setID(idGen.generateIdentifier()); + + // set period of validity for metadata information + final DateTime validUntil = new DateTime(); + spEntitiesDescriptor.setValidUntil(validUntil.plusDays(7)); + + final EntityDescriptor spEntityDescriptor = SAML2Utils + .createSAMLObject(EntityDescriptor.class); + + spEntityDescriptor.setValidUntil(date.plusDays(VALIDUNTIL_IN_HOURS)); + + spEntitiesDescriptor.getEntityDescriptors().add(spEntityDescriptor); + + // set OA-ID (PublicURL Prefix) as identifier + String serviceURL = config.getPublicUrlPreFix(request); + if (!serviceURL.endsWith("/")) { + serviceURL = serviceURL + "/"; + } + + log.debug("Set OnlineApplicationURL to " + serviceURL); + spEntityDescriptor.setEntityID(serviceURL); + + final SPSSODescriptor spSSODescriptor = SAML2Utils + .createSAMLObject(SPSSODescriptor.class); + + spSSODescriptor.setAuthnRequestsSigned(true); + spSSODescriptor.setWantAssertionsSigned(true); + + final X509KeyInfoGeneratorFactory keyInfoFactory = new X509KeyInfoGeneratorFactory(); + keyInfoFactory.setEmitEntityCertificate(true); + final KeyInfoGenerator keyInfoGenerator = keyInfoFactory.newInstance(); + + final KeyStore keyStore = config.getPVP2KeyStore(); + + final X509Credential signingcredential = new KeyStoreX509CredentialAdapter( + keyStore, + config.getPVP2KeystoreMetadataKeyAlias(), + config.getPVP2KeystoreMetadataKeyPassword().toCharArray()); + + log.debug("Set Metadata key information"); + // Set MetaData Signing key + final KeyDescriptor entitiesSignKeyDescriptor = SAML2Utils + .createSAMLObject(KeyDescriptor.class); + entitiesSignKeyDescriptor.setUse(UsageType.SIGNING); + entitiesSignKeyDescriptor.setKeyInfo(keyInfoGenerator.generate(signingcredential)); + final Signature entitiesSignature = getSignature(signingcredential); + spEntitiesDescriptor.setSignature(entitiesSignature); + + // Set AuthRequest Signing certificate + final X509Credential authcredential = new KeyStoreX509CredentialAdapter( + keyStore, + config.getPVP2KeystoreAuthRequestKeyAlias(), + config.getPVP2KeystoreAuthRequestKeyPassword().toCharArray()); + final KeyDescriptor signKeyDescriptor = SAML2Utils + .createSAMLObject(KeyDescriptor.class); + + signKeyDescriptor.setUse(UsageType.SIGNING); + signKeyDescriptor.setKeyInfo(keyInfoGenerator.generate(authcredential)); + + spSSODescriptor.getKeyDescriptors().add(signKeyDescriptor); + + // set AuthRequest encryption certificate + if (MiscUtil.isNotEmpty(config.getPVP2KeystoreAuthRequestEncryptionKeyAlias()) || + MiscUtil.isNotEmpty(config.getPVP2KeystoreAuthRequestEncryptionKeyPassword())) { + final X509Credential authEncCredential = new KeyStoreX509CredentialAdapter( + keyStore, + config.getPVP2KeystoreAuthRequestEncryptionKeyAlias(), + config.getPVP2KeystoreAuthRequestEncryptionKeyPassword().toCharArray()); + final KeyDescriptor encryKeyDescriptor = SAML2Utils + .createSAMLObject(KeyDescriptor.class); + encryKeyDescriptor.setUse(UsageType.ENCRYPTION); + encryKeyDescriptor.setKeyInfo(keyInfoGenerator.generate(authEncCredential)); + + // set encryption methode // EncryptionMethod encMethode = SAML2Utils.createSAMLObject(EncryptionMethod.class); -// encMethode.setAlgorithm(EncryptionConstants.ALGO_ID_BLOCKCIPHER_AES128_GCM); +// encMethode.setAlgorithm(EncryptionConstants.ALGO_ID_BLOCKCIPHER_AES128_GCM); // encryKeyDescriptor.getEncryptionMethods().add(encMethode); -// +// // EncryptionMethod keyencMethode = SAML2Utils.createSAMLObject(EncryptionMethod.class); -// keyencMethode.setAlgorithm(EncryptionConstants.ALGO_ID_KEYTRANSPORT_RSAOAEP); +// keyencMethode.setAlgorithm(EncryptionConstants.ALGO_ID_KEYTRANSPORT_RSAOAEP); // encryKeyDescriptor.getEncryptionMethods().add(keyencMethode); - - spSSODescriptor.getKeyDescriptors().add(encryKeyDescriptor); - - } else { - log.warn("No Assertion Encryption-Key defined. This setting is not recommended!"); - - } - - - NameIDFormat persistentnameIDFormat = SAML2Utils.createSAMLObject(NameIDFormat.class); - persistentnameIDFormat.setFormat(NameIDType.PERSISTENT); - - spSSODescriptor.getNameIDFormats().add(persistentnameIDFormat); - - NameIDFormat transientnameIDFormat = SAML2Utils.createSAMLObject(NameIDFormat.class); - transientnameIDFormat.setFormat(NameIDType.TRANSIENT); - - spSSODescriptor.getNameIDFormats().add(transientnameIDFormat); - - NameIDFormat unspecifiednameIDFormat = SAML2Utils.createSAMLObject(NameIDFormat.class); - unspecifiednameIDFormat.setFormat(NameIDType.UNSPECIFIED); - - spSSODescriptor.getNameIDFormats().add(unspecifiednameIDFormat); - - //set HTTP-POST Binding assertion consumer service - AssertionConsumerService postassertionConsumerService = - SAML2Utils.createSAMLObject(AssertionConsumerService.class); - postassertionConsumerService.setIndex(0); - postassertionConsumerService.setBinding(SAMLConstants.SAML2_POST_BINDING_URI); - postassertionConsumerService.setLocation(serviceURL + Constants.SERVLET_PVP2ASSERTION); - spSSODescriptor.getAssertionConsumerServices().add(postassertionConsumerService); - - //set HTTP-Redirect Binding assertion consumer service - AssertionConsumerService redirectassertionConsumerService = - SAML2Utils.createSAMLObject(AssertionConsumerService.class); - redirectassertionConsumerService.setIndex(1); - redirectassertionConsumerService.setBinding(SAMLConstants.SAML2_REDIRECT_BINDING_URI); - redirectassertionConsumerService.setLocation(serviceURL + Constants.SERVLET_PVP2ASSERTION); - spSSODescriptor.getAssertionConsumerServices().add(redirectassertionConsumerService); - - //set Single Log-Out service - SingleLogoutService sloService = SAML2Utils.createSAMLObject(SingleLogoutService.class); - sloService.setBinding(SAMLConstants.SAML2_REDIRECT_BINDING_URI); - sloService.setLocation(serviceURL + Constants.SERVLET_PVPSINGLELOGOUT); - spSSODescriptor.getSingleLogoutServices().add(sloService); - - spSSODescriptor.addSupportedProtocol(SAMLConstants.SAML20P_NS); - - spEntityDescriptor.getRoleDescriptors().add(spSSODescriptor); - - AttributeConsumingService attributeService = - SAML2Utils.createSAMLObject(AttributeConsumingService.class); - - attributeService.setIndex(0); - attributeService.setIsDefault(true); - ServiceName serviceName = SAML2Utils.createSAMLObject(ServiceName.class); - serviceName.setName(new LocalizedString("Default Service", "de")); - attributeService.getNames().add(serviceName); - - //set attributes which are requested - attributeService.getRequestAttributes().addAll(AttributeListBuilder.getRequestedAttributes()); - spSSODescriptor.getAttributeConsumingServices().add(attributeService); - - - //build metadata - DocumentBuilder builder; - DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); - - builder = factory.newDocumentBuilder(); - Document document = builder.newDocument(); - Marshaller out = org.opensaml.Configuration.getMarshallerFactory().getMarshaller(spEntitiesDescriptor); - out.marshall(spEntitiesDescriptor, document); - - Signer.signObject(entitiesSignature); - - Transformer transformer = TransformerFactory.newInstance().newTransformer(); - - StringWriter sw = new StringWriter(); - StreamResult sr = new StreamResult(sw); - DOMSource source = new DOMSource(document); - transformer.transform(source, sr); - sw.close(); - - String metadataXML = sw.toString(); - - response.setContentType("text/xml"); - response.getOutputStream().write(metadataXML.getBytes()); - - response.getOutputStream().close(); - - } catch (ConfigurationException e) { - log.warn("Configuration can not be loaded.", e); - throw new ServletException("MetaData can not be created. Look into LogFiles for more details."); - - } catch (NoSuchAlgorithmException e) { - log.warn("Requested Algorithm could not found.", e); - throw new ServletException("MetaData can not be created. Look into LogFiles for more details."); - - } catch (ParserConfigurationException e) { - log.warn("PVP2 Metadata createn error", e); - throw new ServletException("MetaData can not be created. Look into LogFiles for more details."); - - } catch (TransformerConfigurationException e) { - log.warn("PVP2 Metadata createn error", e); - throw new ServletException("MetaData can not be created. Look into LogFiles for more details."); - - } catch (TransformerFactoryConfigurationError e) { - log.warn("PVP2 Metadata createn error", e); - throw new ServletException("MetaData can not be created. Look into LogFiles for more details."); - - } catch (TransformerException e) { - log.warn("PVP2 Metadata createn error", e); - throw new ServletException("MetaData can not be created. Look into LogFiles for more details."); - } - - catch (Exception e) { - log.warn("Unspecific PVP2 Metadata createn error", e); - throw new ServletException("MetaData can not be created. Look into LogFiles for more details."); - } - - } - - /** - * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse - * response) - */ - protected void doPost(HttpServletRequest request, - HttpServletResponse response) throws ServletException, IOException { - } + + spSSODescriptor.getKeyDescriptors().add(encryKeyDescriptor); + + } else { + log.warn("No Assertion Encryption-Key defined. This setting is not recommended!"); + + } + + final NameIDFormat persistentnameIDFormat = SAML2Utils.createSAMLObject(NameIDFormat.class); + persistentnameIDFormat.setFormat(NameIDType.PERSISTENT); + + spSSODescriptor.getNameIDFormats().add(persistentnameIDFormat); + + final NameIDFormat transientnameIDFormat = SAML2Utils.createSAMLObject(NameIDFormat.class); + transientnameIDFormat.setFormat(NameIDType.TRANSIENT); + + spSSODescriptor.getNameIDFormats().add(transientnameIDFormat); + + final NameIDFormat unspecifiednameIDFormat = SAML2Utils.createSAMLObject(NameIDFormat.class); + unspecifiednameIDFormat.setFormat(NameIDType.UNSPECIFIED); + + spSSODescriptor.getNameIDFormats().add(unspecifiednameIDFormat); + + // set HTTP-POST Binding assertion consumer service + final AssertionConsumerService postassertionConsumerService = + SAML2Utils.createSAMLObject(AssertionConsumerService.class); + postassertionConsumerService.setIndex(0); + postassertionConsumerService.setBinding(SAMLConstants.SAML2_POST_BINDING_URI); + postassertionConsumerService.setLocation(serviceURL + Constants.SERVLET_PVP2ASSERTION); + spSSODescriptor.getAssertionConsumerServices().add(postassertionConsumerService); + + // set HTTP-Redirect Binding assertion consumer service + final AssertionConsumerService redirectassertionConsumerService = + SAML2Utils.createSAMLObject(AssertionConsumerService.class); + redirectassertionConsumerService.setIndex(1); + redirectassertionConsumerService.setBinding(SAMLConstants.SAML2_REDIRECT_BINDING_URI); + redirectassertionConsumerService.setLocation(serviceURL + Constants.SERVLET_PVP2ASSERTION); + spSSODescriptor.getAssertionConsumerServices().add(redirectassertionConsumerService); + + // set Single Log-Out service + final SingleLogoutService sloService = SAML2Utils.createSAMLObject(SingleLogoutService.class); + sloService.setBinding(SAMLConstants.SAML2_REDIRECT_BINDING_URI); + sloService.setLocation(serviceURL + Constants.SERVLET_PVPSINGLELOGOUT); + spSSODescriptor.getSingleLogoutServices().add(sloService); + + spSSODescriptor.addSupportedProtocol(SAMLConstants.SAML20P_NS); + + spEntityDescriptor.getRoleDescriptors().add(spSSODescriptor); + + final AttributeConsumingService attributeService = + SAML2Utils.createSAMLObject(AttributeConsumingService.class); + + attributeService.setIndex(0); + attributeService.setIsDefault(true); + final ServiceName serviceName = SAML2Utils.createSAMLObject(ServiceName.class); + serviceName.setName(new LocalizedString("Default Service", "de")); + attributeService.getNames().add(serviceName); + + // set attributes which are requested + attributeService.getRequestAttributes().addAll(AttributeListBuilder.getRequestedAttributes()); + spSSODescriptor.getAttributeConsumingServices().add(attributeService); + + // build metadata + DocumentBuilder builder; + final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + + builder = factory.newDocumentBuilder(); + final Document document = builder.newDocument(); + final Marshaller out = org.opensaml.xml.Configuration.getMarshallerFactory().getMarshaller( + spEntitiesDescriptor); + out.marshall(spEntitiesDescriptor, document); + + Signer.signObject(entitiesSignature); + + final Transformer transformer = TransformerFactory.newInstance().newTransformer(); + + final StringWriter sw = new StringWriter(); + final StreamResult sr = new StreamResult(sw); + final DOMSource source = new DOMSource(document); + transformer.transform(source, sr); + sw.close(); + + final String metadataXML = sw.toString(); + + response.setContentType("text/xml"); + response.getOutputStream().write(metadataXML.getBytes()); + + response.getOutputStream().close(); + + } catch (final ConfigurationException e) { + log.warn("Configuration can not be loaded.", e); + throw new ServletException("MetaData can not be created. Look into LogFiles for more details."); + + } catch (final NoSuchAlgorithmException e) { + log.warn("Requested Algorithm could not found.", e); + throw new ServletException("MetaData can not be created. Look into LogFiles for more details."); + + } catch (final ParserConfigurationException e) { + log.warn("PVP2 Metadata createn error", e); + throw new ServletException("MetaData can not be created. Look into LogFiles for more details."); + + } catch (final TransformerConfigurationException e) { + log.warn("PVP2 Metadata createn error", e); + throw new ServletException("MetaData can not be created. Look into LogFiles for more details."); + + } catch (final TransformerFactoryConfigurationError e) { + log.warn("PVP2 Metadata createn error", e); + throw new ServletException("MetaData can not be created. Look into LogFiles for more details."); + + } catch (final TransformerException e) { + log.warn("PVP2 Metadata createn error", e); + throw new ServletException("MetaData can not be created. Look into LogFiles for more details."); + } + + catch (final Exception e) { + log.warn("Unspecific PVP2 Metadata createn error", e); + throw new ServletException("MetaData can not be created. Look into LogFiles for more details."); + } + + } + + /** + * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse + * response) + */ + @Override + protected void doPost(HttpServletRequest request, + HttpServletResponse response) throws ServletException, IOException { + } }
\ No newline at end of file diff --git a/id/oa/src/main/java/at/gv/egovernment/moa/id/demoOA/servlet/pvp2/DemoApplication.java b/id/oa/src/main/java/at/gv/egovernment/moa/id/demoOA/servlet/pvp2/DemoApplication.java index e36a880ba..e4acd8152 100644 --- a/id/oa/src/main/java/at/gv/egovernment/moa/id/demoOA/servlet/pvp2/DemoApplication.java +++ b/id/oa/src/main/java/at/gv/egovernment/moa/id/demoOA/servlet/pvp2/DemoApplication.java @@ -33,7 +33,6 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; -import org.apache.log4j.Logger; import org.opensaml.common.SAMLObject; import org.opensaml.common.binding.BasicSAMLMessageContext; import org.opensaml.common.xml.SAMLConstants; @@ -41,6 +40,7 @@ import org.opensaml.saml2.binding.decoding.HTTPPostDecoder; import org.opensaml.saml2.binding.decoding.HTTPRedirectDeflateDecoder; import org.opensaml.saml2.binding.security.SAML2AuthnRequestsSignedRule; import org.opensaml.saml2.binding.security.SAML2HTTPRedirectDeflateSignatureRule; +import org.opensaml.saml2.core.Assertion; import org.opensaml.saml2.core.Attribute; import org.opensaml.saml2.core.AttributeStatement; import org.opensaml.saml2.core.EncryptedAssertion; @@ -84,263 +84,285 @@ import at.gv.egovernment.moa.id.demoOA.Constants; import at.gv.egovernment.moa.id.demoOA.PVPConstants; import at.gv.egovernment.moa.id.demoOA.utils.ApplicationBean; import at.gv.egovernment.moa.id.demoOA.utils.SAML2Utils; +import lombok.extern.slf4j.Slf4j; +@Slf4j public class DemoApplication extends HttpServlet { - Logger log = Logger.getLogger(DemoApplication.class); - - private static final long serialVersionUID = -2129228304760706063L; - - - - private void process(HttpServletRequest request, - HttpServletResponse response) throws ServletException, IOException { - - - ApplicationBean bean = new ApplicationBean(); - - log.debug("Receive request on secure-area endpoint ..."); - - String method = request.getMethod(); - HttpSession session = request.getSession(); - if (session == null) { - log.info("NO HTTP Session"); - bean.setErrorMessage("NO HTTP session"); - setAnser(request, response, bean); - return; - } - - try { - Configuration config = Configuration.getInstance(); - Response samlResponse = null; - - if (method.equals("GET")) { - log.debug("Find possible SAML2 Redirect-Binding response ..."); - HTTPRedirectDeflateDecoder decode = new HTTPRedirectDeflateDecoder(new BasicParserPool()); - BasicSAMLMessageContext<Response, ?, ?> messageContext = new BasicSAMLMessageContext<Response, SAMLObject, SAMLObject>(); - - messageContext.setInboundMessageTransport(new HttpServletRequestAdapter(request)); - messageContext.setPeerEntityRole(SPSSODescriptor.DEFAULT_ELEMENT_NAME); - - messageContext.setMetadataProvider(config.getMetaDataProvier()); - - MetadataCredentialResolver resolver = new MetadataCredentialResolver(config.getMetaDataProvier()); - List<KeyInfoProvider> keyInfoProvider = new ArrayList<KeyInfoProvider>(); - keyInfoProvider.add(new DSAKeyValueProvider()); - keyInfoProvider.add(new RSAKeyValueProvider()); - keyInfoProvider.add(new InlineX509DataProvider()); - KeyInfoCredentialResolver keyInfoResolver = new BasicProviderKeyInfoCredentialResolver( - keyInfoProvider); - ExplicitKeySignatureTrustEngine engine = new ExplicitKeySignatureTrustEngine( - resolver, keyInfoResolver); - - SAML2HTTPRedirectDeflateSignatureRule signatureRule = new SAML2HTTPRedirectDeflateSignatureRule(engine); - SAML2AuthnRequestsSignedRule signedRole = new SAML2AuthnRequestsSignedRule(); - BasicSecurityPolicy policy = new BasicSecurityPolicy(); - policy.getPolicyRules().add(signatureRule); - policy.getPolicyRules().add(signedRole); - SecurityPolicyResolver resolver1 = new StaticSecurityPolicyResolver(policy); - messageContext.setSecurityPolicyResolver(resolver1); - - decode.decode(messageContext); - - log.info("PVP2 Assertion with Redirect-Binding is valid"); - - } else if (method.equals("POST")) { - log.debug("Find possible SAML2 Post-Binding response ..."); - //Decode with HttpPost Binding - HTTPPostDecoder decode = new HTTPPostDecoder(new BasicParserPool()); - BasicSAMLMessageContext<Response, ?, ?> messageContext = new BasicSAMLMessageContext<Response, SAMLObject, SAMLObject>(); - messageContext - .setInboundMessageTransport(new HttpServletRequestAdapter( - request)); - decode.decode(messageContext); - - samlResponse = (Response) messageContext.getInboundMessage(); - - Signature sign = samlResponse.getSignature(); - if (sign == null) { - log.info("Only http POST Requests can be used"); - bean.setErrorMessage("Only http POST Requests can be used"); - setAnser(request, response, bean); - return; - } - - //Validate Signature - SAMLSignatureProfileValidator profileValidator = new SAMLSignatureProfileValidator(); - profileValidator.validate(sign); - - //Verify Signature - List<KeyInfoProvider> keyInfoProvider = new ArrayList<KeyInfoProvider>(); - keyInfoProvider.add(new DSAKeyValueProvider()); - keyInfoProvider.add(new RSAKeyValueProvider()); - keyInfoProvider.add(new InlineX509DataProvider()); - - KeyInfoCredentialResolver keyInfoResolver = new BasicProviderKeyInfoCredentialResolver( - keyInfoProvider); - - MetadataCredentialResolverFactory credentialResolverFactory = MetadataCredentialResolverFactory.getFactory(); - MetadataCredentialResolver credentialResolver = credentialResolverFactory.getInstance(config.getMetaDataProvier()); - - CriteriaSet criteriaSet = new CriteriaSet(); - criteriaSet.add(new MetadataCriteria(IDPSSODescriptor.DEFAULT_ELEMENT_NAME, SAMLConstants.SAML20P_NS)); - criteriaSet.add(new EntityIDCriteria(config.getPVP2IDPMetadataEntityName())); - criteriaSet.add(new UsageCriteria(UsageType.SIGNING)); - - ExplicitKeySignatureTrustEngine trustEngine = new ExplicitKeySignatureTrustEngine(credentialResolver, keyInfoResolver); - trustEngine.validate(sign, criteriaSet); - - log.info("PVP2 Assertion with POST-Binding is valid"); - - } else { - bean.setErrorMessage("Die Demoapplikation unterstützt nur SAML2 POST-Binding."); - setAnser(request, response, bean); - return; - - } - - - if (samlResponse.getStatus().getStatusCode().getValue().equals(StatusCode.SUCCESS_URI)) { - - List<org.opensaml.saml2.core.Assertion> saml2assertions = new ArrayList<org.opensaml.saml2.core.Assertion>(); - - //check encrypted Assertion - List<EncryptedAssertion> encryAssertionList = samlResponse.getEncryptedAssertions(); - if (encryAssertionList != null && encryAssertionList.size() > 0) { - //decrypt assertions - - log.debug("Found encryped assertion. Start decryption ..."); - - KeyStore keyStore = config.getPVP2KeyStore(); - - X509Credential authDecCredential = new KeyStoreX509CredentialAdapter( - keyStore, - config.getPVP2KeystoreAuthRequestEncryptionKeyAlias(), - config.getPVP2KeystoreAuthRequestEncryptionKeyPassword().toCharArray()); - - - StaticKeyInfoCredentialResolver skicr = - new StaticKeyInfoCredentialResolver(authDecCredential); - - ChainingEncryptedKeyResolver encryptedKeyResolver = new ChainingEncryptedKeyResolver(); - encryptedKeyResolver.getResolverChain().add( new InlineEncryptedKeyResolver() ); - encryptedKeyResolver.getResolverChain().add( new EncryptedElementTypeEncryptedKeyResolver() ); - encryptedKeyResolver.getResolverChain().add( new SimpleRetrievalMethodEncryptedKeyResolver() ); - - Decrypter samlDecrypter = - new Decrypter(null, skicr, encryptedKeyResolver); - - for (EncryptedAssertion encAssertion : encryAssertionList) { - saml2assertions.add(samlDecrypter.decrypt(encAssertion)); - - } - - log.debug("Assertion decryption finished. "); - - } else { - saml2assertions = samlResponse.getAssertions(); - - } - - samlResponse.getAssertions().clear(); - samlResponse.getAssertions().addAll(saml2assertions); - - //set assertion - org.w3c.dom.Document doc = SAML2Utils.asDOMDocument(samlResponse); - String assertion = DOMUtils.serializeNode(doc); - bean.setAssertion(assertion); - - String principleId = null; - String givenName = null; - String familyName = null; - String birthday = null; - - for (org.opensaml.saml2.core.Assertion saml2assertion : saml2assertions) { - - try { - principleId = saml2assertion.getSubject().getNameID().getValue(); - - } catch (Exception e) { - log.warn("Can not read SubjectNameId", e); - } - - //loop through the nodes to get what we want - List<AttributeStatement> attributeStatements = saml2assertion.getAttributeStatements(); - for (int i = 0; i < attributeStatements.size(); i++) - { - List<Attribute> attributes = attributeStatements.get(i).getAttributes(); - for (int x = 0; x < attributes.size(); x++) - { - String strAttributeName = attributes.get(x).getDOM().getAttribute("Name"); - - if (strAttributeName.equals(PVPConstants.PRINCIPAL_NAME_NAME)) - familyName = attributes.get(x).getAttributeValues().get(0).getDOM().getFirstChild().getNodeValue(); - if (strAttributeName.equals(PVPConstants.GIVEN_NAME_NAME)) - givenName = attributes.get(x).getAttributeValues().get(0).getDOM().getFirstChild().getNodeValue(); - - if (strAttributeName.equals(PVPConstants.BIRTHDATE_NAME)) { - birthday = attributes.get(x).getAttributeValues().get(0).getDOM().getFirstChild().getNodeValue(); - } - } - } - request.getSession().setAttribute(Constants.SESSION_NAMEIDFORMAT, - saml2assertion.getSubject().getNameID().getFormat()); - request.getSession().setAttribute(Constants.SESSION_NAMEID, - saml2assertion.getSubject().getNameID().getValue()); - - } - - bean.setPrincipleId(principleId); - bean.setDateOfBirth(birthday); - bean.setFamilyName(familyName); - bean.setGivenName(givenName); - bean.setLogin(true); - - setAnser(request, response, bean); - return; - - - } else { - bean.setErrorMessage("Der Anmeldevorgang wurde abgebrochen.<br>Eine genaue Beschreibung des Fehlers finden Sie in der darunterliegenden Assertion."); - setAnser(request, response, bean); - return; - - } - - } catch (Exception e) { - log.warn(e); - bean.setErrorMessage("Internal Error: " + e.getMessage()); - setAnser(request, response, bean); - return; - } - - } - - private void setAnser(HttpServletRequest request, HttpServletResponse response, ApplicationBean answersBean) throws ServletException, IOException { - // store bean in session - request.setAttribute("answers", answersBean); - - // you now can forward to some view, for example some results.jsp - request.getRequestDispatcher("demoapp.jsp").forward(request, response); - - } - - /** - * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse - * response) - */ - protected void doGet(HttpServletRequest request, - HttpServletResponse response) throws ServletException, IOException { - - process(request, response); - } - - - /** - * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse - * response) - */ - protected void doPost(HttpServletRequest request, - HttpServletResponse response) throws ServletException, IOException { - process(request, response); - } + + private static final long serialVersionUID = -2129228304760706063L; + + private void process(HttpServletRequest request, + HttpServletResponse response) throws ServletException, IOException { + + final ApplicationBean bean = new ApplicationBean(); + + log.debug("Receive request on secure-area endpoint ..."); + + final String method = request.getMethod(); + final HttpSession session = request.getSession(); + if (session == null) { + log.info("NO HTTP Session"); + bean.setErrorMessage("NO HTTP session"); + setAnser(request, response, bean); + return; + } + + try { + final Configuration config = Configuration.getInstance(); + Response samlResponse = null; + + if (method.equals("GET")) { + log.debug("Find possible SAML2 Redirect-Binding response ..."); + final HTTPRedirectDeflateDecoder decode = new HTTPRedirectDeflateDecoder(new BasicParserPool()); + final BasicSAMLMessageContext<Response, ?, ?> messageContext = + new BasicSAMLMessageContext<>(); + + messageContext.setInboundMessageTransport(new HttpServletRequestAdapter(request)); + messageContext.setPeerEntityRole(SPSSODescriptor.DEFAULT_ELEMENT_NAME); + + messageContext.setMetadataProvider(config.getMetaDataProvier()); + + final MetadataCredentialResolver resolver = new MetadataCredentialResolver(config + .getMetaDataProvier()); + final List<KeyInfoProvider> keyInfoProvider = new ArrayList<>(); + keyInfoProvider.add(new DSAKeyValueProvider()); + keyInfoProvider.add(new RSAKeyValueProvider()); + keyInfoProvider.add(new InlineX509DataProvider()); + final KeyInfoCredentialResolver keyInfoResolver = new BasicProviderKeyInfoCredentialResolver( + keyInfoProvider); + final ExplicitKeySignatureTrustEngine engine = new ExplicitKeySignatureTrustEngine( + resolver, keyInfoResolver); + + final SAML2HTTPRedirectDeflateSignatureRule signatureRule = new SAML2HTTPRedirectDeflateSignatureRule( + engine); + final SAML2AuthnRequestsSignedRule signedRole = new SAML2AuthnRequestsSignedRule(); + final BasicSecurityPolicy policy = new BasicSecurityPolicy(); + policy.getPolicyRules().add(signatureRule); + policy.getPolicyRules().add(signedRole); + final SecurityPolicyResolver resolver1 = new StaticSecurityPolicyResolver(policy); + messageContext.setSecurityPolicyResolver(resolver1); + + decode.decode(messageContext); + + log.info("PVP2 Assertion with Redirect-Binding is valid"); + + } else if (method.equals("POST")) { + log.debug("Find possible SAML2 Post-Binding response ..."); + // Decode with HttpPost Binding + final HTTPPostDecoder decode = new HTTPPostDecoder(new BasicParserPool()); + final BasicSAMLMessageContext<Response, ?, ?> messageContext = + new BasicSAMLMessageContext<>(); + messageContext + .setInboundMessageTransport(new HttpServletRequestAdapter( + request)); + decode.decode(messageContext); + + samlResponse = (Response) messageContext.getInboundMessage(); + + final Signature sign = samlResponse.getSignature(); + if (sign == null) { + log.info("Only http POST Requests can be used"); + bean.setErrorMessage("Only http POST Requests can be used"); + setAnser(request, response, bean); + return; + } + + // Validate Signature + final SAMLSignatureProfileValidator profileValidator = new SAMLSignatureProfileValidator(); + profileValidator.validate(sign); + + // Verify Signature + final List<KeyInfoProvider> keyInfoProvider = new ArrayList<>(); + keyInfoProvider.add(new DSAKeyValueProvider()); + keyInfoProvider.add(new RSAKeyValueProvider()); + keyInfoProvider.add(new InlineX509DataProvider()); + + final KeyInfoCredentialResolver keyInfoResolver = new BasicProviderKeyInfoCredentialResolver( + keyInfoProvider); + + final MetadataCredentialResolverFactory credentialResolverFactory = MetadataCredentialResolverFactory + .getFactory(); + final MetadataCredentialResolver credentialResolver = credentialResolverFactory.getInstance(config + .getMetaDataProvier()); + + final CriteriaSet criteriaSet = new CriteriaSet(); + criteriaSet.add(new MetadataCriteria(IDPSSODescriptor.DEFAULT_ELEMENT_NAME, + SAMLConstants.SAML20P_NS)); + criteriaSet.add(new EntityIDCriteria(config.getPVP2IDPMetadataEntityName())); + criteriaSet.add(new UsageCriteria(UsageType.SIGNING)); + + final ExplicitKeySignatureTrustEngine trustEngine = new ExplicitKeySignatureTrustEngine( + credentialResolver, keyInfoResolver); + trustEngine.validate(sign, criteriaSet); + + log.info("PVP2 Assertion with POST-Binding is valid"); + + } else { + bean.setErrorMessage("Die Demoapplikation unterstützt nur SAML2 POST-Binding."); + setAnser(request, response, bean); + return; + + } + + if (samlResponse.getStatus().getStatusCode().getValue().equals(StatusCode.SUCCESS_URI)) { + + final List<org.opensaml.saml2.core.Assertion> saml2assertions = + new ArrayList<>(); + + // check encrypted Assertion + final List<EncryptedAssertion> encryAssertionList = samlResponse.getEncryptedAssertions(); + if (encryAssertionList != null && encryAssertionList.size() > 0) { + // decrypt assertions + + log.debug("Found encryped assertion. Start decryption ..."); + + final KeyStore keyStore = config.getPVP2KeyStore(); + + final X509Credential authDecCredential = new KeyStoreX509CredentialAdapter( + keyStore, + config.getPVP2KeystoreAuthRequestEncryptionKeyAlias(), + config.getPVP2KeystoreAuthRequestEncryptionKeyPassword().toCharArray()); + + final StaticKeyInfoCredentialResolver skicr = + new StaticKeyInfoCredentialResolver(authDecCredential); + + final ChainingEncryptedKeyResolver encryptedKeyResolver = new ChainingEncryptedKeyResolver(); + encryptedKeyResolver.getResolverChain().add(new InlineEncryptedKeyResolver()); + encryptedKeyResolver.getResolverChain().add(new EncryptedElementTypeEncryptedKeyResolver()); + encryptedKeyResolver.getResolverChain().add(new SimpleRetrievalMethodEncryptedKeyResolver()); + + final Decrypter samlDecrypter = + new Decrypter(null, skicr, encryptedKeyResolver); + + for (final EncryptedAssertion encAssertion : encryAssertionList) { + final Assertion decryptedAssertion = samlDecrypter.decrypt(encAssertion); + samlResponse.getAssertions().add(decryptedAssertion); + log.debug("Decrypted Assertion: " + DOMUtils.serializeNode(SAML2Utils.asDOMDocument( + decryptedAssertion))); + + } + + log.debug("Assertion decryption finished. "); + + } else { + log.debug("Assertiojn is not encryted. Use it as it is"); + + } + + // set assertion + final org.w3c.dom.Document doc = SAML2Utils.asDOMDocument(samlResponse); + final String assertion = DOMUtils.serializeNode(doc); + bean.setAssertion(assertion); + + String principleId = null; + String givenName = null; + String familyName = null; + String birthday = null; + + log.debug("Find #" + samlResponse.getAssertions().size() + " assertions after decryption"); + + for (final org.opensaml.saml2.core.Assertion saml2assertion : samlResponse.getAssertions()) { + + try { + principleId = saml2assertion.getSubject().getNameID().getValue(); + + } catch (final Exception e) { + log.warn("Can not read SubjectNameId", e); + } + + // loop through the nodes to get what we want + final List<AttributeStatement> attributeStatements = saml2assertion.getAttributeStatements(); + for (final AttributeStatement attributeStatement : attributeStatements) { + final List<Attribute> attributes = attributeStatement.getAttributes(); + for (final Attribute attribute : attributes) { + + final String strAttributeName = attribute.getName(); + + log.debug("Find attribute with name: " + strAttributeName + " and value: " + + attribute.getAttributeValues().get(0).getDOM().getNodeValue()); + + if (strAttributeName.equals(PVPConstants.PRINCIPAL_NAME_NAME)) { + familyName = attribute.getAttributeValues().get(0).getDOM().getFirstChild().getNodeValue(); + + } + + if (strAttributeName.equals(PVPConstants.GIVEN_NAME_NAME)) { + givenName = attribute.getAttributeValues().get(0).getDOM().getFirstChild().getNodeValue(); + + } + + if (strAttributeName.equals(PVPConstants.BIRTHDATE_NAME)) { + birthday = attribute.getAttributeValues().get(0).getDOM().getFirstChild().getNodeValue(); + + } + + if (strAttributeName.equals(PVPConstants.BPK_NAME)) { + principleId = attribute.getAttributeValues().get(0).getDOM().getFirstChild().getNodeValue(); + + } + } + } + request.getSession().setAttribute(Constants.SESSION_NAMEIDFORMAT, + saml2assertion.getSubject().getNameID().getFormat()); + request.getSession().setAttribute(Constants.SESSION_NAMEID, + saml2assertion.getSubject().getNameID().getValue()); + + } + + bean.setPrincipleId(principleId); + bean.setDateOfBirth(birthday); + bean.setFamilyName(familyName); + bean.setGivenName(givenName); + bean.setLogin(true); + + setAnser(request, response, bean); + return; + + } else { + bean.setErrorMessage( + "Der Anmeldevorgang wurde abgebrochen.<br>Eine genaue Beschreibung des Fehlers finden Sie in der darunterliegenden Assertion."); + setAnser(request, response, bean); + return; + + } + + } catch (final Exception e) { + log.warn(e.getMessage(), e); + bean.setErrorMessage("Internal Error: " + e.getMessage()); + setAnser(request, response, bean); + return; + } + + } + + private void setAnser(HttpServletRequest request, HttpServletResponse response, ApplicationBean answersBean) + throws ServletException, IOException { + // store bean in session + request.setAttribute("answers", answersBean); + + // you now can forward to some view, for example some results.jsp + request.getRequestDispatcher("demoapp.jsp").forward(request, response); + + } + + /** + * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse + * response) + */ + @Override + protected void doGet(HttpServletRequest request, + HttpServletResponse response) throws ServletException, IOException { + + process(request, response); + } + + /** + * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse + * response) + */ + @Override + protected void doPost(HttpServletRequest request, + HttpServletResponse response) throws ServletException, IOException { + process(request, response); + } } diff --git a/id/oa/src/main/java/at/gv/egovernment/moa/id/demoOA/servlet/pvp2/Index.java b/id/oa/src/main/java/at/gv/egovernment/moa/id/demoOA/servlet/pvp2/Index.java index bac3e1949..1b0eb35c9 100644 --- a/id/oa/src/main/java/at/gv/egovernment/moa/id/demoOA/servlet/pvp2/Index.java +++ b/id/oa/src/main/java/at/gv/egovernment/moa/id/demoOA/servlet/pvp2/Index.java @@ -90,241 +90,240 @@ import at.gv.egovernment.moa.id.demoOA.utils.ApplicationBean; import at.gv.egovernment.moa.id.demoOA.utils.SAML2Utils; import at.gv.egovernment.moa.util.MiscUtil; +public class Index extends HttpServlet { + private static final long serialVersionUID = -2129228304760706063L; + private static final Logger log = LoggerFactory + .getLogger(Index.class); -public class Index extends HttpServlet { + private void process(HttpServletRequest request, + HttpServletResponse response) throws ServletException, IOException { + + final ApplicationBean bean = new ApplicationBean(); + + final String method = request.getMethod(); + final HttpSession session = request.getSession(); + if (session == null) { + log.info("NO HTTP Session"); + bean.setErrorMessage("NO HTTP session"); + setAnser(request, response, bean); + return; + } + + if (method.equals("GET")) { + try { + final Configuration config = Configuration.getInstance(); + + // Decode with HttpPost Binding + final HTTPRedirectDeflateDecoder decode = new HTTPRedirectDeflateDecoder( + new BasicParserPool()); + final BasicSAMLMessageContext<SAMLObject, ?, ?> messageContext = + new BasicSAMLMessageContext<>(); + messageContext + .setInboundMessageTransport(new HttpServletRequestAdapter(request)); + + decode.decode(messageContext); + + messageContext.setMetadataProvider(config.getMetaDataProvier()); + final CriteriaSet criteriaSet = new CriteriaSet(); + criteriaSet.add(new MetadataCriteria(IDPSSODescriptor.DEFAULT_ELEMENT_NAME, + SAMLConstants.SAML20P_NS)); + criteriaSet.add(new EntityIDCriteria(config.getPVP2IDPMetadataEntityName())); + criteriaSet.add(new UsageCriteria(UsageType.SIGNING)); + + final MetadataCredentialResolverFactory credentialResolverFactory = MetadataCredentialResolverFactory + .getFactory(); + final MetadataCredentialResolver credentialResolver = credentialResolverFactory.getInstance(config + .getMetaDataProvier()); + + // Verify Signature + final List<KeyInfoProvider> keyInfoProvider = new ArrayList<>(); + keyInfoProvider.add(new DSAKeyValueProvider()); + keyInfoProvider.add(new RSAKeyValueProvider()); + keyInfoProvider.add(new InlineX509DataProvider()); + + final KeyInfoCredentialResolver keyInfoResolver = new BasicProviderKeyInfoCredentialResolver( + keyInfoProvider); + + final ExplicitKeySignatureTrustEngine trustEngine = new ExplicitKeySignatureTrustEngine( + credentialResolver, keyInfoResolver); + + final SAML2HTTPRedirectDeflateSignatureRule signatureRule = new SAML2HTTPRedirectDeflateSignatureRule( + trustEngine); + final SAML2AuthnRequestsSignedRule signedRole = new SAML2AuthnRequestsSignedRule(); + final BasicSecurityPolicy policy = new BasicSecurityPolicy(); + policy.getPolicyRules().add(signatureRule); + policy.getPolicyRules().add(signedRole); + final SecurityPolicyResolver resolver = new StaticSecurityPolicyResolver( + policy); + messageContext.setSecurityPolicyResolver(resolver); + + messageContext.setPeerEntityRole(IDPSSODescriptor.DEFAULT_ELEMENT_NAME); + + signatureRule.evaluate(messageContext); + + final SignableXMLObject samlResponse = (SignableXMLObject) messageContext.getInboundMessage(); + + log.info("PVP2 statusrequest or statusresponse is valid"); + + if (samlResponse instanceof LogoutResponse) { + + final LogoutResponse sloResp = (LogoutResponse) samlResponse; + + // set assertion + final org.w3c.dom.Document doc = SAML2Utils.asDOMDocument(samlResponse); + final String assertion = DOMUtils.serializeNode(doc); + bean.setAssertion(assertion); + + if (sloResp.getStatus().getStatusCode().getValue().equals(StatusCode.SUCCESS_URI)) { + + bean.setSuccessMessage("Der Single Log-Out Vorgang konnte erfolgreich durchgeführt werden."); + + setAnser(request, response, bean); + return; + + } else { + bean.setErrorMessage( + "Der Single Log-Out Vorgang war nicht erfolgreich.<br>Bitte schließen Sie aus sicherheitsgründen den Browser!"); + setAnser(request, response, bean); + return; + + } + + } else if (samlResponse instanceof LogoutRequest) { + // invalidate user session + request.getSession().invalidate(); + + // build LogOutResponse + final LogoutResponse sloResp = SAML2Utils.createSAMLObject(LogoutResponse.class); + final SecureRandomIdentifierGenerator gen = new SecureRandomIdentifierGenerator(); + sloResp.setID(gen.generateIdentifier()); + sloResp.setIssueInstant(new DateTime()); + final NameID name = SAML2Utils.createSAMLObject(NameID.class); + final Issuer issuer = SAML2Utils.createSAMLObject(Issuer.class); + + String serviceURL = config.getPublicUrlPreFix(request); + if (!serviceURL.endsWith("/")) { + serviceURL = serviceURL + "/"; + } + name.setValue(serviceURL); + issuer.setValue(serviceURL); + issuer.setFormat(NameIDType.ENTITY); + sloResp.setIssuer(issuer); + + final Status status = SAML2Utils.createSAMLObject(Status.class); + sloResp.setStatus(status); + final StatusCode statusCode = SAML2Utils.createSAMLObject(StatusCode.class); + statusCode.setValue(StatusCode.SUCCESS_URI); + status.setStatusCode(statusCode); + + final String entityname = config.getPVP2IDPMetadataEntityName(); + if (MiscUtil.isEmpty(entityname)) { + log.info("No IDP EntityName configurated"); + throw new ConfigurationException("No IDP EntityName configurated"); + } + + // get IDP metadata from metadataprovider + final HTTPMetadataProvider idpmetadata = config.getMetaDataProvier(); + final EntityDescriptor idpEntity = idpmetadata.getEntityDescriptor(entityname); + if (idpEntity == null) { + log.info("IDP EntityName is not found in IDP Metadata"); + throw new ConfigurationException("IDP EntityName is not found in IDP Metadata"); + } + + // select authentication-service url from metadata + SingleLogoutService redirectEndpoint = null; + for (final SingleLogoutService sss : idpEntity.getIDPSSODescriptor(SAMLConstants.SAML20P_NS) + .getSingleLogoutServices()) { + + // Get the service address for the binding you wish to use + if (sss.getBinding().equals(SAMLConstants.SAML2_REDIRECT_BINDING_URI)) { + redirectEndpoint = sss; + } + } + sloResp.setDestination(redirectEndpoint.getLocation()); + + // sign authentication request + final KeyStore keyStore = config.getPVP2KeyStore(); + final X509Credential authcredential = new KeyStoreX509CredentialAdapter( + keyStore, + config.getPVP2KeystoreAuthRequestKeyAlias(), + config.getPVP2KeystoreAuthRequestKeyPassword().toCharArray()); + + final Signature signer = SAML2Utils.createSAMLObject(Signature.class); + signer.setSignatureAlgorithm(SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA1); + signer.setCanonicalizationAlgorithm(SignatureConstants.ALGO_ID_C14N_EXCL_OMIT_COMMENTS); + signer.setSigningCredential(authcredential); + sloResp.setSignature(signer); + + final HTTPRedirectDeflateEncoder encoder = new HTTPRedirectDeflateEncoder(); + final HttpServletResponseAdapter responseAdapter = new HttpServletResponseAdapter( + response, true); + final BasicSAMLMessageContext<SAMLObject, SAMLObject, SAMLObject> context = + new BasicSAMLMessageContext<>(); + final SingleSignOnService service = new SingleSignOnServiceBuilder() + .buildObject(); + service.setBinding("urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"); + service.setLocation(redirectEndpoint.getLocation()); + + context.setOutboundSAMLMessageSigningCredential(authcredential); + context.setPeerEntityEndpoint(service); + context.setOutboundSAMLMessage(sloResp); + context.setOutboundMessageTransport(responseAdapter); + context.setRelayState(messageContext.getRelayState()); + + encoder.encode(context); + + } else { + bean.setErrorMessage("Kein gültiger LogOut Request oder LogOut Response"); + setAnser(request, response, bean); + return; + + } + + } catch (final Exception e) { + log.warn("Internal error", e); + bean.setErrorMessage("Internal Error: " + e.getMessage()); + setAnser(request, response, bean); + return; + } + + } else { + bean.setErrorMessage("Die Demoapplikation unterstützt nur SAML2 POST-Binding."); + setAnser(request, response, bean); + return; + + } + } + + private void setAnser(HttpServletRequest request, HttpServletResponse response, ApplicationBean answersBean) + throws ServletException, IOException { + // store bean in session + request.setAttribute("answers", answersBean); + + // you now can forward to some view, for example some results.jsp + request.getRequestDispatcher("demoapp.jsp").forward(request, response); + + } + + /** + * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse + * response) + */ + @Override + protected void doGet(HttpServletRequest request, + HttpServletResponse response) throws ServletException, IOException { + + process(request, response); + } - private static final long serialVersionUID = -2129228304760706063L; - private static final Logger log = LoggerFactory - .getLogger(Index.class); - - - private void process(HttpServletRequest request, - HttpServletResponse response) throws ServletException, IOException { - - - ApplicationBean bean = new ApplicationBean(); - - - String method = request.getMethod(); - HttpSession session = request.getSession(); - if (session == null) { - log.info("NO HTTP Session"); - bean.setErrorMessage("NO HTTP session"); - setAnser(request, response, bean); - return; - } - - if (method.equals("GET")) { - try { - Configuration config = Configuration.getInstance(); - - //Decode with HttpPost Binding - HTTPRedirectDeflateDecoder decode = new HTTPRedirectDeflateDecoder( - new BasicParserPool()); - BasicSAMLMessageContext<SAMLObject, ?, ?> messageContext = new BasicSAMLMessageContext<SAMLObject, SAMLObject, SAMLObject>(); - messageContext - .setInboundMessageTransport(new HttpServletRequestAdapter(request)); - - decode.decode(messageContext); - - messageContext.setMetadataProvider(config.getMetaDataProvier()); - CriteriaSet criteriaSet = new CriteriaSet(); - criteriaSet.add(new MetadataCriteria(IDPSSODescriptor.DEFAULT_ELEMENT_NAME, SAMLConstants.SAML20P_NS)); - criteriaSet.add(new EntityIDCriteria(config.getPVP2IDPMetadataEntityName())); - criteriaSet.add(new UsageCriteria(UsageType.SIGNING)); - - MetadataCredentialResolverFactory credentialResolverFactory = MetadataCredentialResolverFactory.getFactory(); - MetadataCredentialResolver credentialResolver = credentialResolverFactory.getInstance(config.getMetaDataProvier()); - - //Verify Signature - List<KeyInfoProvider> keyInfoProvider = new ArrayList<KeyInfoProvider>(); - keyInfoProvider.add(new DSAKeyValueProvider()); - keyInfoProvider.add(new RSAKeyValueProvider()); - keyInfoProvider.add(new InlineX509DataProvider()); - - KeyInfoCredentialResolver keyInfoResolver = new BasicProviderKeyInfoCredentialResolver( - keyInfoProvider); - - - ExplicitKeySignatureTrustEngine trustEngine = new ExplicitKeySignatureTrustEngine(credentialResolver, keyInfoResolver); - - - SAML2HTTPRedirectDeflateSignatureRule signatureRule = new SAML2HTTPRedirectDeflateSignatureRule( - trustEngine); - SAML2AuthnRequestsSignedRule signedRole = new SAML2AuthnRequestsSignedRule(); - BasicSecurityPolicy policy = new BasicSecurityPolicy(); - policy.getPolicyRules().add(signatureRule); - policy.getPolicyRules().add(signedRole); - SecurityPolicyResolver resolver = new StaticSecurityPolicyResolver( - policy); - messageContext.setSecurityPolicyResolver(resolver); - - messageContext.setPeerEntityRole(IDPSSODescriptor.DEFAULT_ELEMENT_NAME); - - signatureRule.evaluate(messageContext); - - SignableXMLObject samlResponse = (SignableXMLObject) messageContext.getInboundMessage(); - - - - log.info("PVP2 statusrequest or statusresponse is valid"); - - - if (samlResponse instanceof LogoutResponse) { - - LogoutResponse sloResp = (LogoutResponse) samlResponse; - - //set assertion - org.w3c.dom.Document doc = SAML2Utils.asDOMDocument(samlResponse); - String assertion = DOMUtils.serializeNode(doc); - bean.setAssertion(assertion); - - if (sloResp.getStatus().getStatusCode().getValue().equals(StatusCode.SUCCESS_URI)) { - - bean.setSuccessMessage("Der Single Log-Out Vorgang konnte erfolgreich durchgeführt werden."); - - setAnser(request, response, bean); - return; - - } else { - bean.setErrorMessage("Der Single Log-Out Vorgang war nicht erfolgreich.<br>Bitte schließen Sie aus sicherheitsgründen den Browser!"); - setAnser(request, response, bean); - return; - - } - - } else if (samlResponse instanceof LogoutRequest) { - //invalidate user session - request.getSession().invalidate(); - - //build LogOutResponse - LogoutResponse sloResp = SAML2Utils.createSAMLObject(LogoutResponse.class); - SecureRandomIdentifierGenerator gen = new SecureRandomIdentifierGenerator(); - sloResp.setID(gen.generateIdentifier()); - sloResp.setIssueInstant(new DateTime()); - NameID name = SAML2Utils.createSAMLObject(NameID.class); - Issuer issuer = SAML2Utils.createSAMLObject(Issuer.class); - - String serviceURL = config.getPublicUrlPreFix(request); - if (!serviceURL.endsWith("/")) - serviceURL = serviceURL + "/"; - name.setValue(serviceURL); - issuer.setValue(serviceURL); - issuer.setFormat(NameIDType.ENTITY); - sloResp.setIssuer(issuer); - - Status status = SAML2Utils.createSAMLObject(Status.class); - sloResp.setStatus(status); - StatusCode statusCode = SAML2Utils.createSAMLObject(StatusCode.class); - statusCode.setValue(StatusCode.SUCCESS_URI); - status.setStatusCode(statusCode ); - - String entityname = config.getPVP2IDPMetadataEntityName(); - if (MiscUtil.isEmpty(entityname)) { - log.info("No IDP EntityName configurated"); - throw new ConfigurationException("No IDP EntityName configurated"); - } - - //get IDP metadata from metadataprovider - HTTPMetadataProvider idpmetadata = config.getMetaDataProvier(); - EntityDescriptor idpEntity = idpmetadata.getEntityDescriptor(entityname); - if (idpEntity == null) { - log.info("IDP EntityName is not found in IDP Metadata"); - throw new ConfigurationException("IDP EntityName is not found in IDP Metadata"); - } - - //select authentication-service url from metadata - SingleLogoutService redirectEndpoint = null; - for (SingleLogoutService sss : - idpEntity.getIDPSSODescriptor(SAMLConstants.SAML20P_NS).getSingleLogoutServices()) { - - //Get the service address for the binding you wish to use - if (sss.getBinding().equals(SAMLConstants.SAML2_REDIRECT_BINDING_URI)) { - redirectEndpoint = sss; - } - } - sloResp.setDestination(redirectEndpoint.getLocation()); - - //sign authentication request - KeyStore keyStore = config.getPVP2KeyStore(); - X509Credential authcredential = new KeyStoreX509CredentialAdapter( - keyStore, - config.getPVP2KeystoreAuthRequestKeyAlias(), - config.getPVP2KeystoreAuthRequestKeyPassword().toCharArray()); - - Signature signer = SAML2Utils.createSAMLObject(Signature.class); - signer.setSignatureAlgorithm(SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA1); - signer.setCanonicalizationAlgorithm(SignatureConstants.ALGO_ID_C14N_EXCL_OMIT_COMMENTS); - signer.setSigningCredential(authcredential); - sloResp.setSignature(signer); - - HTTPRedirectDeflateEncoder encoder = new HTTPRedirectDeflateEncoder(); - HttpServletResponseAdapter responseAdapter = new HttpServletResponseAdapter( - response, true); - BasicSAMLMessageContext<SAMLObject, SAMLObject, SAMLObject> context = new BasicSAMLMessageContext<SAMLObject, SAMLObject, SAMLObject>(); - SingleSignOnService service = new SingleSignOnServiceBuilder() - .buildObject(); - service.setBinding("urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"); - service.setLocation(redirectEndpoint.getLocation());; - - context.setOutboundSAMLMessageSigningCredential(authcredential); - context.setPeerEntityEndpoint(service); - context.setOutboundSAMLMessage(sloResp); - context.setOutboundMessageTransport(responseAdapter); - context.setRelayState(messageContext.getRelayState()); - - encoder.encode(context); - - } else { - bean.setErrorMessage("Kein gültiger LogOut Request oder LogOut Response"); - setAnser(request, response, bean); - return; - - } - - - } catch (Exception e) { - log.warn("Internal error", e); - bean.setErrorMessage("Internal Error: " + e.getMessage()); - setAnser(request, response, bean); - return; - } - - } else { - bean.setErrorMessage("Die Demoapplikation unterstützt nur SAML2 POST-Binding."); - setAnser(request, response, bean); - return; - - } - } - - private void setAnser(HttpServletRequest request, HttpServletResponse response, ApplicationBean answersBean) throws ServletException, IOException { - // store bean in session - request.setAttribute("answers", answersBean); - - // you now can forward to some view, for example some results.jsp - request.getRequestDispatcher("demoapp.jsp").forward(request, response); - - } - - /** - * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse - * response) - */ - protected void doGet(HttpServletRequest request, - HttpServletResponse response) throws ServletException, IOException { - - process(request, response); - } - - - /** - * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse - * response) - */ - protected void doPost(HttpServletRequest request, - HttpServletResponse response) throws ServletException, IOException { - process(request, response); - } + /** + * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse + * response) + */ + @Override + protected void doPost(HttpServletRequest request, + HttpServletResponse response) throws ServletException, IOException { + process(request, response); + } } diff --git a/id/oa/src/main/java/at/gv/egovernment/moa/id/demoOA/servlet/pvp2/SingleLogOut.java b/id/oa/src/main/java/at/gv/egovernment/moa/id/demoOA/servlet/pvp2/SingleLogOut.java index 9bd0ff2e3..49d7b2cc6 100644 --- a/id/oa/src/main/java/at/gv/egovernment/moa/id/demoOA/servlet/pvp2/SingleLogOut.java +++ b/id/oa/src/main/java/at/gv/egovernment/moa/id/demoOA/servlet/pvp2/SingleLogOut.java @@ -62,156 +62,158 @@ import at.gv.egovernment.moa.id.demoOA.exception.ConfigurationException; import at.gv.egovernment.moa.id.demoOA.utils.SAML2Utils; import at.gv.egovernment.moa.util.MiscUtil; - /** * Servlet implementation class Authenticate */ public class SingleLogOut extends HttpServlet { - private static final long serialVersionUID = 1L; - - private static final Logger log = LoggerFactory - .getLogger(SingleLogOut.class); - - /** - * @see HttpServlet#HttpServlet() - */ - public SingleLogOut() { - super(); - DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); - factory.setNamespaceAware(true); - try { - builder = factory.newDocumentBuilder(); - - } catch (ParserConfigurationException e) { - log.warn("PVP2 AuthenticationServlet can not be initialized.", e); - } - } - - DocumentBuilder builder; - - - //generate AuthenticationRequest - protected void process(HttpServletRequest request, - HttpServletResponse response) throws ServletException, IOException { - try { - - Configuration config = Configuration.getInstance(); - config.initializePVP2Login(); - - String nameIDFormat = (String) request.getSession().getAttribute(Constants.SESSION_NAMEIDFORMAT); - String nameID = (String) request.getSession().getAttribute(Constants.SESSION_NAMEID); - - if (MiscUtil.isEmpty(nameID) || MiscUtil.isEmpty(nameIDFormat)) { - log.warn("No user information found. Single Log-Out not possible"); - throw new ServletException("No user information found. Single Log-Out not possible"); - - } else - log.info("Fount user information for user nameID: " + nameID - + " , nameIDFormat: " + nameIDFormat - + ". Build Single Log-Out request ..."); - - //invalidate local session - request.getSession().invalidate(); - - //build Single LogOut request - LogoutRequest sloReq = SAML2Utils.createSAMLObject(LogoutRequest.class); - SecureRandomIdentifierGenerator gen = new SecureRandomIdentifierGenerator(); - sloReq.setID(gen.generateIdentifier()); - sloReq.setIssueInstant(new DateTime()); - NameID name = SAML2Utils.createSAMLObject(NameID.class); - Issuer issuer = SAML2Utils.createSAMLObject(Issuer.class); - - String serviceURL = config.getPublicUrlPreFix(request); - if (!serviceURL.endsWith("/")) - serviceURL = serviceURL + "/"; - name.setValue(serviceURL); - issuer.setValue(serviceURL); - issuer.setFormat(NameIDType.ENTITY); - sloReq.setIssuer(issuer); - - NameID userNameID = SAML2Utils.createSAMLObject(NameID.class); - sloReq.setNameID(userNameID); - userNameID.setFormat(nameIDFormat); - userNameID.setValue(nameID); - - String entityname = config.getPVP2IDPMetadataEntityName(); - if (MiscUtil.isEmpty(entityname)) { - log.info("No IDP EntityName configurated"); - throw new ConfigurationException("No IDP EntityName configurated"); - } - - //get IDP metadata from metadataprovider - HTTPMetadataProvider idpmetadata = config.getMetaDataProvier(); - EntityDescriptor idpEntity = idpmetadata.getEntityDescriptor(entityname); - if (idpEntity == null) { - log.info("IDP EntityName is not found in IDP Metadata"); - throw new ConfigurationException("IDP EntityName is not found in IDP Metadata"); - } - - //select authentication-service url from metadata - SingleLogoutService redirectEndpoint = null; - for (SingleLogoutService sss : - idpEntity.getIDPSSODescriptor(SAMLConstants.SAML20P_NS).getSingleLogoutServices()) { - - //Get the service address for the binding you wish to use - if (sss.getBinding().equals(SAMLConstants.SAML2_REDIRECT_BINDING_URI)) { - redirectEndpoint = sss; - } - } - sloReq.setDestination(redirectEndpoint.getLocation()); - - //sign authentication request - KeyStore keyStore = config.getPVP2KeyStore(); - X509Credential authcredential = new KeyStoreX509CredentialAdapter( - keyStore, - config.getPVP2KeystoreAuthRequestKeyAlias(), - config.getPVP2KeystoreAuthRequestKeyPassword().toCharArray()); - - Signature signer = SAML2Utils.createSAMLObject(Signature.class); - signer.setSignatureAlgorithm(SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA1); - signer.setCanonicalizationAlgorithm(SignatureConstants.ALGO_ID_C14N_EXCL_OMIT_COMMENTS); - signer.setSigningCredential(authcredential); - sloReq.setSignature(signer); - - HTTPRedirectDeflateEncoder encoder = new HTTPRedirectDeflateEncoder(); - HttpServletResponseAdapter responseAdapter = new HttpServletResponseAdapter( - response - , true); - BasicSAMLMessageContext<SAMLObject, SAMLObject, SAMLObject> context = new BasicSAMLMessageContext<SAMLObject, SAMLObject, SAMLObject>(); - SingleSignOnService service = new SingleSignOnServiceBuilder() - .buildObject(); - service.setBinding(SAMLConstants.SAML2_REDIRECT_BINDING_URI); - service.setLocation(redirectEndpoint.getLocation()); - context.setOutboundSAMLMessageSigningCredential(authcredential); - context.setPeerEntityEndpoint(service); - context.setOutboundSAMLMessage(sloReq); - context.setOutboundMessageTransport(responseAdapter); - - encoder.encode(context); - - } catch (Exception e) { - log.warn("Authentication Request can not be generated", e); - throw new ServletException("Authentication Request can not be generated.", e); - } - } - - /** - * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse - * response) - */ - protected void doGet(HttpServletRequest request, - HttpServletResponse response) throws ServletException, IOException { - - process(request, response); - } - - /** - * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse - * response) - */ - protected void doPost(HttpServletRequest request, - HttpServletResponse response) throws ServletException, IOException { - process(request, response); - } + private static final long serialVersionUID = 1L; + + private static final Logger log = LoggerFactory + .getLogger(SingleLogOut.class); + + /** + * @see HttpServlet#HttpServlet() + */ + public SingleLogOut() { + super(); + final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + factory.setNamespaceAware(true); + try { + builder = factory.newDocumentBuilder(); + + } catch (final ParserConfigurationException e) { + log.warn("PVP2 AuthenticationServlet can not be initialized.", e); + } + } + + DocumentBuilder builder; + + // generate AuthenticationRequest + protected void process(HttpServletRequest request, + HttpServletResponse response) throws ServletException, IOException { + try { + + final Configuration config = Configuration.getInstance(); + config.initializePVP2Login(); + + final String nameIDFormat = (String) request.getSession().getAttribute(Constants.SESSION_NAMEIDFORMAT); + final String nameID = (String) request.getSession().getAttribute(Constants.SESSION_NAMEID); + + if (MiscUtil.isEmpty(nameID) || MiscUtil.isEmpty(nameIDFormat)) { + log.warn("No user information found. Single Log-Out not possible"); + throw new ServletException("No user information found. Single Log-Out not possible"); + + } else { + log.info("Fount user information for user nameID: " + nameID + + " , nameIDFormat: " + nameIDFormat + + ". Build Single Log-Out request ..."); + } + + // invalidate local session + request.getSession().invalidate(); + + // build Single LogOut request + final LogoutRequest sloReq = SAML2Utils.createSAMLObject(LogoutRequest.class); + final SecureRandomIdentifierGenerator gen = new SecureRandomIdentifierGenerator(); + sloReq.setID(gen.generateIdentifier()); + sloReq.setIssueInstant(new DateTime()); + final NameID name = SAML2Utils.createSAMLObject(NameID.class); + final Issuer issuer = SAML2Utils.createSAMLObject(Issuer.class); + + String serviceURL = config.getPublicUrlPreFix(request); + if (!serviceURL.endsWith("/")) { + serviceURL = serviceURL + "/"; + } + name.setValue(serviceURL); + issuer.setValue(serviceURL); + issuer.setFormat(NameIDType.ENTITY); + sloReq.setIssuer(issuer); + + final NameID userNameID = SAML2Utils.createSAMLObject(NameID.class); + sloReq.setNameID(userNameID); + userNameID.setFormat(nameIDFormat); + userNameID.setValue(nameID); + + final String entityname = config.getPVP2IDPMetadataEntityName(); + if (MiscUtil.isEmpty(entityname)) { + log.info("No IDP EntityName configurated"); + throw new ConfigurationException("No IDP EntityName configurated"); + } + + // get IDP metadata from metadataprovider + final HTTPMetadataProvider idpmetadata = config.getMetaDataProvier(); + final EntityDescriptor idpEntity = idpmetadata.getEntityDescriptor(entityname); + if (idpEntity == null) { + log.info("IDP EntityName is not found in IDP Metadata"); + throw new ConfigurationException("IDP EntityName is not found in IDP Metadata"); + } + + // select authentication-service url from metadata + SingleLogoutService redirectEndpoint = null; + for (final SingleLogoutService sss : idpEntity.getIDPSSODescriptor(SAMLConstants.SAML20P_NS) + .getSingleLogoutServices()) { + + // Get the service address for the binding you wish to use + if (sss.getBinding().equals(SAMLConstants.SAML2_REDIRECT_BINDING_URI)) { + redirectEndpoint = sss; + } + } + sloReq.setDestination(redirectEndpoint.getLocation()); + + // sign authentication request + final KeyStore keyStore = config.getPVP2KeyStore(); + final X509Credential authcredential = new KeyStoreX509CredentialAdapter( + keyStore, + config.getPVP2KeystoreAuthRequestKeyAlias(), + config.getPVP2KeystoreAuthRequestKeyPassword().toCharArray()); + + final Signature signer = SAML2Utils.createSAMLObject(Signature.class); + signer.setSignatureAlgorithm(SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA1); + signer.setCanonicalizationAlgorithm(SignatureConstants.ALGO_ID_C14N_EXCL_OMIT_COMMENTS); + signer.setSigningCredential(authcredential); + sloReq.setSignature(signer); + + final HTTPRedirectDeflateEncoder encoder = new HTTPRedirectDeflateEncoder(); + final HttpServletResponseAdapter responseAdapter = new HttpServletResponseAdapter( + response, true); + final BasicSAMLMessageContext<SAMLObject, SAMLObject, SAMLObject> context = + new BasicSAMLMessageContext<>(); + final SingleSignOnService service = new SingleSignOnServiceBuilder() + .buildObject(); + service.setBinding(SAMLConstants.SAML2_REDIRECT_BINDING_URI); + service.setLocation(redirectEndpoint.getLocation()); + context.setOutboundSAMLMessageSigningCredential(authcredential); + context.setPeerEntityEndpoint(service); + context.setOutboundSAMLMessage(sloReq); + context.setOutboundMessageTransport(responseAdapter); + + encoder.encode(context); + + } catch (final Exception e) { + log.warn("Authentication Request can not be generated", e); + throw new ServletException("Authentication Request can not be generated.", e); + } + } + + /** + * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse + * response) + */ + @Override + protected void doGet(HttpServletRequest request, + HttpServletResponse response) throws ServletException, IOException { + + process(request, response); + } + + /** + * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse + * response) + */ + @Override + protected void doPost(HttpServletRequest request, + HttpServletResponse response) throws ServletException, IOException { + process(request, response); + } } diff --git a/id/oa/src/main/java/at/gv/egovernment/moa/id/demoOA/utils/AttributeListBuilder.java b/id/oa/src/main/java/at/gv/egovernment/moa/id/demoOA/utils/AttributeListBuilder.java index 1dcc66a56..9dc0d1d6f 100644 --- a/id/oa/src/main/java/at/gv/egovernment/moa/id/demoOA/utils/AttributeListBuilder.java +++ b/id/oa/src/main/java/at/gv/egovernment/moa/id/demoOA/utils/AttributeListBuilder.java @@ -47,19 +47,19 @@ public class AttributeListBuilder implements PVPConstants{ //select PVP2 attributes which are needed for this application - requestedAttributes.add(buildReqAttribute(PVP_VERSION_NAME, PVP_VERSION_FRIENDLY_NAME, true)); + requestedAttributes.add(buildReqAttribute(PVP_VERSION_NAME, PVP_VERSION_FRIENDLY_NAME, false)); requestedAttributes.add(buildReqAttribute(PRINCIPAL_NAME_NAME, PRINCIPAL_NAME_FRIENDLY_NAME, true)); requestedAttributes.add(buildReqAttribute(GIVEN_NAME_NAME, GIVEN_NAME_FRIENDLY_NAME, true)); requestedAttributes.add(buildReqAttribute(BIRTHDATE_NAME, BIRTHDATE_FRIENDLY_NAME, false)); requestedAttributes.add(buildReqAttribute(BPK_NAME, BPK_FRIENDLY_NAME, true)); - requestedAttributes.add(buildReqAttribute(EID_CITIZEN_QAA_LEVEL_NAME, EID_CITIZEN_QAA_LEVEL_FRIENDLY_NAME, true)); - requestedAttributes.add(buildReqAttribute(EID_ISSUING_NATION_NAME, EID_ISSUING_NATION_FRIENDLY_NAME, true)); - requestedAttributes.add(buildReqAttribute(EID_SECTOR_FOR_IDENTIFIER_NAME, EID_SECTOR_FOR_IDENTIFIER_FRIENDLY_NAME, true)); + requestedAttributes.add(buildReqAttribute(EID_CITIZEN_QAA_LEVEL_NAME, EID_CITIZEN_QAA_LEVEL_FRIENDLY_NAME, false)); + requestedAttributes.add(buildReqAttribute(EID_ISSUING_NATION_NAME, EID_ISSUING_NATION_FRIENDLY_NAME, false)); + requestedAttributes.add(buildReqAttribute(EID_SECTOR_FOR_IDENTIFIER_NAME, EID_SECTOR_FOR_IDENTIFIER_FRIENDLY_NAME, false)); requestedAttributes.add(buildReqAttribute(EID_SIGNER_CERTIFICATE_NAME, EID_SIGNER_CERTIFICATE_FRIENDLY_NAME, false)); - requestedAttributes.add(buildReqAttribute(EID_CCS_URL_NAME, EID_CCS_URL_FRIENDLY_NAME, true)); + requestedAttributes.add(buildReqAttribute(EID_CCS_URL_NAME, EID_CCS_URL_FRIENDLY_NAME, false)); requestedAttributes.add(buildReqAttribute(EID_AUTH_BLOCK_NAME, EID_AUTH_BLOCK_FRIENDLY_NAME, false)); - requestedAttributes.add(buildReqAttribute(EID_IDENTITY_LINK_NAME, EID_IDENTITY_LINK_FRIENDLY_NAME, true)); + requestedAttributes.add(buildReqAttribute(EID_IDENTITY_LINK_NAME, EID_IDENTITY_LINK_FRIENDLY_NAME, false)); requestedAttributes.add(buildReqAttribute(MANDATE_TYPE_NAME, MANDATE_TYPE_FRIENDLY_NAME, false)); requestedAttributes.add(buildReqAttribute(MANDATE_FULL_MANDATE_NAME, MANDATE_FULL_MANDATE_FRIENDLY_NAME, false)); diff --git a/id/oa/src/main/resources/logback.xml b/id/oa/src/main/resources/logback.xml new file mode 100644 index 000000000..b94b7476a --- /dev/null +++ b/id/oa/src/main/resources/logback.xml @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="UTF-8"?> +<configuration> + <appender name="DEMO_SP" class="ch.qos.logback.core.rolling.RollingFileAppender"> + <!--See also http://logback.qos.ch/manual/appenders.html#RollingFileAppender--> + <File>${catalina.base}/logs/moa-demo-sp.log</File> + <encoder> + <pattern>%5p | %d{dd HH:mm:ss,SSS} | %X{sessionId} | %X{transactionId} | %X{oaId} | %t | %m%n</pattern> + </encoder> + <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy"> + <maxIndex>1</maxIndex> + <FileNamePattern>${catalina.base}/logs/moa-demo-sp.%i.gz</FileNamePattern> + </rollingPolicy> + <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTrimoa-demo-spggeringPolicy"> + <MaxFileSize>10000KB</MaxFileSize> + </triggeringPolicy> + </appender> + <appender name="stdout" class="ch.qos.logback.core.ConsoleAppender"> + <encoder> + <pattern>%5p | %d{dd HH:mm:ss,SSS} | %X{sessionId} | %X{transactionId} | %X{oaId} |%20.20c | %10t | %m%n</pattern> + </encoder> + </appender> + + <logger name="at.gv.egovernment.moa.id.demoOA" level="info"> + <appender-ref ref="DEMO_SP"/> + </logger> + + <root level="warn"> + <appender-ref ref="stdout"/> + </root> +</configuration> |