Search in sources :

Example 6 with ValidationException

use of ddf.security.samlp.ValidationException in project ddf by codice.

the class IdpEndpoint method showLoginPage.

private Response showLoginPage(String samlRequest, String relayState, String signatureAlgorithm, String signature, HttpServletRequest request, Binding binding, String template, String originalBinding) throws WSSecurityException {
    String responseStr;
    AuthnRequest authnRequest = null;
    try {
        Map<String, Object> responseMap = new HashMap<>();
        binding.validator().validateRelayState(relayState);
        authnRequest = binding.decoder().decodeRequest(samlRequest);
        authnRequest.getIssueInstant();
        binding.validator().validateAuthnRequest(authnRequest, samlRequest, relayState, signatureAlgorithm, signature, strictSignature);
        if (!request.isSecure()) {
            throw new IllegalArgumentException("Authn Request must use TLS.");
        }
        X509Certificate[] certs = (X509Certificate[]) request.getAttribute(CERTIFICATES_ATTR);
        boolean hasCerts = (certs != null && certs.length > 0);
        boolean hasCookie = hasValidCookie(request, authnRequest.isForceAuthn());
        if ((authnRequest.isPassive() && hasCerts) || hasCookie) {
            LOGGER.debug("Received Passive & PKI AuthnRequest.");
            org.opensaml.saml.saml2.core.Response samlpResponse;
            try {
                samlpResponse = handleLogin(authnRequest, PKI, request, null, authnRequest.isPassive(), hasCookie);
                LOGGER.debug("Passive & PKI AuthnRequest logged in successfully.");
            } catch (SecurityServiceException e) {
                LOGGER.debug(e.getMessage(), e);
                return getErrorResponse(relayState, authnRequest, StatusCode.AUTHN_FAILED, binding);
            } catch (WSSecurityException e) {
                LOGGER.debug(e.getMessage(), e);
                return getErrorResponse(relayState, authnRequest, StatusCode.REQUEST_DENIED, binding);
            } catch (SimpleSign.SignatureException | ConstraintViolationException e) {
                LOGGER.debug(e.getMessage(), e);
                return getErrorResponse(relayState, authnRequest, StatusCode.REQUEST_UNSUPPORTED, binding);
            }
            LOGGER.debug("Returning Passive & PKI SAML Response.");
            NewCookie cookie = null;
            if (hasCookie) {
                cookieCache.addActiveSp(getCookie(request).getValue(), authnRequest.getIssuer().getValue());
            } else {
                cookie = createCookie(request, samlpResponse);
                if (cookie != null) {
                    cookieCache.addActiveSp(cookie.getValue(), authnRequest.getIssuer().getValue());
                }
            }
            logAddedSp(authnRequest);
            return binding.creator().getSamlpResponse(relayState, authnRequest, samlpResponse, cookie, template);
        } else {
            LOGGER.debug("Building the JSON map to embed in the index.html page for login.");
            Document doc = DOMUtils.createDocument();
            doc.appendChild(doc.createElement("root"));
            String authn = DOM2Writer.nodeToString(OpenSAMLUtil.toDom(authnRequest, doc, false));
            String encodedAuthn = RestSecurity.deflateAndBase64Encode(authn);
            responseMap.put(PKI, hasCerts);
            responseMap.put(GUEST, guestAccess);
            responseMap.put(SAML_REQ, encodedAuthn);
            responseMap.put(RELAY_STATE, relayState);
            String assertionConsumerServiceURL = ((ResponseCreatorImpl) binding.creator()).getAssertionConsumerServiceURL(authnRequest);
            responseMap.put(ACS_URL, assertionConsumerServiceURL);
            responseMap.put(SSOConstants.SIG_ALG, signatureAlgorithm);
            responseMap.put(SSOConstants.SIGNATURE, signature);
            responseMap.put(ORIGINAL_BINDING, originalBinding);
        }
        String json = Boon.toJson(responseMap);
        LOGGER.debug("Returning index.html page.");
        responseStr = indexHtml.replace(IDP_STATE_OBJ, json);
        return Response.ok(responseStr).build();
    } catch (IllegalArgumentException e) {
        LOGGER.debug(e.getMessage(), e);
        if (authnRequest != null) {
            try {
                return getErrorResponse(relayState, authnRequest, StatusCode.REQUEST_UNSUPPORTED, binding);
            } catch (IOException | SimpleSign.SignatureException e1) {
                LOGGER.debug(e1.getMessage(), e1);
            }
        }
    } catch (UnsupportedOperationException e) {
        LOGGER.debug(e.getMessage(), e);
        if (authnRequest != null) {
            try {
                return getErrorResponse(relayState, authnRequest, StatusCode.UNSUPPORTED_BINDING, binding);
            } catch (IOException | SimpleSign.SignatureException e1) {
                LOGGER.debug(e1.getMessage(), e1);
            }
        }
    } catch (SimpleSign.SignatureException e) {
        LOGGER.debug("Unable to validate AuthRequest Signature", e);
    } catch (IOException e) {
        LOGGER.debug("Unable to decode AuthRequest", e);
    } catch (ValidationException e) {
        LOGGER.debug("AuthnRequest schema validation failed.", e);
    }
    return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
}
Also used : SecurityServiceException(ddf.security.service.SecurityServiceException) ValidationException(ddf.security.samlp.ValidationException) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) Document(org.w3c.dom.Document) SimpleSign(ddf.security.samlp.SimpleSign) ConstraintViolationException(net.shibboleth.utilities.java.support.logic.ConstraintViolationException) NewCookie(javax.ws.rs.core.NewCookie) ResponseCreatorImpl(org.codice.ddf.security.idp.binding.api.impl.ResponseCreatorImpl) WSSecurityException(org.apache.wss4j.common.ext.WSSecurityException) IOException(java.io.IOException) X509Certificate(java.security.cert.X509Certificate) AuthnRequest(org.opensaml.saml.saml2.core.AuthnRequest) SignableSAMLObject(org.opensaml.saml.common.SignableSAMLObject) SignableXMLObject(org.opensaml.xmlsec.signature.SignableXMLObject) XMLObject(org.opensaml.core.xml.XMLObject)

