aboutsummaryrefslogtreecommitdiff
path: root/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/SingleLogOutBuilder.java
diff options
context:
space:
mode:
Diffstat (limited to 'id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/SingleLogOutBuilder.java')
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/SingleLogOutBuilder.java247
1 files changed, 213 insertions, 34 deletions
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/SingleLogOutBuilder.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/SingleLogOutBuilder.java
index 04d374e93..eeb1dd104 100644
--- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/SingleLogOutBuilder.java
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/SingleLogOutBuilder.java
@@ -22,30 +22,53 @@
*/
package at.gv.egovernment.moa.id.protocols.pvp2x.builder;
+import java.security.NoSuchAlgorithmException;
import java.util.List;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
import org.joda.time.DateTime;
+import org.opensaml.common.SAMLObject;
+import org.opensaml.common.binding.BasicSAMLMessageContext;
+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.RequestAbstractType;
import org.opensaml.saml2.core.Status;
import org.opensaml.saml2.core.StatusCode;
import org.opensaml.saml2.core.StatusMessage;
+import org.opensaml.saml2.core.StatusResponseType;
import org.opensaml.saml2.metadata.EntityDescriptor;
import org.opensaml.saml2.metadata.SPSSODescriptor;
+import org.opensaml.saml2.metadata.SSODescriptor;
import org.opensaml.saml2.metadata.SingleLogoutService;
+import org.opensaml.saml2.metadata.impl.SingleLogoutServiceBuilder;
import org.opensaml.saml2.metadata.provider.MetadataProviderException;
+import org.opensaml.ws.message.encoder.MessageEncodingException;
+import org.opensaml.xml.security.SecurityException;
+import org.opensaml.xml.security.x509.X509Credential;
+import at.gv.egovernment.moa.id.auth.exception.AuthenticationException;
+import at.gv.egovernment.moa.id.auth.exception.MOAIDException;
import at.gv.egovernment.moa.id.config.ConfigurationException;
+import at.gv.egovernment.moa.id.data.SLOInformationContainer;
import at.gv.egovernment.moa.id.data.SLOInformationImpl;
+import at.gv.egovernment.moa.id.opemsaml.MOAStringRedirectDeflateEncoder;
import at.gv.egovernment.moa.id.protocols.pvp2x.PVPTargetConfiguration;
+import at.gv.egovernment.moa.id.protocols.pvp2x.binding.IEncoder;
+import at.gv.egovernment.moa.id.protocols.pvp2x.binding.PostBinding;
+import at.gv.egovernment.moa.id.protocols.pvp2x.binding.RedirectBinding;
import at.gv.egovernment.moa.id.protocols.pvp2x.config.PVPConfiguration;
+import at.gv.egovernment.moa.id.protocols.pvp2x.exceptions.BindingNotSupportedException;
import at.gv.egovernment.moa.id.protocols.pvp2x.exceptions.NOSLOServiceDescriptorException;
import at.gv.egovernment.moa.id.protocols.pvp2x.exceptions.NoMetadataInformationException;
import at.gv.egovernment.moa.id.protocols.pvp2x.messages.MOARequest;
import at.gv.egovernment.moa.id.protocols.pvp2x.metadata.MOAMetadataProvider;
+import at.gv.egovernment.moa.id.protocols.pvp2x.signer.CredentialProvider;
import at.gv.egovernment.moa.id.protocols.pvp2x.utils.SAML2Utils;
import at.gv.egovernment.moa.id.util.MOAIDMessageProvider;
import at.gv.egovernment.moa.logging.Logger;
@@ -56,9 +79,141 @@ import at.gv.egovernment.moa.logging.Logger;
*/
public class SingleLogOutBuilder {
- public static LogoutRequest buildSLORequestMessage(SLOInformationImpl sloInfo) throws ConfigurationException {
+ public static void checkStatusCode(SLOInformationContainer sloContainer, LogoutResponse logOutResp) {
+ Status status = logOutResp.getStatus();
+ if (!status.getStatusCode().getValue().equals(StatusCode.SUCCESS_URI)) {
+ String message = " Message: ";
+ if (status.getStatusMessage() != null)
+ message += status.getStatusMessage().getMessage();
+ Logger.warn("Single LogOut for OA " + logOutResp.getIssuer().getValue()
+ + " FAILED. (ResponseCode: " + status.getStatusCode().getValue()
+ + message + ")");
+ sloContainer.putFailedOA(logOutResp.getIssuer().getValue());
+
+ } else
+ sloContainer.removeFrontChannelOA(logOutResp.getIssuer().getValue());
+ Logger.debug("Single LogOut for OA " + logOutResp.getIssuer().getValue() + " SUCCESS");
+
+ }
+
+ /**
+ * @param serviceURL
+ * @param binding
+ * @param sloReq
+ * @param httpReq
+ * @param httpResp
+ * @param relayState
+ * @return
+ */
+ public static String getFrontChannelSLOMessageURL(String serviceURL, String bindingType,
+ RequestAbstractType sloReq, HttpServletRequest httpReq,
+ HttpServletResponse httpResp, String relayState) throws MOAIDException {
+
+ try {
+ X509Credential credentials = CredentialProvider
+ .getIDPAssertionSigningCredential();
+
+ Logger.debug("create SAML RedirectBinding response");
+
+ MOAStringRedirectDeflateEncoder encoder = new MOAStringRedirectDeflateEncoder();
+ BasicSAMLMessageContext<SAMLObject, SAMLObject, SAMLObject> context = new BasicSAMLMessageContext<SAMLObject, SAMLObject, SAMLObject>();
+ SingleLogoutService service = new SingleLogoutServiceBuilder()
+ .buildObject();
+ service.setBinding(SAMLConstants.SAML2_REDIRECT_BINDING_URI);
+ service.setLocation(serviceURL);
+ context.setOutboundSAMLMessageSigningCredential(credentials);
+ context.setPeerEntityEndpoint(service);
+ context.setOutboundSAMLMessage(sloReq);
+ context.setRelayState(relayState);
+
+ encoder.encode(context);
+
+ return encoder.getRedirectURL();
+
+ } catch (MessageEncodingException e) {
+ Logger.error("Message Encoding exception", e);
+ throw new MOAIDException("pvp2.01", null, e);
+
+ }
+ }
+
+ public static String getFrontChannelSLOMessageURL(SingleLogoutService service,
+ StatusResponseType sloResp, HttpServletRequest httpReq,
+ HttpServletResponse httpResp, String relayState) throws MOAIDException {
+
+ try {
+ X509Credential credentials = CredentialProvider
+ .getIDPAssertionSigningCredential();
+
+ Logger.debug("create SAML RedirectBinding response");
+
+ MOAStringRedirectDeflateEncoder encoder = new MOAStringRedirectDeflateEncoder();
+ BasicSAMLMessageContext<SAMLObject, SAMLObject, SAMLObject> context = new BasicSAMLMessageContext<SAMLObject, SAMLObject, SAMLObject>();
+ context.setOutboundSAMLMessageSigningCredential(credentials);
+ context.setPeerEntityEndpoint(service);
+ context.setOutboundSAMLMessage(sloResp);
+ context.setRelayState(relayState);
+
+ encoder.encode(context);
+
+ return encoder.getRedirectURL();
+
+ } catch (MessageEncodingException e) {
+ Logger.error("Message Encoding exception", e);
+ throw new MOAIDException("pvp2.01", null, e);
+
+ }
+ }
+
+ public static void sendFrontChannelSLOMessage(SingleLogoutService consumerService,
+ LogoutResponse sloResp, HttpServletRequest req, HttpServletResponse resp,
+ String relayState) throws MOAIDException {
+ IEncoder binding = null;
+ if (consumerService.getBinding().equals(
+ SAMLConstants.SAML2_REDIRECT_BINDING_URI)) {
+ binding = new RedirectBinding();
+
+ } else if (consumerService.getBinding().equals(
+ SAMLConstants.SAML2_POST_BINDING_URI)) {
+ binding = new PostBinding();
+
+ }
+
+ if (binding == null) {
+ throw new BindingNotSupportedException(consumerService.getBinding());
+ }
+
+ try {
+ binding.encodeRespone(req, resp, sloResp,
+ consumerService.getLocation(), relayState);
+
+ } catch (MessageEncodingException e) {
+ Logger.error("Message Encoding exception", e);
+ throw new MOAIDException("pvp2.01", null, e);
+
+ } catch (SecurityException e) {
+ Logger.error("Security exception", e);
+ throw new MOAIDException("pvp2.01", null, e);
+
+ }
+ }
+
+
+ public static LogoutRequest buildSLORequestMessage(SLOInformationImpl sloInfo) throws ConfigurationException, MOAIDException {
LogoutRequest sloReq = SAML2Utils.createSAMLObject(LogoutRequest.class);
+ SecureRandomIdentifierGenerator gen;
+ try {
+ gen = new SecureRandomIdentifierGenerator();
+ sloReq.setID(gen.generateIdentifier());
+
+ } catch (NoSuchAlgorithmException e) {
+ Logger.error("Internal server error", e);
+ throw new AuthenticationException("pvp2.13", new Object[]{});
+
+ }
+
+
Issuer issuer = SAML2Utils.createSAMLObject(Issuer.class);
issuer.setValue(PVPConfiguration.getInstance().getIDPPublicPath());
issuer.setFormat(NameID.ENTITY);
@@ -75,14 +230,9 @@ public class SingleLogOutBuilder {
return sloReq;
}
- public static LogoutResponse buildSLOErrorResponse(SingleLogoutService sloService, PVPTargetConfiguration spRequest) throws ConfigurationException {
- LogoutResponse sloResp = SAML2Utils.createSAMLObject(LogoutResponse.class);
- Issuer issuer = SAML2Utils.createSAMLObject(Issuer.class);
- issuer.setValue(PVPConfiguration.getInstance().getIDPPublicPath());
- issuer.setFormat(NameID.ENTITY);
- sloResp.setIssuer(issuer);
- sloResp.setIssueInstant(new DateTime());
- sloResp.setDestination(sloService.getLocation());
+ public static LogoutResponse buildSLOErrorResponse(SingleLogoutService sloService, PVPTargetConfiguration spRequest) throws ConfigurationException, MOAIDException {
+ LogoutResponse sloResp = buildBasicResponse(sloService, spRequest);
+
Status status = SAML2Utils.createSAMLObject(Status.class);
StatusCode statusCode = SAML2Utils.createSAMLObject(StatusCode.class);
StatusMessage statusMessage = SAML2Utils.createSAMLObject(StatusMessage.class);
@@ -94,14 +244,8 @@ public class SingleLogOutBuilder {
return sloResp;
}
- public static LogoutResponse buildSLOResponseMessage(SingleLogoutService sloService, PVPTargetConfiguration spRequest, List<String> failedOAs) throws ConfigurationException {
- LogoutResponse sloResp = SAML2Utils.createSAMLObject(LogoutResponse.class);
- Issuer issuer = SAML2Utils.createSAMLObject(Issuer.class);
- issuer.setValue(PVPConfiguration.getInstance().getIDPPublicPath());
- issuer.setFormat(NameID.ENTITY);
- sloResp.setIssuer(issuer);
- sloResp.setIssueInstant(new DateTime());
- sloResp.setDestination(sloService.getLocation());
+ public static LogoutResponse buildSLOResponseMessage(SingleLogoutService sloService, PVPTargetConfiguration spRequest, List<String> failedOAs) throws MOAIDException {
+ LogoutResponse sloResp = buildBasicResponse(sloService, spRequest);
Status status;
if (failedOAs == null || failedOAs.size() == 0) {
@@ -122,10 +266,41 @@ public class SingleLogOutBuilder {
}
+ private static LogoutResponse buildBasicResponse(SingleLogoutService sloService, PVPTargetConfiguration spRequest) throws ConfigurationException, MOAIDException {
+ LogoutResponse sloResp = SAML2Utils.createSAMLObject(LogoutResponse.class);
+ Issuer issuer = SAML2Utils.createSAMLObject(Issuer.class);
+ issuer.setValue(PVPConfiguration.getInstance().getIDPPublicPath());
+ issuer.setFormat(NameID.ENTITY);
+ sloResp.setIssuer(issuer);
+ sloResp.setIssueInstant(new DateTime());
+ sloResp.setDestination(sloService.getLocation());
+
+ SecureRandomIdentifierGenerator gen;
+ try {
+ gen = new SecureRandomIdentifierGenerator();
+ sloResp.setID(gen.generateIdentifier());
+
+ } catch (NoSuchAlgorithmException e) {
+ Logger.error("Internal server error", e);
+ throw new AuthenticationException("pvp2.13", new Object[]{});
+
+ }
+
+ if (spRequest.getRequest() instanceof MOARequest &&
+ ((MOARequest)spRequest.getRequest()).getSamlRequest() instanceof LogoutRequest) {
+ LogoutRequest sloReq = (LogoutRequest) ((MOARequest)spRequest.getRequest()).getSamlRequest();
+ sloResp.setInResponseTo(sloReq.getID());
+
+ }
+
+ return sloResp;
+
+ }
+
public static SingleLogoutService getRequestSLODescriptor(String entityID) throws NOSLOServiceDescriptorException {
try {
EntityDescriptor entity = MOAMetadataProvider.getInstance().getEntityDescriptor(entityID);
- SPSSODescriptor spsso = entity.getSPSSODescriptor(SAMLConstants.SAML20P_NS);
+ SSODescriptor spsso = entity.getSPSSODescriptor(SAMLConstants.SAML20P_NS);
SingleLogoutService sloService = null;
for (SingleLogoutService el : spsso.getSingleLogoutServices()) {
@@ -139,19 +314,19 @@ public class SingleLogOutBuilder {
)
sloService = el;
- else if (el.getBinding().equals(SAMLConstants.SAML2_POST_BINDING_URI)
- && (
- (sloService != null
- && !sloService.getBinding().equals(SAMLConstants.SAML2_SOAP11_BINDING_URI)
- && !sloService.getBinding().equals(SAMLConstants.SAML2_REDIRECT_BINDING_URI))
- || sloService == null)
- )
- sloService = el;
+// else if (el.getBinding().equals(SAMLConstants.SAML2_POST_BINDING_URI)
+// && (
+// (sloService != null
+// && !sloService.getBinding().equals(SAMLConstants.SAML2_SOAP11_BINDING_URI)
+// && !sloService.getBinding().equals(SAMLConstants.SAML2_REDIRECT_BINDING_URI))
+// || sloService == null)
+// )
+// sloService = el;
}
if (sloService == null) {
- Logger.error("Found no SLO ServiceDescriptor in Metadata");
- throw new NOSLOServiceDescriptorException("NO SLO ServiceDescriptor", null);
+ Logger.error("Found no valid SLO ServiceDescriptor in Metadata");
+ throw new NOSLOServiceDescriptorException("NO valid SLO ServiceDescriptor", null);
}
return sloService;
@@ -173,14 +348,18 @@ public class SingleLogOutBuilder {
if (el.getBinding().equals(spRequest.getBinding()))
sloService = el;
}
- if (sloService == null && spsso.getSingleLogoutServices().size() != 0)
- sloService = spsso.getSingleLogoutServices().get(0);
- else {
- Logger.error("Found no SLO ServiceDescriptor in Metadata");
- throw new NOSLOServiceDescriptorException("NO SLO ServiceDescriptor", null);
+ if (sloService == null) {
+ if (spsso.getSingleLogoutServices().size() != 0)
+ sloService = spsso.getSingleLogoutServices().get(0);
+
+ else {
+ Logger.error("Found no SLO ServiceDescriptor in Metadata");
+ throw new NOSLOServiceDescriptorException("NO SLO ServiceDescriptor", null);
+ }
}
- return sloService;
+
+ return sloService;
}
}