diff options
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.java | 228 |
1 files changed, 201 insertions, 27 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 7aa860c5c..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,31 +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; @@ -57,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); @@ -76,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); @@ -95,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) { @@ -123,6 +266,37 @@ 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); @@ -140,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; |