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/ConfigWebTool/src/main/java/at/gv/egovernment/moa/id/configuration/auth | |
parent | fc0385dbeee71f1ce18783ef1c7a4d06288fdb0d (diff) | |
parent | 600369d4ffa753716a9572824de7a96a04cb05a7 (diff) | |
download | moa-id-spss-master.tar.gz moa-id-spss-master.tar.bz2 moa-id-spss-master.zip |
Diffstat (limited to 'id/ConfigWebTool/src/main/java/at/gv/egovernment/moa/id/configuration/auth')
5 files changed, 973 insertions, 950 deletions
diff --git a/id/ConfigWebTool/src/main/java/at/gv/egovernment/moa/id/configuration/auth/pvp2/servlets/Authenticate.java b/id/ConfigWebTool/src/main/java/at/gv/egovernment/moa/id/configuration/auth/pvp2/servlets/Authenticate.java index 84fbec0e8..c6946e509 100644 --- a/id/ConfigWebTool/src/main/java/at/gv/egovernment/moa/id/configuration/auth/pvp2/servlets/Authenticate.java +++ b/id/ConfigWebTool/src/main/java/at/gv/egovernment/moa/id/configuration/auth/pvp2/servlets/Authenticate.java @@ -36,7 +36,6 @@ import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.TransformerException; import org.joda.time.DateTime; -import org.opensaml.Configuration; import org.opensaml.common.impl.SecureRandomIdentifierGenerator; import org.opensaml.common.xml.SAMLConstants; import org.opensaml.saml2.core.AuthnContextClassRef; @@ -67,163 +66,167 @@ import at.gv.egovernment.moa.id.configuration.config.ConfigurationProvider; import at.gv.egovernment.moa.id.configuration.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); - - private static DocumentBuilderFactory factory = null; - - static { - initialDocumentBuilderFactory(); - } - - synchronized private static void initialDocumentBuilderFactory() { - factory = DocumentBuilderFactory.newInstance(); - factory.setNamespaceAware(true); - - } - - public Document asDOMDocument(XMLObject object) throws IOException, - MarshallingException, TransformerException, ParserConfigurationException { - try { - DocumentBuilder builder = null; - synchronized (factory) { - builder = factory.newDocumentBuilder(); - - } - - Document document = builder.newDocument(); - Marshaller out = Configuration.getMarshallerFactory().getMarshaller( - object); - out.marshall(object, document); - return document; - - } catch (ParserConfigurationException e) { - log.warn("PVP2 AuthenticationServlet can not be initialized.", e); - throw e; - } - - } - - protected void process(HttpServletRequest request, - HttpServletResponse response, Map<String,String> legacyParameter) throws ServletException, IOException { - try { - - ConfigurationProvider config = ConfigurationProvider.getInstance(); - config.initializePVP2Login(); - - AuthnRequest authReq = SAML2Utils - .createSAMLObject(AuthnRequest.class); - SecureRandomIdentifierGenerator gen = new SecureRandomIdentifierGenerator(); - authReq.setID(gen.generateIdentifier()); - - HttpSession session = request.getSession(); - if (session != null) { - session.setAttribute(Constants.SESSION_PVP2REQUESTID, authReq.getID()); - } - - 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); - - subject.setNameID(name); - authReq.setSubject(subject); - issuer.setFormat(NameIDType.ENTITY); - authReq.setIssuer(issuer); - 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"); - } - - 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"); - } - - 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)) { - redirectEndpoint = sss; - } - } - - authReq.setDestination(redirectEndpoint.getLocation()); - - RequestedAuthnContext reqAuthContext = - SAML2Utils.createSAMLObject(RequestedAuthnContext.class); - - AuthnContextClassRef authnClassRef = - SAML2Utils.createSAMLObject(AuthnContextClassRef.class); - - authnClassRef.setAuthnContextClassRef("http://www.stork.gov.eu/1.0/citizenQAALevel/4"); - - reqAuthContext.setComparison(AuthnContextComparisonTypeEnumeration.MINIMUM); - - reqAuthContext.getAuthnContextClassRefs().add(authnClassRef); - - authReq.setRequestedAuthnContext(reqAuthContext); - - //sign Message - X509Credential authcredential = PVP2Utils.signMessage((AbstractSignableXMLObject) authReq, config); - - //encode message - PVP2Utils.postBindingEncoder(request, - response, - authReq, - authcredential, - redirectEndpoint.getLocation(), - null); - - } 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, null); - } - - /** - * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse - * response) - */ - protected void doPost(HttpServletRequest request, - HttpServletResponse response) throws ServletException, IOException { - process(request, response, null); - } + private static final long serialVersionUID = 1L; + + private static final Logger log = LoggerFactory + .getLogger(Authenticate.class); + + private static DocumentBuilderFactory factory = null; + + static { + initialDocumentBuilderFactory(); + } + + synchronized private static void initialDocumentBuilderFactory() { + factory = DocumentBuilderFactory.newInstance(); + factory.setNamespaceAware(true); + + } + + public Document asDOMDocument(XMLObject object) throws IOException, + MarshallingException, TransformerException, ParserConfigurationException { + try { + DocumentBuilder builder = null; + synchronized (factory) { + builder = factory.newDocumentBuilder(); + + } + + final Document document = builder.newDocument(); + final Marshaller out = org.opensaml.xml.Configuration.getMarshallerFactory().getMarshaller( + object); + out.marshall(object, document); + return document; + + } catch (final ParserConfigurationException e) { + log.warn("PVP2 AuthenticationServlet can not be initialized.", e); + throw e; + } + + } + + protected void process(HttpServletRequest request, + HttpServletResponse response, Map<String, String> legacyParameter) throws ServletException, + IOException { + try { + + final ConfigurationProvider config = ConfigurationProvider.getInstance(); + config.initializePVP2Login(); + + final AuthnRequest authReq = SAML2Utils + .createSAMLObject(AuthnRequest.class); + final SecureRandomIdentifierGenerator gen = new SecureRandomIdentifierGenerator(); + authReq.setID(gen.generateIdentifier()); + + final HttpSession session = request.getSession(); + if (session != null) { + session.setAttribute(Constants.SESSION_PVP2REQUESTID, authReq.getID()); + } + + authReq.setAssertionConsumerServiceIndex(0); + authReq.setAttributeConsumingServiceIndex(0); + authReq.setIssueInstant(new DateTime()); + final Subject subject = SAML2Utils.createSAMLObject(Subject.class); + 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); + + subject.setNameID(name); + authReq.setSubject(subject); + issuer.setFormat(NameIDType.ENTITY); + authReq.setIssuer(issuer); + 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"); + } + + 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"); + } + + 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)) { + redirectEndpoint = sss; + } + } + + authReq.setDestination(redirectEndpoint.getLocation()); + + final RequestedAuthnContext reqAuthContext = + SAML2Utils.createSAMLObject(RequestedAuthnContext.class); + + final AuthnContextClassRef authnClassRef = + SAML2Utils.createSAMLObject(AuthnContextClassRef.class); + + authnClassRef.setAuthnContextClassRef("http://www.stork.gov.eu/1.0/citizenQAALevel/4"); + + reqAuthContext.setComparison(AuthnContextComparisonTypeEnumeration.MINIMUM); + + reqAuthContext.getAuthnContextClassRefs().add(authnClassRef); + + authReq.setRequestedAuthnContext(reqAuthContext); + + // sign Message + final X509Credential authcredential = PVP2Utils.signMessage((AbstractSignableXMLObject) authReq, + config); + + // encode message + PVP2Utils.postBindingEncoder(request, + response, + authReq, + authcredential, + redirectEndpoint.getLocation(), + null); + + } 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, 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/ConfigWebTool/src/main/java/at/gv/egovernment/moa/id/configuration/auth/pvp2/servlets/BuildMetadata.java b/id/ConfigWebTool/src/main/java/at/gv/egovernment/moa/id/configuration/auth/pvp2/servlets/BuildMetadata.java index 7256d8688..ca03054aa 100644 --- a/id/ConfigWebTool/src/main/java/at/gv/egovernment/moa/id/configuration/auth/pvp2/servlets/BuildMetadata.java +++ b/id/ConfigWebTool/src/main/java/at/gv/egovernment/moa/id/configuration/auth/pvp2/servlets/BuildMetadata.java @@ -44,9 +44,7 @@ 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.Configuration; import org.opensaml.common.impl.SecureRandomIdentifierGenerator; import org.opensaml.common.xml.SAMLConstants; import org.opensaml.saml2.core.NameIDType; @@ -81,275 +79,274 @@ import at.gv.egovernment.moa.id.configuration.auth.pvp2.AttributeListBuilder; import at.gv.egovernment.moa.id.configuration.config.ConfigurationProvider; import at.gv.egovernment.moa.id.configuration.utils.SAML2Utils; import at.gv.egovernment.moa.util.MiscUtil; +import lombok.extern.slf4j.Slf4j; /** * Servlet implementation class BuildMetadata */ +@Slf4j public class BuildMetadata extends HttpServlet { - private static final long serialVersionUID = 1L; - - private static final Logger log = Logger.getLogger(BuildMetadata.class); - - 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 { - ConfigurationProvider config = ConfigurationProvider.getInstance(); - - //config.initializePVP2Login(); - - 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()); - - EntityDescriptor spEntityDescriptor = SAML2Utils - .createSAMLObject(EntityDescriptor.class); - - spEntityDescriptor.setValidUntil(date.plusDays(VALIDUNTIL_IN_HOURS)); - - spEntitiesDescriptor.getEntityDescriptors().add(spEntityDescriptor); - - 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())) { - 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)); - 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); - - 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); - - - //add SLO services - SingleLogoutService postBindingService = SAML2Utils.createSAMLObject(SingleLogoutService.class); - postBindingService.setBinding(SAMLConstants.SAML2_POST_BINDING_URI); - postBindingService.setLocation(serviceURL + Constants.SERVLET_SLO_FRONT); - spSSODescriptor.getSingleLogoutServices().add(postBindingService); - - SingleLogoutService redirectBindingService = SAML2Utils.createSAMLObject(SingleLogoutService.class); - redirectBindingService.setBinding(SAMLConstants.SAML2_REDIRECT_BINDING_URI); - redirectBindingService.setLocation(serviceURL + Constants.SERVLET_SLO_FRONT); - spSSODescriptor.getSingleLogoutServices().add(redirectBindingService); - - SingleLogoutService soapBindingService = SAML2Utils.createSAMLObject(SingleLogoutService.class); - soapBindingService.setBinding(SAMLConstants.SAML2_SOAP11_BINDING_URI); - soapBindingService.setLocation(serviceURL + Constants.SERVLET_SLO_BACK); - spSSODescriptor.getSingleLogoutServices().add(soapBindingService); - - spSSODescriptor.addSupportedProtocol(SAMLConstants.SAML20P_NS); - - spEntityDescriptor.getRoleDescriptors().add(spSSODescriptor); - - spSSODescriptor.setWantAssertionsSigned(true); - spSSODescriptor.setAuthnRequestsSigned(true); - - 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); - - attributeService.getRequestAttributes().addAll(AttributeListBuilder.getRequestedAttributes()); - - spSSODescriptor.getAttributeConsumingServices().add(attributeService); - - DocumentBuilder builder; - DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); - - builder = factory.newDocumentBuilder(); - Document document = builder.newDocument(); - Marshaller out = 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(); - - byte[] metadataXML = sw.toString().getBytes("UTF-8"); - - response.setContentType("text/xml"); - response.setContentLength(metadataXML.length); - response.getOutputStream().write(metadataXML); - - - } 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 (KeyStoreException e) { - log.warn("Requested KeyStoreType is not implemented.", e); - throw new ServletException("MetaData can not be created. Look into LogFiles for more details."); - - } catch (CertificateException e) { - log.warn("KeyStore can not be opend or userd.", e); - throw new ServletException("MetaData can not be created. Look into LogFiles for more details."); - - } catch (SecurityException e) { - log.warn("KeyStore can not be opend or used", 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 (MarshallingException e) { - log.warn("PVP2 Metadata createn error", e); - throw new ServletException("MetaData can not be created. Look into LogFiles for more details."); - - } catch (SignatureException e) { - log.warn("PVP2 Metadata can not be signed", 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 { - } + 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 ConfigurationProvider config = ConfigurationProvider.getInstance(); + + // config.initializePVP2Login(); + + 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()); + + final EntityDescriptor spEntityDescriptor = SAML2Utils + .createSAMLObject(EntityDescriptor.class); + + spEntityDescriptor.setValidUntil(date.plusDays(VALIDUNTIL_IN_HOURS)); + + spEntitiesDescriptor.getEntityDescriptors().add(spEntityDescriptor); + + 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())) { + 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)); + 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); + + 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); + + // add SLO services + final SingleLogoutService postBindingService = SAML2Utils.createSAMLObject(SingleLogoutService.class); + postBindingService.setBinding(SAMLConstants.SAML2_POST_BINDING_URI); + postBindingService.setLocation(serviceURL + Constants.SERVLET_SLO_FRONT); + spSSODescriptor.getSingleLogoutServices().add(postBindingService); + + final SingleLogoutService redirectBindingService = SAML2Utils.createSAMLObject( + SingleLogoutService.class); + redirectBindingService.setBinding(SAMLConstants.SAML2_REDIRECT_BINDING_URI); + redirectBindingService.setLocation(serviceURL + Constants.SERVLET_SLO_FRONT); + spSSODescriptor.getSingleLogoutServices().add(redirectBindingService); + + final SingleLogoutService soapBindingService = SAML2Utils.createSAMLObject(SingleLogoutService.class); + soapBindingService.setBinding(SAMLConstants.SAML2_SOAP11_BINDING_URI); + soapBindingService.setLocation(serviceURL + Constants.SERVLET_SLO_BACK); + spSSODescriptor.getSingleLogoutServices().add(soapBindingService); + + spSSODescriptor.addSupportedProtocol(SAMLConstants.SAML20P_NS); + + spEntityDescriptor.getRoleDescriptors().add(spSSODescriptor); + + spSSODescriptor.setWantAssertionsSigned(true); + spSSODescriptor.setAuthnRequestsSigned(true); + + 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); + + attributeService.getRequestAttributes().addAll(AttributeListBuilder.getRequestedAttributes()); + + spSSODescriptor.getAttributeConsumingServices().add(attributeService); + + 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 byte[] metadataXML = sw.toString().getBytes("UTF-8"); + + response.setContentType("text/xml"); + response.setContentLength(metadataXML.length); + response.getOutputStream().write(metadataXML); + + } 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 KeyStoreException e) { + log.warn("Requested KeyStoreType is not implemented.", e); + throw new ServletException("MetaData can not be created. Look into LogFiles for more details."); + + } catch (final CertificateException e) { + log.warn("KeyStore can not be opend or userd.", e); + throw new ServletException("MetaData can not be created. Look into LogFiles for more details."); + + } catch (final SecurityException e) { + log.warn("KeyStore can not be opend or used", 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 MarshallingException e) { + log.warn("PVP2 Metadata createn error", e); + throw new ServletException("MetaData can not be created. Look into LogFiles for more details."); + + } catch (final SignatureException e) { + log.warn("PVP2 Metadata can not be signed", 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 { + } } diff --git a/id/ConfigWebTool/src/main/java/at/gv/egovernment/moa/id/configuration/auth/pvp2/servlets/SLOBackChannelServlet.java b/id/ConfigWebTool/src/main/java/at/gv/egovernment/moa/id/configuration/auth/pvp2/servlets/SLOBackChannelServlet.java index f2c95f391..01bf39696 100644 --- a/id/ConfigWebTool/src/main/java/at/gv/egovernment/moa/id/configuration/auth/pvp2/servlets/SLOBackChannelServlet.java +++ b/id/ConfigWebTool/src/main/java/at/gv/egovernment/moa/id/configuration/auth/pvp2/servlets/SLOBackChannelServlet.java @@ -64,111 +64,116 @@ import at.gv.egovernment.moa.id.configuration.auth.pvp2.PVP2Utils; */ public class SLOBackChannelServlet extends SLOBasicServlet { - private static final long serialVersionUID = 1481623547633064922L; - private static final Logger log = LoggerFactory - .getLogger(SLOBackChannelServlet.class); - - /** - * @throws ConfigurationException - */ - public SLOBackChannelServlet() throws ConfigurationException { - super(); - } - - - protected void doPost(HttpServletRequest request, - HttpServletResponse response) throws ServletException, IOException { - - try { - HTTPSOAP11Decoder soapDecoder = new HTTPSOAP11Decoder(new BasicParserPool()); - - BasicSOAPMessageContext messageContext = new BasicSOAPMessageContext(); - -// BasicSAMLMessageContext<SAMLObject, ?, ?> messageContext = + private static final long serialVersionUID = 1481623547633064922L; + private static final Logger log = LoggerFactory + .getLogger(SLOBackChannelServlet.class); + + /** + * @throws ConfigurationException + */ + public SLOBackChannelServlet() throws ConfigurationException { + super(); + } + + @Override + protected void doPost(HttpServletRequest request, + HttpServletResponse response) throws ServletException, IOException { + + try { + final HTTPSOAP11Decoder soapDecoder = new HTTPSOAP11Decoder(new BasicParserPool()); + + final BasicSOAPMessageContext messageContext = new BasicSOAPMessageContext(); + +// BasicSAMLMessageContext<SAMLObject, ?, ?> messageContext = // new BasicSAMLMessageContext<SAMLObject, SAMLObject, SAMLObject>(); - - messageContext.setInboundMessageTransport(new HttpServletRequestAdapter(request)); - //messageContext.setMetadataProvider(getConfig().getMetaDataProvier()); - - //set trustPolicy + messageContext.setInboundMessageTransport(new HttpServletRequestAdapter(request)); + + // messageContext.setMetadataProvider(getConfig().getMetaDataProvier()); + + // set trustPolicy // BasicSecurityPolicy policy = new BasicSecurityPolicy(); // policy.getPolicyRules().add( // new PVPSOAPRequestSecurityPolicy( // PVP2Utils.getTrustEngine(getConfig()), -// IDPSSODescriptor.DEFAULT_ELEMENT_NAME)); +// IDPSSODescriptor.DEFAULT_ELEMENT_NAME)); // SecurityPolicyResolver resolver = new StaticSecurityPolicyResolver( -// policy); +// policy); // messageContext.setSecurityPolicyResolver(resolver); - - soapDecoder.decode(messageContext); - - Envelope inboundMessage = (Envelope) messageContext - .getInboundMessage(); - - LogoutResponse sloResp = null; - - if (inboundMessage.getBody() != null) { - List<XMLObject> xmlElemList = inboundMessage.getBody().getUnknownXMLObjects(); - - if (!xmlElemList.isEmpty() && xmlElemList.get(0) instanceof LogoutRequest) { - LogoutRequest sloReq = (LogoutRequest) xmlElemList.get(0); - - //validate request signature - PVP2Utils.validateSignature(sloReq, getConfig()); - - sloResp = processLogOutRequest(sloReq, request); - - KeyStore keyStore = getConfig().getPVP2KeyStore(); - X509Credential authcredential = new KeyStoreX509CredentialAdapter( - keyStore, - getConfig().getPVP2KeystoreAuthRequestKeyAlias(), - getConfig().getPVP2KeystoreAuthRequestKeyPassword().toCharArray()); - - HTTPSOAP11Encoder encoder = new HTTPSOAP11Encoder(); - HttpServletResponseAdapter responseAdapter = new HttpServletResponseAdapter( - response, true); - BasicSAMLMessageContext<SAMLObject, SAMLObject, SAMLObject> context = new BasicSAMLMessageContext<SAMLObject, SAMLObject, SAMLObject>(); - context.setOutboundSAMLMessageSigningCredential(authcredential); - context.setOutboundSAMLMessage(sloResp); - context.setOutboundMessageTransport(responseAdapter); - - encoder.encode(context); - - } else { - log.warn("Received request ist not of type LogOutRequest"); - response.setStatus(HttpServletResponse.SC_BAD_REQUEST); - return; - - } - } - - } catch (MessageDecodingException | SecurityException | NoSuchAlgorithmException | ConfigurationException | ValidationException e) { - log.error("SLO message processing FAILED." , e); - response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, StringEscapeUtils.escapeHtml(e.getMessage())); - - } catch (CertificateException e) { - log.error("SLO message processing FAILED." , e); - response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, StringEscapeUtils.escapeHtml(e.getMessage())); - - } catch (KeyStoreException e) { - log.error("SLO message processing FAILED." , e); - response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, StringEscapeUtils.escapeHtml(e.getMessage())); - - } catch (MessageEncodingException e) { - log.error("SLO message processing FAILED." , e); - response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, StringEscapeUtils.escapeHtml(e.getMessage())); - - } - - - - } - - protected void doGet(HttpServletRequest request, - HttpServletResponse response) throws ServletException, IOException { - response.setStatus(HttpServletResponse.SC_NOT_FOUND); - - } - + + soapDecoder.decode(messageContext); + + final Envelope inboundMessage = (Envelope) messageContext + .getInboundMessage(); + + LogoutResponse sloResp = null; + + if (inboundMessage.getBody() != null) { + final List<XMLObject> xmlElemList = inboundMessage.getBody().getUnknownXMLObjects(); + + if (!xmlElemList.isEmpty() && xmlElemList.get(0) instanceof LogoutRequest) { + final LogoutRequest sloReq = (LogoutRequest) xmlElemList.get(0); + + // validate request signature + PVP2Utils.validateSignature(sloReq, getConfig()); + + sloResp = processLogOutRequest(sloReq, request); + + final KeyStore keyStore = getConfig().getPVP2KeyStore(); + final X509Credential authcredential = new KeyStoreX509CredentialAdapter( + keyStore, + getConfig().getPVP2KeystoreAuthRequestKeyAlias(), + getConfig().getPVP2KeystoreAuthRequestKeyPassword().toCharArray()); + + final HTTPSOAP11Encoder encoder = new HTTPSOAP11Encoder(); + final HttpServletResponseAdapter responseAdapter = new HttpServletResponseAdapter( + response, true); + final BasicSAMLMessageContext<SAMLObject, SAMLObject, SAMLObject> context = + new BasicSAMLMessageContext<>(); + context.setOutboundSAMLMessageSigningCredential(authcredential); + context.setOutboundSAMLMessage(sloResp); + context.setOutboundMessageTransport(responseAdapter); + + encoder.encode(context); + + } else { + log.warn("Received request ist not of type LogOutRequest"); + response.setStatus(HttpServletResponse.SC_BAD_REQUEST); + return; + + } + } + + } catch (MessageDecodingException | SecurityException | NoSuchAlgorithmException | ConfigurationException + | ValidationException e) { + log.error("SLO message processing FAILED.", e); + response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, StringEscapeUtils.escapeHtml(e + .getMessage())); + + } catch (final CertificateException e) { + log.error("SLO message processing FAILED.", e); + response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, StringEscapeUtils.escapeHtml(e + .getMessage())); + + } catch (final KeyStoreException e) { + log.error("SLO message processing FAILED.", e); + response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, StringEscapeUtils.escapeHtml(e + .getMessage())); + + } catch (final MessageEncodingException e) { + log.error("SLO message processing FAILED.", e); + response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, StringEscapeUtils.escapeHtml(e + .getMessage())); + + } + + } + + @Override + protected void doGet(HttpServletRequest request, + HttpServletResponse response) throws ServletException, IOException { + response.setStatus(HttpServletResponse.SC_NOT_FOUND); + + } + } diff --git a/id/ConfigWebTool/src/main/java/at/gv/egovernment/moa/id/configuration/auth/pvp2/servlets/SLOBasicServlet.java b/id/ConfigWebTool/src/main/java/at/gv/egovernment/moa/id/configuration/auth/pvp2/servlets/SLOBasicServlet.java index c70d34d7e..a880e800b 100644 --- a/id/ConfigWebTool/src/main/java/at/gv/egovernment/moa/id/configuration/auth/pvp2/servlets/SLOBasicServlet.java +++ b/id/ConfigWebTool/src/main/java/at/gv/egovernment/moa/id/configuration/auth/pvp2/servlets/SLOBasicServlet.java @@ -62,217 +62,226 @@ import at.gv.egovernment.moa.util.MiscUtil; * */ public class SLOBasicServlet extends HttpServlet { - private static final long serialVersionUID = -4547240664871845098L; - private static final Logger log = LoggerFactory - .getLogger(SLOBasicServlet.class); - - private ConfigurationProvider config; - - public SLOBasicServlet() throws ConfigurationException { - config = ConfigurationProvider.getInstance(); - config.initializePVP2Login(); - } - - protected LogoutRequest createLogOutRequest(String nameID, String nameIDFormat, HttpServletRequest request) throws SLOException { - try { - 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); - - return sloReq; - - } catch (NoSuchAlgorithmException e) { - log.warn("Single LogOut request createn FAILED. ", e); - throw new SLOException(); - - } - - } - - protected LogoutResponse processLogOutRequest(LogoutRequest sloReq, HttpServletRequest request) throws NoSuchAlgorithmException { - //check response destination - String serviceURL = config.getPublicUrlPreFix(request); - if (!serviceURL.endsWith("/")) - serviceURL = serviceURL + "/"; - - String responseDestination = sloReq.getDestination(); - if (MiscUtil.isEmpty(responseDestination) || - !responseDestination.startsWith(serviceURL)) { - log.warn("PVPResponse destination does not match requested destination"); - return createSLOResponse(sloReq, StatusCode.REQUESTER_URI, request); - } - - AuthenticationManager authManager = AuthenticationManager.getInstance(); - if (authManager.isActiveUser(sloReq.getNameID().getValue())) { - AuthenticatedUser authUser = authManager.getActiveUser(sloReq.getNameID().getValue()); - log.info("User " + authUser.getGivenName() + " " + authUser.getFamilyName() + " with nameID:" - + authUser.getNameID() + " get logged out by Single LogOut request."); - authManager.removeActiveUser(authUser); - HttpSession session = request.getSession(false); - if (session != null) - session.invalidate(); - return createSLOResponse(sloReq, StatusCode.SUCCESS_URI, request); - - } else { - log.debug("Single LogOut not possible! User with nameID:" + sloReq.getNameID().getValue() + " is not found."); - return createSLOResponse(sloReq, StatusCode.SUCCESS_URI, request); - - } - - } - - protected LogoutResponse createSLOResponse(LogoutRequest sloReq, String statusCodeURI, HttpServletRequest request) throws NoSuchAlgorithmException { - LogoutResponse sloResp = SAML2Utils.createSAMLObject(LogoutResponse.class); - SecureRandomIdentifierGenerator gen = new SecureRandomIdentifierGenerator(); - sloResp.setID(gen.generateIdentifier()); - sloResp.setInResponseTo(sloReq.getID()); - 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(statusCodeURI); - status.setStatusCode(statusCode ); - - return sloResp; - } - - protected void validateLogOutResponse(LogoutResponse sloResp, String reqID, HttpServletRequest request, HttpServletResponse response) throws PVP2Exception { - //ckeck InResponseTo matchs requestID - if (MiscUtil.isEmpty(reqID)) { - log.info("NO Sigle LogOut request ID"); - throw new PVP2Exception("NO Sigle LogOut request ID"); - } - - if (!reqID.equals(sloResp.getInResponseTo())) { - log.warn("SLORequestID does not match SLO Response ID!"); - throw new PVP2Exception("SLORequestID does not match SLO Response ID!"); - - } - - //check response destination - String serviceURL = config.getPublicUrlPreFix(request); - if (!serviceURL.endsWith("/")) - serviceURL = serviceURL + "/"; - - String responseDestination = sloResp.getDestination(); - if (MiscUtil.isEmpty(responseDestination) || - !responseDestination.startsWith(serviceURL)) { - log.warn("PVPResponse destination does not match requested destination"); - throw new PVP2Exception("SLO response destination does not match requested destination"); - } - - request.getSession().invalidate(); - - if (sloResp.getStatus().getStatusCode().getValue().equals(StatusCode.PARTIAL_LOGOUT_URI)) { - log.warn("Single LogOut process is not completed."); - request.getSession().setAttribute(Constants.SESSION_SLOERROR, - LanguageHelper.getErrorString("webpages.slo.error", request)); - - - } else if (sloResp.getStatus().getStatusCode().getValue().equals(StatusCode.SUCCESS_URI)) { - - if (sloResp.getStatus().getStatusCode().getStatusCode() != null && - !sloResp.getStatus().getStatusCode().getStatusCode().equals(StatusCode.PARTIAL_LOGOUT_URI)) { - log.info("Single LogOut process complete."); - request.getSession().setAttribute(Constants.SESSION_SLOSUCCESS, - LanguageHelper.getErrorString("webpages.slo.success", request)); - - } else { - log.warn("Single LogOut process is not completed."); - request.getSession().setAttribute(Constants.SESSION_SLOERROR, - LanguageHelper.getErrorString("webpages.slo.error", request)); - - } - - } else { - log.warn("Single LogOut response sends an unsupported statustype " + sloResp.getStatus().getStatusCode().getValue()); - request.getSession().setAttribute(Constants.SESSION_SLOERROR, - LanguageHelper.getErrorString("webpages.slo.error", request)); - - } - String redirectURL = serviceURL + Constants.SERVLET_LOGOUT; - redirectURL = response.encodeRedirectURL(redirectURL); - response.setContentType("text/html"); - response.setStatus(302); - response.addHeader("Location", redirectURL); - - } - - protected SingleLogoutService findIDPFrontChannelSLOService() throws - ConfigurationException, SLOException { - - 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(); - try { - 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; - - else if (sss.getBinding().equals(SAMLConstants.SAML2_POST_BINDING_URI) && - redirectEndpoint == null) - redirectEndpoint = sss; - } - - if (redirectEndpoint == null) { - log.warn("Single LogOut FAILED: IDP implements no frontchannel SLO service."); - throw new SLOException("Single LogOut FAILED: IDP implements no frontchannel SLO service."); - } - - return redirectEndpoint; - } catch (MetadataProviderException e) { - log.info("IDP EntityName is not found in IDP Metadata", e); - throw new ConfigurationException("IDP EntityName is not found in IDP Metadata"); - - } - } - - protected ConfigurationProvider getConfig() { - return config; - } + private static final long serialVersionUID = -4547240664871845098L; + private static final Logger log = LoggerFactory + .getLogger(SLOBasicServlet.class); + + private final ConfigurationProvider config; + + public SLOBasicServlet() throws ConfigurationException { + config = ConfigurationProvider.getInstance(); + config.initializePVP2Login(); + } + + protected LogoutRequest createLogOutRequest(String nameID, String nameIDFormat, HttpServletRequest request) + throws SLOException { + try { + 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); + + return sloReq; + + } catch (final NoSuchAlgorithmException e) { + log.warn("Single LogOut request createn FAILED. ", e); + throw new SLOException(); + + } + + } + + protected LogoutResponse processLogOutRequest(LogoutRequest sloReq, HttpServletRequest request) + throws NoSuchAlgorithmException { + // check response destination + String serviceURL = config.getPublicUrlPreFix(request); + if (!serviceURL.endsWith("/")) { + serviceURL = serviceURL + "/"; + } + + final String responseDestination = sloReq.getDestination(); + if (MiscUtil.isEmpty(responseDestination) || + !responseDestination.startsWith(serviceURL)) { + log.warn("PVPResponse destination does not match requested destination"); + return createSLOResponse(sloReq, StatusCode.REQUESTER_URI, request); + } + + final AuthenticationManager authManager = AuthenticationManager.getInstance(); + if (authManager.isActiveUser(sloReq.getNameID().getValue())) { + final AuthenticatedUser authUser = authManager.getActiveUser(sloReq.getNameID().getValue()); + log.info("User " + authUser.getGivenName() + " " + authUser.getFamilyName() + " with nameID:" + + authUser.getNameID() + " get logged out by Single LogOut request."); + authManager.removeActiveUser(authUser); + final HttpSession session = request.getSession(false); + if (session != null) { + session.invalidate(); + } + return createSLOResponse(sloReq, StatusCode.SUCCESS_URI, request); + + } else { + log.debug("Single LogOut not possible! User with nameID:" + sloReq.getNameID().getValue() + + " is not found."); + return createSLOResponse(sloReq, StatusCode.SUCCESS_URI, request); + + } + + } + + protected LogoutResponse createSLOResponse(LogoutRequest sloReq, String statusCodeURI, + HttpServletRequest request) throws NoSuchAlgorithmException { + final LogoutResponse sloResp = SAML2Utils.createSAMLObject(LogoutResponse.class); + final SecureRandomIdentifierGenerator gen = new SecureRandomIdentifierGenerator(); + sloResp.setID(gen.generateIdentifier()); + sloResp.setInResponseTo(sloReq.getID()); + 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(statusCodeURI); + status.setStatusCode(statusCode); + + return sloResp; + } + + protected void validateLogOutResponse(LogoutResponse sloResp, String reqID, HttpServletRequest request, + HttpServletResponse response) throws PVP2Exception { + // ckeck InResponseTo matchs requestID + if (MiscUtil.isEmpty(reqID)) { + log.info("NO Sigle LogOut request ID"); + throw new PVP2Exception("NO Sigle LogOut request ID"); + } + + if (!reqID.equals(sloResp.getInResponseTo())) { + log.warn("SLORequestID does not match SLO Response ID!"); + throw new PVP2Exception("SLORequestID does not match SLO Response ID!"); + + } + + // check response destination + String serviceURL = config.getPublicUrlPreFix(request); + if (!serviceURL.endsWith("/")) { + serviceURL = serviceURL + "/"; + } + + final String responseDestination = sloResp.getDestination(); + if (MiscUtil.isEmpty(responseDestination) || + !responseDestination.startsWith(serviceURL)) { + log.warn("PVPResponse destination does not match requested destination"); + throw new PVP2Exception("SLO response destination does not match requested destination"); + } + + request.getSession().invalidate(); + + if (sloResp.getStatus().getStatusCode().getValue().equals(StatusCode.PARTIAL_LOGOUT_URI)) { + log.warn("Single LogOut process is not completed."); + request.getSession().setAttribute(Constants.SESSION_SLOERROR, + LanguageHelper.getErrorString("webpages.slo.error", request)); + + } else if (sloResp.getStatus().getStatusCode().getValue().equals(StatusCode.SUCCESS_URI)) { + + if (sloResp.getStatus().getStatusCode().getStatusCode() != null && + !sloResp.getStatus().getStatusCode().getStatusCode().equals(StatusCode.PARTIAL_LOGOUT_URI)) { + log.info("Single LogOut process complete."); + request.getSession().setAttribute(Constants.SESSION_SLOSUCCESS, + LanguageHelper.getErrorString("webpages.slo.success", request)); + + } else { + log.warn("Single LogOut process is not completed."); + request.getSession().setAttribute(Constants.SESSION_SLOERROR, + LanguageHelper.getErrorString("webpages.slo.error", request)); + + } + + } else { + log.warn("Single LogOut response sends an unsupported statustype " + sloResp.getStatus().getStatusCode() + .getValue()); + request.getSession().setAttribute(Constants.SESSION_SLOERROR, + LanguageHelper.getErrorString("webpages.slo.error", request)); + + } + String redirectURL = serviceURL + Constants.SERVLET_LOGOUT; + redirectURL = response.encodeRedirectURL(redirectURL); + response.setContentType("text/html"); + response.setStatus(302); + response.addHeader("Location", redirectURL); + + } + + protected SingleLogoutService findIDPFrontChannelSLOService() throws ConfigurationException, SLOException { + + 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(); + try { + 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; + } else if (sss.getBinding().equals(SAMLConstants.SAML2_POST_BINDING_URI) && + redirectEndpoint == null) { + redirectEndpoint = sss; + } + } + + if (redirectEndpoint == null) { + log.warn("Single LogOut FAILED: IDP implements no frontchannel SLO service."); + throw new SLOException("Single LogOut FAILED: IDP implements no frontchannel SLO service."); + } + + return redirectEndpoint; + } catch (final MetadataProviderException e) { + log.info("IDP EntityName is not found in IDP Metadata", e); + throw new ConfigurationException("IDP EntityName is not found in IDP Metadata"); + + } + } + + protected ConfigurationProvider getConfig() { + return config; + } } diff --git a/id/ConfigWebTool/src/main/java/at/gv/egovernment/moa/id/configuration/auth/pvp2/servlets/SLOFrontChannelServlet.java b/id/ConfigWebTool/src/main/java/at/gv/egovernment/moa/id/configuration/auth/pvp2/servlets/SLOFrontChannelServlet.java index 274aa21bf..ac9d65cbf 100644 --- a/id/ConfigWebTool/src/main/java/at/gv/egovernment/moa/id/configuration/auth/pvp2/servlets/SLOFrontChannelServlet.java +++ b/id/ConfigWebTool/src/main/java/at/gv/egovernment/moa/id/configuration/auth/pvp2/servlets/SLOFrontChannelServlet.java @@ -77,221 +77,230 @@ import at.gv.egovernment.moa.util.MiscUtil; */ public class SLOFrontChannelServlet extends SLOBasicServlet { - private static final long serialVersionUID = -6280199681356977759L; - private static final Logger log = LoggerFactory - .getLogger(SLOFrontChannelServlet.class); - - /** - * @throws ConfigurationException - */ - public SLOFrontChannelServlet() throws ConfigurationException { - super(); - } - - /** - * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse - * response) - */ - protected void doGet(HttpServletRequest request, - HttpServletResponse response) throws ServletException, IOException { - try { - if (MiscUtil.isNotEmpty(request.getParameter(Constants.REQUEST_USERSLO))) { - //process user initiated single logout process - Object authUserObj = request.getSession().getAttribute(Constants.SESSION_AUTH); - - if (authUserObj == null) { - log.warn("No user information found. Single Log-Out not possible"); - buildErrorMessage(request, response); - - } - - AuthenticatedUser authUser = (AuthenticatedUser) authUserObj; - - String nameIDFormat = authUser.getNameIDFormat(); - String nameID = authUser.getNameID(); - - //remove user - AuthenticationManager authManager = AuthenticationManager.getInstance(); - authManager.removeActiveUser(authUser); - - if (MiscUtil.isEmpty(nameID) || MiscUtil.isEmpty(nameIDFormat)) { - log.warn("No user information found. Single Log-Out not possible"); - buildErrorMessage(request, response); - - } else - log.info("Fount user information for user nameID: " + nameID - + " , nameIDFormat: " + nameIDFormat - + ". Build Single Log-Out request ..."); - - //build SLO request to IDP - LogoutRequest sloReq = createLogOutRequest(nameID, nameIDFormat, request); - - request.getSession().setAttribute(Constants.SESSION_PVP2REQUESTID, sloReq.getID()); - - //send message - sendMessage(request, response, sloReq, null); - - } else { - //process PVP 2.1 single logout process - HTTPRedirectDeflateDecoder decode = new HTTPRedirectDeflateDecoder( - new BasicParserPool()); - BasicSAMLMessageContext<SAMLObject, ?, ?> messageContext = new BasicSAMLMessageContext<SAMLObject, SAMLObject, SAMLObject>(); - messageContext.setInboundMessageTransport(new HttpServletRequestAdapter(request)); - messageContext.setMetadataProvider(getConfig().getMetaDataProvier()); - - SAML2HTTPRedirectDeflateSignatureRule signatureRule = new SAML2HTTPRedirectDeflateSignatureRule( - PVP2Utils.getTrustEngine(getConfig())); - 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); - - decode.decode(messageContext); - - signatureRule.evaluate(messageContext); - - - processMessage(request, response, - messageContext.getInboundMessage(), messageContext.getRelayState()); - - } - - } catch (SLOException e) { - log.error("Single LogOut processing error.", e); - buildErrorMessage(request, response); - - } catch (ConfigurationException e) { - log.error("Single LogOut processing error.", e); - buildErrorMessage(request, response); - - } catch (PVP2Exception e) { - log.error("Single LogOut processing error.", e); - buildErrorMessage(request, response); - - } catch (SecurityPolicyException e) { - log.error("Single LogOut processing error.", e); - buildErrorMessage(request, response); - - } catch (MessageDecodingException e) { - log.error("Single LogOut processing error.", e); - buildErrorMessage(request, response); - - } catch (SecurityException e) { - log.error("Single LogOut processing error.", e); - buildErrorMessage(request, response); - - } catch (NoSuchAlgorithmException e) { - log.error("Single LogOut processing error.", e); - buildErrorMessage(request, response); - - } - } - - /** - * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse - * response) - */ - protected void doPost(HttpServletRequest request, - HttpServletResponse response) throws ServletException, IOException { - try { - HTTPPostDecoder decode = new HTTPPostDecoder(new BasicParserPool()); - BasicSAMLMessageContext<Response, ?, ?> messageContext = new BasicSAMLMessageContext<Response, SAMLObject, SAMLObject>(); - messageContext.setInboundMessageTransport(new HttpServletRequestAdapter(request)); - decode.decode(messageContext); - - PVP2Utils.validateSignature((SignableXMLObject) messageContext.getInboundMessage(), getConfig()); - - processMessage(request, response, - messageContext.getInboundMessage(), messageContext.getRelayState()); - - - } catch (MessageDecodingException e) { - log.error("Single LogOut processing error.", e); - buildErrorMessage(request, response); - - } catch (SecurityException e) { - log.error("Single LogOut processing error.", e); - buildErrorMessage(request, response); - - } catch (ValidationException e) { - log.error("Single LogOut processing error.", e); - buildErrorMessage(request, response); - - } catch (ConfigurationException e) { - log.error("Single LogOut processing error.", e); - buildErrorMessage(request, response); - - } catch (PVP2Exception e) { - log.error("Single LogOut processing error.", e); - buildErrorMessage(request, response); - - } catch (NoSuchAlgorithmException e) { - log.error("Single LogOut processing error.", e); - buildErrorMessage(request, response); - - } - } - - private void buildErrorMessage(HttpServletRequest request, HttpServletResponse response) { - - request.getSession().setAttribute(Constants.SESSION_SLOERROR, - LanguageHelper.getErrorString("webpages.slo.error", request)); - - //check response destination - String serviceURL = getConfig().getPublicUrlPreFix(request); - if (!serviceURL.endsWith("/")) - serviceURL = serviceURL + "/"; - - String redirectURL = serviceURL + Constants.SERVLET_LOGOUT; - redirectURL = response.encodeRedirectURL(redirectURL); - response.setContentType("text/html"); - response.setStatus(302); - response.addHeader("Location", redirectURL); - } - - private void processMessage(HttpServletRequest request, HttpServletResponse response, - XMLObject xmlObject, String relayState) throws ConfigurationException, PVP2Exception, NoSuchAlgorithmException { - if (xmlObject instanceof LogoutRequest) { - LogoutResponse sloResp = - processLogOutRequest((LogoutRequest) xmlObject, request); - sendMessage(request, response, sloResp, relayState); - - } else if (xmlObject instanceof LogoutResponse) { - LogoutResponse sloResp = (LogoutResponse) xmlObject; - - String reqID = (String) request.getSession().getAttribute(Constants.SESSION_PVP2REQUESTID); - request.getSession().setAttribute(Constants.SESSION_PVP2REQUESTID, null); - validateLogOutResponse(sloResp, reqID, request, response); - - } - } - - private void sendMessage(HttpServletRequest request, HttpServletResponse response, - RequestAbstractType sloReq, String relayState) throws ConfigurationException, PVP2Exception { - SingleLogoutService sloService = findIDPFrontChannelSLOService(); - sloReq.setDestination(sloService.getLocation()); - sendMessage(request, response, sloReq, sloService, relayState); - } - - private void sendMessage(HttpServletRequest request, HttpServletResponse response, - StatusResponseType sloReq, String relayState) throws ConfigurationException, PVP2Exception { - SingleLogoutService sloService = findIDPFrontChannelSLOService(); - sloReq.setDestination(sloService.getLocation()); - sendMessage(request, response, sloReq, sloService, relayState); - } - - private void sendMessage(HttpServletRequest request, HttpServletResponse response, - SignableSAMLObject sloReq, SingleLogoutService sloService, String relayState) throws ConfigurationException, PVP2Exception { - X509Credential authcredential = PVP2Utils.signMessage((AbstractSignableXMLObject) sloReq, getConfig()); - if (sloService.getBinding().equals(SAMLConstants.SAML2_POST_BINDING_URI)) - PVP2Utils.postBindingEncoder(request, response, sloReq, authcredential, sloService.getLocation(), relayState); - - else if (sloService.getBinding().equals(SAMLConstants.SAML2_REDIRECT_BINDING_URI)) - PVP2Utils.redirectBindingEncoder(request, response, sloReq, authcredential, sloService.getLocation(), relayState); - } - + private static final long serialVersionUID = -6280199681356977759L; + private static final Logger log = LoggerFactory + .getLogger(SLOFrontChannelServlet.class); + + /** + * @throws ConfigurationException + */ + public SLOFrontChannelServlet() throws ConfigurationException { + super(); + } + + /** + * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse + * response) + */ + @Override + protected void doGet(HttpServletRequest request, + HttpServletResponse response) throws ServletException, IOException { + try { + if (MiscUtil.isNotEmpty(request.getParameter(Constants.REQUEST_USERSLO))) { + // process user initiated single logout process + final Object authUserObj = request.getSession().getAttribute(Constants.SESSION_AUTH); + + if (authUserObj == null) { + log.warn("No user information found. Single Log-Out not possible"); + buildErrorMessage(request, response); + + } + + final AuthenticatedUser authUser = (AuthenticatedUser) authUserObj; + + final String nameIDFormat = authUser.getNameIDFormat(); + final String nameID = authUser.getNameID(); + + // remove user + final AuthenticationManager authManager = AuthenticationManager.getInstance(); + authManager.removeActiveUser(authUser); + + if (MiscUtil.isEmpty(nameID) || MiscUtil.isEmpty(nameIDFormat)) { + log.warn("No user information found. Single Log-Out not possible"); + buildErrorMessage(request, response); + + } else { + log.info("Fount user information for user nameID: " + nameID + + " , nameIDFormat: " + nameIDFormat + + ". Build Single Log-Out request ..."); + } + + // build SLO request to IDP + final LogoutRequest sloReq = createLogOutRequest(nameID, nameIDFormat, request); + + request.getSession().setAttribute(Constants.SESSION_PVP2REQUESTID, sloReq.getID()); + + // send message + sendMessage(request, response, sloReq, null); + + } else { + // process PVP 2.1 single logout process + final HTTPRedirectDeflateDecoder decode = new HTTPRedirectDeflateDecoder( + new BasicParserPool()); + final BasicSAMLMessageContext<SAMLObject, ?, ?> messageContext = + new BasicSAMLMessageContext<>(); + messageContext.setInboundMessageTransport(new HttpServletRequestAdapter(request)); + messageContext.setMetadataProvider(getConfig().getMetaDataProvier()); + + final SAML2HTTPRedirectDeflateSignatureRule signatureRule = new SAML2HTTPRedirectDeflateSignatureRule( + PVP2Utils.getTrustEngine(getConfig())); + 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); + + decode.decode(messageContext); + + signatureRule.evaluate(messageContext); + + processMessage(request, response, + messageContext.getInboundMessage(), messageContext.getRelayState()); + + } + + } catch (final SLOException e) { + log.error("Single LogOut processing error.", e); + buildErrorMessage(request, response); + + } catch (final ConfigurationException e) { + log.error("Single LogOut processing error.", e); + buildErrorMessage(request, response); + + } catch (final PVP2Exception e) { + log.error("Single LogOut processing error.", e); + buildErrorMessage(request, response); + + } catch (final SecurityPolicyException e) { + log.error("Single LogOut processing error.", e); + buildErrorMessage(request, response); + + } catch (final MessageDecodingException e) { + log.error("Single LogOut processing error.", e); + buildErrorMessage(request, response); + + } catch (final SecurityException e) { + log.error("Single LogOut processing error.", e); + buildErrorMessage(request, response); + + } catch (final NoSuchAlgorithmException e) { + log.error("Single LogOut processing error.", e); + buildErrorMessage(request, response); + + } + } + + /** + * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse + * response) + */ + @Override + protected void doPost(HttpServletRequest request, + HttpServletResponse response) throws ServletException, IOException { + try { + final HTTPPostDecoder decode = new HTTPPostDecoder(new BasicParserPool()); + final BasicSAMLMessageContext<Response, ?, ?> messageContext = + new BasicSAMLMessageContext<>(); + messageContext.setInboundMessageTransport(new HttpServletRequestAdapter(request)); + decode.decode(messageContext); + + PVP2Utils.validateSignature((SignableXMLObject) messageContext.getInboundMessage(), getConfig()); + + processMessage(request, response, + messageContext.getInboundMessage(), messageContext.getRelayState()); + + } catch (final MessageDecodingException e) { + log.error("Single LogOut processing error.", e); + buildErrorMessage(request, response); + + } catch (final SecurityException e) { + log.error("Single LogOut processing error.", e); + buildErrorMessage(request, response); + + } catch (final ValidationException e) { + log.error("Single LogOut processing error.", e); + buildErrorMessage(request, response); + + } catch (final ConfigurationException e) { + log.error("Single LogOut processing error.", e); + buildErrorMessage(request, response); + + } catch (final PVP2Exception e) { + log.error("Single LogOut processing error.", e); + buildErrorMessage(request, response); + + } catch (final NoSuchAlgorithmException e) { + log.error("Single LogOut processing error.", e); + buildErrorMessage(request, response); + + } + } + + private void buildErrorMessage(HttpServletRequest request, HttpServletResponse response) { + + request.getSession().setAttribute(Constants.SESSION_SLOERROR, + LanguageHelper.getErrorString("webpages.slo.error", request)); + + // check response destination + String serviceURL = getConfig().getPublicUrlPreFix(request); + if (!serviceURL.endsWith("/")) { + serviceURL = serviceURL + "/"; + } + + String redirectURL = serviceURL + Constants.SERVLET_LOGOUT; + redirectURL = response.encodeRedirectURL(redirectURL); + response.setContentType("text/html"); + response.setStatus(302); + response.addHeader("Location", redirectURL); + } + + private void processMessage(HttpServletRequest request, HttpServletResponse response, + XMLObject xmlObject, String relayState) throws ConfigurationException, PVP2Exception, + NoSuchAlgorithmException { + if (xmlObject instanceof LogoutRequest) { + final LogoutResponse sloResp = + processLogOutRequest((LogoutRequest) xmlObject, request); + sendMessage(request, response, sloResp, relayState); + + } else if (xmlObject instanceof LogoutResponse) { + final LogoutResponse sloResp = (LogoutResponse) xmlObject; + + final String reqID = (String) request.getSession().getAttribute(Constants.SESSION_PVP2REQUESTID); + request.getSession().setAttribute(Constants.SESSION_PVP2REQUESTID, null); + validateLogOutResponse(sloResp, reqID, request, response); + + } + } + + private void sendMessage(HttpServletRequest request, HttpServletResponse response, + RequestAbstractType sloReq, String relayState) throws ConfigurationException, PVP2Exception { + final SingleLogoutService sloService = findIDPFrontChannelSLOService(); + sloReq.setDestination(sloService.getLocation()); + sendMessage(request, response, sloReq, sloService, relayState); + } + + private void sendMessage(HttpServletRequest request, HttpServletResponse response, + StatusResponseType sloReq, String relayState) throws ConfigurationException, PVP2Exception { + final SingleLogoutService sloService = findIDPFrontChannelSLOService(); + sloReq.setDestination(sloService.getLocation()); + sendMessage(request, response, sloReq, sloService, relayState); + } + + private void sendMessage(HttpServletRequest request, HttpServletResponse response, + SignableSAMLObject sloReq, SingleLogoutService sloService, String relayState) + throws ConfigurationException, PVP2Exception { + final X509Credential authcredential = PVP2Utils.signMessage((AbstractSignableXMLObject) sloReq, + getConfig()); + if (sloService.getBinding().equals(SAMLConstants.SAML2_POST_BINDING_URI)) { + PVP2Utils.postBindingEncoder(request, response, sloReq, authcredential, sloService.getLocation(), + relayState); + } else if (sloService.getBinding().equals(SAMLConstants.SAML2_REDIRECT_BINDING_URI)) { + PVP2Utils.redirectBindingEncoder(request, response, sloReq, authcredential, sloService.getLocation(), + relayState); + } + } + } |