Example 7 with ValidationException

use of ddf.security.samlp.ValidationException in project ddf by codice.

the class AuthnResponseValidator method validate.

public void validate(XMLObject xmlObject) throws ValidationException {
    if (!(xmlObject instanceof Response)) {
        throw new ValidationException("Invalid AuthN response XML.");
    }
    Response authnResponse = (Response) xmlObject;
    String status = authnResponse.getStatus().getStatusCode().getValue();
    if (!StatusCode.SUCCESS.equals(status)) {
        throw new ValidationException("AuthN request was unsuccessful.  Received status: " + status);
    }
    if (authnResponse.getAssertions().size() < 1) {
        throw new ValidationException("Assertion missing in AuthN response.");
    }
    if (authnResponse.getAssertions().size() > 1) {
        LOGGER.info("Received multiple assertions in AuthN response.  Only using the first assertion.");
    }
    if (authnResponse.getSignature() != null) {
        try {
            simpleSign.validateSignature(authnResponse.getSignature(), authnResponse.getDOM().getOwnerDocument());
        } catch (SimpleSign.SignatureException e) {
            throw new ValidationException("Invalid or untrusted signature.");
        }
    }
}
Also used : Response(org.opensaml.saml.saml2.core.Response) SimpleSign(ddf.security.samlp.SimpleSign) ValidationException(ddf.security.samlp.ValidationException)

Example 8 with ValidationException

use of ddf.security.samlp.ValidationException in project ddf by codice.

the class LogoutRequestService method getLogoutRequest.

