aboutsummaryrefslogtreecommitdiff
path: root/id/ConfigWebTool/src/main/java/at/gv/egovernment/moa/id/configuration/auth/pvp2/servlets/SLOBasicServlet.java
diff options
context:
space:
mode:
authorThomas Lenz <tlenz@iaik.tugraz.at>2014-06-03 17:10:11 +0200
committerThomas Lenz <tlenz@iaik.tugraz.at>2014-06-03 17:10:11 +0200
commit78c78fc0045580d3456fcb9563209223cf425eb6 (patch)
tree740c5808173030046856879571ec721c241d72da /id/ConfigWebTool/src/main/java/at/gv/egovernment/moa/id/configuration/auth/pvp2/servlets/SLOBasicServlet.java
parentcc20e4171331f78a1bb188f2b885c9754da58a28 (diff)
downloadmoa-id-spss-78c78fc0045580d3456fcb9563209223cf425eb6.tar.gz
moa-id-spss-78c78fc0045580d3456fcb9563209223cf425eb6.tar.bz2
moa-id-spss-78c78fc0045580d3456fcb9563209223cf425eb6.zip
implement configuration tool single logout
Diffstat (limited to 'id/ConfigWebTool/src/main/java/at/gv/egovernment/moa/id/configuration/auth/pvp2/servlets/SLOBasicServlet.java')
-rw-r--r--id/ConfigWebTool/src/main/java/at/gv/egovernment/moa/id/configuration/auth/pvp2/servlets/SLOBasicServlet.java271
1 files changed, 271 insertions, 0 deletions
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
new file mode 100644
index 000000000..69adcc661
--- /dev/null
+++ b/id/ConfigWebTool/src/main/java/at/gv/egovernment/moa/id/configuration/auth/pvp2/servlets/SLOBasicServlet.java
@@ -0,0 +1,271 @@
+/*
+ * Copyright 2014 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+package at.gv.egovernment.moa.id.configuration.auth.pvp2.servlets;
+
+import java.security.NoSuchAlgorithmException;
+
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+
+import org.joda.time.DateTime;
+import org.opensaml.common.impl.SecureRandomIdentifierGenerator;
+import org.opensaml.common.xml.SAMLConstants;
+import org.opensaml.saml2.core.Issuer;
+import org.opensaml.saml2.core.LogoutRequest;
+import org.opensaml.saml2.core.LogoutResponse;
+import org.opensaml.saml2.core.NameID;
+import org.opensaml.saml2.core.NameIDType;
+import org.opensaml.saml2.core.Status;
+import org.opensaml.saml2.core.StatusCode;
+import org.opensaml.saml2.metadata.EntityDescriptor;
+import org.opensaml.saml2.metadata.SingleLogoutService;
+import org.opensaml.saml2.metadata.provider.HTTPMetadataProvider;
+import org.opensaml.saml2.metadata.provider.MetadataProviderException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import at.gv.egovernment.moa.id.configuration.Constants;
+import at.gv.egovernment.moa.id.configuration.auth.AuthenticatedUser;
+import at.gv.egovernment.moa.id.configuration.auth.AuthenticationManager;
+import at.gv.egovernment.moa.id.configuration.config.ConfigurationProvider;
+import at.gv.egovernment.moa.id.configuration.exception.ConfigurationException;
+import at.gv.egovernment.moa.id.configuration.exception.PVP2Exception;
+import at.gv.egovernment.moa.id.configuration.exception.SLOException;
+import at.gv.egovernment.moa.id.configuration.helper.LanguageHelper;
+import at.gv.egovernment.moa.id.configuration.utils.SAML2Utils;
+import at.gv.egovernment.moa.util.MiscUtil;
+
+/**
+ * @author tlenz
+ *
+ */
+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());
+ request.getSession().setAttribute(Constants.SESSION_PVP2REQUESTID, sloReq.getID());
+ 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.PARTIAL_LOGOUT_URI, request);
+
+ }
+
+ }
+
+ private 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)) {
+ log.info("Single LogOut process complete.");
+ request.getSession().setAttribute(Constants.SESSION_SLOSUCCESS,
+ LanguageHelper.getErrorString("webpages.slo.success", 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;
+ }
+
+}