@GET
public Response getLogoutRequest(@QueryParam(SAML_REQUEST) String deflatedSamlRequest, @QueryParam(SAML_RESPONSE) String deflatedSamlResponse, @QueryParam(RELAY_STATE) String relayState, @QueryParam(SIG_ALG) String signatureAlgorithm, @QueryParam(SIGNATURE) String signature) {
    if (deflatedSamlRequest != null) {
        try {
            LogoutRequest logoutRequest = logoutMessage.extractSamlLogoutRequest(RestSecurity.inflateBase64(deflatedSamlRequest));
            if (logoutRequest == null) {
                String msg = "Unable to parse logout request.";
                return buildLogoutResponse(msg);
            }
            buildAndValidateSaml(deflatedSamlRequest, relayState, signatureAlgorithm, signature, logoutRequest);
            logout();
            String entityId = getEntityId();
            LogoutResponse logoutResponse = logoutMessage.buildLogoutResponse(entityId, StatusCode.SUCCESS, logoutRequest.getID());
            return getLogoutResponse(relayState, logoutResponse);
        } catch (IOException e) {
            String msg = "Unable to decode and inflate logout request.";
            LOGGER.info(msg, e);
            return buildLogoutResponse(msg);
        } catch (ValidationException e) {
            String msg = "Unable to validate";
            LOGGER.info(msg, e);
            return buildLogoutResponse(msg);
        } catch (WSSecurityException | XMLStreamException e) {
            String msg = "Unable to parse logout request.";
            LOGGER.info(msg, e);
            return buildLogoutResponse(msg);
        }
    } else {
        try {
            LogoutResponse logoutResponse = logoutMessage.extractSamlLogoutResponse(RestSecurity.inflateBase64(deflatedSamlResponse));
            if (logoutResponse == null) {
                String msg = "Unable to parse logout response.";
                LOGGER.debug(msg);
                return buildLogoutResponse(msg);
            }
            buildAndValidateSaml(deflatedSamlResponse, relayState, signatureAlgorithm, signature, logoutResponse);
            String nameId = "You";
            String decodedValue;
            if (relayState != null && (decodedValue = relayStates.decode(relayState)) != null) {
                nameId = decodedValue;
            }
            return buildLogoutResponse(nameId + " logged out successfully.");
        } catch (IOException e) {
            String msg = "Unable to decode and inflate logout response.";
            LOGGER.info(msg, e);
            return buildLogoutResponse(msg);
        } catch (ValidationException e) {
            String msg = "Unable to validate";
            LOGGER.info(msg, e);
            return buildLogoutResponse(msg);
        } catch (WSSecurityException | XMLStreamException e) {
            String msg = "Unable to parse logout response.";
            LOGGER.info(msg, e);
            return buildLogoutResponse(msg);
        }
    }
}
Also used : ValidationException(ddf.security.samlp.ValidationException) LogoutResponse(org.opensaml.saml.saml2.core.LogoutResponse) XMLStreamException(javax.xml.stream.XMLStreamException) LogoutRequest(org.opensaml.saml.saml2.core.LogoutRequest) WSSecurityException(org.apache.wss4j.common.ext.WSSecurityException) IOException(java.io.IOException) GET(javax.ws.rs.GET)

Example 9 with ValidationException

use of ddf.security.samlp.ValidationException in project ddf by codice.

the class LogoutRequestService method postLogoutRequest.

@POST
@Produces(MediaType.APPLICATION_FORM_URLENCODED)
public Response postLogoutRequest(@FormParam(SAML_REQUEST) String encodedSamlRequest, @FormParam(SAML_REQUEST) String encodedSamlResponse, @FormParam(RELAY_STATE) String relayState) {
    if (encodedSamlRequest != null) {
        try {
            LogoutRequest logoutRequest = logoutMessage.extractSamlLogoutRequest(decodeBase64(encodedSamlRequest));
            if (logoutRequest == null) {
                String msg = "Unable to parse logout request.";
                LOGGER.debug(msg);
                return buildLogoutResponse(msg);
            }
            new SamlValidator.Builder(simpleSign).buildAndValidate(request.getRequestURL().toString(), SamlProtocol.Binding.HTTP_POST, logoutRequest);
            logout();
            LogoutResponse logoutResponse = logoutMessage.buildLogoutResponse(logoutRequest.getIssuer().getValue(), StatusCode.SUCCESS, logoutRequest.getID());
            return getLogoutResponse(relayState, logoutResponse);
        } catch (WSSecurityException e) {
            String msg = "Failed to sign logout response.";
            LOGGER.info(msg, e);
            return buildLogoutResponse(msg);
        } catch (ValidationException e) {
            String msg = "Unable to validate";
            LOGGER.info(msg, e);
            return buildLogoutResponse(msg);
        } catch (XMLStreamException e) {
            String msg = "Unable to parse logout request.";
            LOGGER.info(msg, e);
            return buildLogoutResponse(msg);
        }
    } else {
        try {
            LogoutResponse logoutResponse = logoutMessage.extractSamlLogoutResponse(decodeBase64(encodedSamlResponse));
            if (logoutResponse == null) {
                String msg = "Unable to parse logout response.";
                LOGGER.info(msg);
                return buildLogoutResponse(msg);
            }
            new SamlValidator.Builder(simpleSign).buildAndValidate(request.getRequestURL().toString(), SamlProtocol.Binding.HTTP_POST, logoutResponse);
        } catch (ValidationException e) {
            String msg = "Unable to validate";
            LOGGER.info(msg, e);
            return buildLogoutResponse(msg);
        } catch (WSSecurityException | XMLStreamException e) {
            String msg = "Unable to parse logout response.";
            LOGGER.info(msg, e);
            return buildLogoutResponse(msg);
        }
        String nameId = "You";
        String decodedValue;
        if (relayState != null && (decodedValue = relayStates.decode(relayState)) != null) {
            nameId = decodedValue;
        }
        return buildLogoutResponse(nameId + " logged out successfully.");
    }
}
Also used : ValidationException(ddf.security.samlp.ValidationException) LogoutResponse(org.opensaml.saml.saml2.core.LogoutResponse) XMLStreamException(javax.xml.stream.XMLStreamException) SamlValidator(ddf.security.samlp.impl.SamlValidator) LogoutRequest(org.opensaml.saml.saml2.core.LogoutRequest) WSSecurityException(org.apache.wss4j.common.ext.WSSecurityException) POST(javax.ws.rs.POST) Produces(javax.ws.rs.Produces)

Example 10 with ValidationException

use of ddf.security.samlp.ValidationException in project ddf by codice.

the class RedirectValidator method validateAuthnRequest.

@Override
public void validateAuthnRequest(AuthnRequest authnRequest, String samlRequest, String relayState, String signatureAlgorithm, String signature, boolean strictSignature) throws SimpleSign.SignatureException, ValidationException {
    LOGGER.debug("Validating AuthnRequest required attributes and signature");
    if (strictSignature) {
        if (!StringUtils.isEmpty(signature) && !StringUtils.isEmpty(signatureAlgorithm)) {
            String signedParts;
            try {
                signedParts = String.format("SAMLRequest=%s&RelayState=%s&SigAlg=%s", URLEncoder.encode(samlRequest, "UTF-8"), relayState, URLEncoder.encode(signatureAlgorithm, "UTF-8"));
            } catch (UnsupportedEncodingException e) {
                throw new SimpleSign.SignatureException("Unable to construct signed query parts.", e);
            }
            EntityInformation entityInformation = getServiceProviders().get(authnRequest.getIssuer().getValue());
            if (entityInformation == null) {
                throw new ValidationException(String.format("Unable to find metadata for %s", authnRequest.getIssuer().getValue()));
            }
            String encryptionCertificate = entityInformation.getEncryptionCertificate();
            String signingCertificate = entityInformation.getSigningCertificate();
            if (signingCertificate == null) {
                throw new ValidationException("Unable to find signing certificate in metadata. Please check metadata.");
            }
            boolean result = getSimpleSign().validateSignature(signedParts, signature, signingCertificate);
            if (!result) {
                throw new ValidationException("Signature verification failed for redirect binding.");
            }
        } else {
            throw new SimpleSign.SignatureException("No signature present for AuthnRequest.");
        }
    }
    super.validateAuthnRequest(authnRequest, samlRequest, relayState, signatureAlgorithm, signature, strictSignature);
}
Also used : SimpleSign(ddf.security.samlp.SimpleSign) ValidationException(ddf.security.samlp.ValidationException) UnsupportedEncodingException(java.io.UnsupportedEncodingException) EntityInformation(ddf.security.samlp.impl.EntityInformation)

Aggregations

ValidationException (ddf.security.samlp.ValidationException)10 IOException (java.io.IOException)6 LogoutResponse (org.opensaml.saml.saml2.core.LogoutResponse)6 SimpleSign (ddf.security.samlp.SimpleSign)5 WSSecurityException (org.apache.wss4j.common.ext.WSSecurityException)5 Path (javax.ws.rs.Path)4 NewCookie (javax.ws.rs.core.NewCookie)4 XMLStreamException (javax.xml.stream.XMLStreamException)4 LogoutRequest (org.opensaml.saml.saml2.core.LogoutRequest)4 SecurityServiceException (ddf.security.service.SecurityServiceException)3 GET (javax.ws.rs.GET)3 POST (javax.ws.rs.POST)3 AuthnRequest (org.opensaml.saml.saml2.core.AuthnRequest)3 Cookie (javax.servlet.http.Cookie)2 Response (javax.ws.rs.core.Response)2 SoapBinding (org.codice.ddf.security.idp.binding.soap.SoapBinding)2 EntityInformation (ddf.security.samlp.impl.EntityInformation)1 SamlValidator (ddf.security.samlp.impl.SamlValidator)1 UnsupportedEncodingException (java.io.UnsupportedEncodingException)1 X509Certificate (java.security.cert.X509Certificate)1