Search in sources :

Example 1 with WSSecurityException

use of org.apache.wss4j.common.ext.WSSecurityException in project midpoint by Evolveum.

the class WsFaultListener method faultOccurred.

@Override
public boolean faultOccurred(Exception exception, String description, Message message) {
    LOGGER.trace("Handling fault: {}: {} - {}", new Object[] { exception, description, message, exception });
    Object audited = message.getContextualProperty(SecurityHelper.CONTEXTUAL_PROPERTY_AUDITED_NAME);
    if (audited != null && ((Boolean) audited)) {
        return true;
    }
    if (exception instanceof PasswordCallbackException) {
        return true;
    }
    if (exception.getCause() instanceof PasswordCallbackException) {
        return true;
    }
    if (exception.getCause() != null && exception.getCause().getCause() instanceof PasswordCallbackException) {
        return true;
    }
    try {
        String auditMessage = exception.getMessage();
        if (exception.getClass() != null) {
            // Exception cause has much better message because CXF masks real messages in the SOAP faults.
            auditMessage = exception.getCause().getMessage();
        }
        SOAPMessage saajSoapMessage = message.getContent(SOAPMessage.class);
        String username = securityHelper.getUsernameFromMessage(saajSoapMessage);
        ConnectionEnvironment connEnv = ConnectionEnvironment.create(SchemaConstants.CHANNEL_WEB_SERVICE_URI);
        securityHelper.auditLoginFailure(username, null, connEnv, auditMessage);
    } catch (WSSecurityException e) {
        // Ignore
        LOGGER.trace("Exception getting username from soap message (probably safe to ignore)", e);
    } catch (Exception e) {
        LOGGER.error("Error auditing SOAP fault: " + e.getMessage(), e);
    // but otherwise ignore it
    }
    return true;
}
Also used : WSSecurityException(org.apache.wss4j.common.ext.WSSecurityException) SOAPMessage(javax.xml.soap.SOAPMessage) WSSecurityException(org.apache.wss4j.common.ext.WSSecurityException) ConnectionEnvironment(com.evolveum.midpoint.security.api.ConnectionEnvironment)

Example 2 with WSSecurityException

use of org.apache.wss4j.common.ext.WSSecurityException in project midpoint by Evolveum.

the class SpringAuthenticationInjectorInterceptor method handleMessage.

@Override
public void handleMessage(SoapMessage message) throws Fault {
    //Note: in constructor we have specified that we will be called after we have been successfully authenticated the user through WS-Security
    //Now we will only set the Spring Authentication object based on the user found in the header
    LOGGER.trace("Intercepted message: {}", message);
    SOAPMessage saajSoapMessage = securityHelper.getSOAPMessage(message);
    if (saajSoapMessage == null) {
        LOGGER.error("No soap message in handler");
        throw createFault(WSSecurityException.ErrorCode.FAILURE);
    }
    ConnectionEnvironment connEnv = ConnectionEnvironment.create(SchemaConstants.CHANNEL_WEB_SERVICE_URI);
    String username = null;
    try {
        username = securityHelper.getUsernameFromMessage(saajSoapMessage);
        LOGGER.trace("Attempt to authenticate user '{}'", username);
        if (StringUtils.isBlank(username)) {
            message.put(SecurityHelper.CONTEXTUAL_PROPERTY_AUDITED_NAME, true);
            securityHelper.auditLoginFailure(username, null, connEnv, "Empty username");
            throw createFault(WSSecurityException.ErrorCode.FAILED_AUTHENTICATION);
        }
        MidPointPrincipal principal;
        try {
            principal = userDetailsService.getPrincipal(username);
        } catch (SchemaException e) {
            LOGGER.debug("Access to web service denied for user '{}': schema error: {}", username, e.getMessage(), e);
            message.put(SecurityHelper.CONTEXTUAL_PROPERTY_AUDITED_NAME, true);
            securityHelper.auditLoginFailure(username, null, connEnv, "Schema error: " + e.getMessage());
            throw new Fault(e);
        }
        LOGGER.trace("Principal: {}", principal);
        if (principal == null) {
            message.put(SecurityHelper.CONTEXTUAL_PROPERTY_AUDITED_NAME, true);
            securityHelper.auditLoginFailure(username, null, connEnv, "No user");
            throw createFault(WSSecurityException.ErrorCode.FAILED_AUTHENTICATION);
        }
        // Account validity and credentials and all this stuff should be already checked
        // in the password callback
        Authentication authentication = new UsernamePasswordAuthenticationToken(principal, null);
        SecurityContextHolder.getContext().setAuthentication(authentication);
        String operationName;
        try {
            operationName = DOMUtil.getFirstChildElement(saajSoapMessage.getSOAPBody()).getLocalName();
        } catch (SOAPException e) {
            LOGGER.debug("Access to web service denied for user '{}': SOAP error: {}", username, e.getMessage(), e);
            message.put(SecurityHelper.CONTEXTUAL_PROPERTY_AUDITED_NAME, true);
            securityHelper.auditLoginFailure(username, principal.getUser(), connEnv, "SOAP error: " + e.getMessage());
            throw new Fault(e);
        }
        // AUTHORIZATION
        boolean isAuthorized;
        try {
            isAuthorized = securityEnforcer.isAuthorized(AuthorizationConstants.AUTZ_WS_ALL_URL, AuthorizationPhaseType.REQUEST, null, null, null, null);
            LOGGER.trace("Determined authorization for web service access (action: {}): {}", AuthorizationConstants.AUTZ_WS_ALL_URL, isAuthorized);
        } catch (SchemaException e) {
            LOGGER.debug("Access to web service denied for user '{}': schema error: {}", username, e.getMessage(), e);
            message.put(SecurityHelper.CONTEXTUAL_PROPERTY_AUDITED_NAME, true);
            securityHelper.auditLoginFailure(username, principal.getUser(), connEnv, "Schema error: " + e.getMessage());
            throw createFault(WSSecurityException.ErrorCode.FAILURE);
        }
        if (!isAuthorized) {
            String action = QNameUtil.qNameToUri(new QName(AuthorizationConstants.NS_AUTHORIZATION_WS, operationName));
            try {
                isAuthorized = securityEnforcer.isAuthorized(action, AuthorizationPhaseType.REQUEST, null, null, null, null);
                LOGGER.trace("Determined authorization for web service operation {} (action: {}): {}", operationName, action, isAuthorized);
            } catch (SchemaException e) {
                LOGGER.debug("Access to web service denied for user '{}': schema error: {}", username, e.getMessage(), e);
                message.put(SecurityHelper.CONTEXTUAL_PROPERTY_AUDITED_NAME, true);
                securityHelper.auditLoginFailure(username, principal.getUser(), connEnv, "Schema error: " + e.getMessage());
                throw createFault(WSSecurityException.ErrorCode.FAILURE);
            }
        }
        if (!isAuthorized) {
            LOGGER.debug("Access to web service denied for user '{}': not authorized", username);
            message.put(SecurityHelper.CONTEXTUAL_PROPERTY_AUDITED_NAME, true);
            securityHelper.auditLoginFailure(username, principal.getUser(), connEnv, "Not authorized");
            throw createFault(WSSecurityException.ErrorCode.FAILED_AUTHENTICATION);
        }
    } catch (WSSecurityException e) {
        LOGGER.debug("Access to web service denied for user '{}': security exception: {}", username, e.getMessage(), e);
        message.put(SecurityHelper.CONTEXTUAL_PROPERTY_AUDITED_NAME, true);
        securityHelper.auditLoginFailure(username, null, connEnv, "Security exception: " + e.getMessage());
        throw new Fault(e, e.getFaultCode());
    } catch (ObjectNotFoundException e) {
        LOGGER.debug("Access to web service denied for user '{}': object not found: {}", username, e.getMessage(), e);
        message.put(SecurityHelper.CONTEXTUAL_PROPERTY_AUDITED_NAME, true);
        securityHelper.auditLoginFailure(username, null, connEnv, "No user");
        throw createFault(WSSecurityException.ErrorCode.FAILED_AUTHENTICATION);
    }
    // Avoid auditing login attempt again if the operation fails on internal authorization
    message.put(SecurityHelper.CONTEXTUAL_PROPERTY_AUDITED_NAME, true);
    LOGGER.debug("Access to web service allowed for user '{}'", username);
}
Also used : SchemaException(com.evolveum.midpoint.util.exception.SchemaException) QName(javax.xml.namespace.QName) Fault(org.apache.cxf.interceptor.Fault) UsernamePasswordAuthenticationToken(org.springframework.security.authentication.UsernamePasswordAuthenticationToken) WSSecurityException(org.apache.wss4j.common.ext.WSSecurityException) SOAPMessage(javax.xml.soap.SOAPMessage) ConnectionEnvironment(com.evolveum.midpoint.security.api.ConnectionEnvironment) Authentication(org.springframework.security.core.Authentication) SOAPException(javax.xml.soap.SOAPException) ObjectNotFoundException(com.evolveum.midpoint.util.exception.ObjectNotFoundException) MidPointPrincipal(com.evolveum.midpoint.security.api.MidPointPrincipal)

Example 3 with WSSecurityException

use of org.apache.wss4j.common.ext.WSSecurityException in project ddf by codice.

the class SimpleSign method validateSignature.

public void validateSignature(Signature signature, Document doc) throws SignatureException {
    RequestData requestData = new RequestData();
    requestData.setSigVerCrypto(crypto.getSignatureCrypto());
    WSSConfig wssConfig = WSSConfig.getNewInstance();
    requestData.setWssConfig(wssConfig);
    SAMLKeyInfo samlKeyInfo = null;
    KeyInfo keyInfo = signature.getKeyInfo();
    if (keyInfo != null) {
        try {
            samlKeyInfo = SAMLUtil.getCredentialFromKeyInfo(keyInfo.getDOM(), new WSSSAMLKeyInfoProcessor(requestData, new WSDocInfo(doc)), crypto.getSignatureCrypto());
        } catch (WSSecurityException e) {
            throw new SignatureException("Unable to get KeyInfo.", e);
        }
    }
    if (samlKeyInfo == null) {
        throw new SignatureException("No KeyInfo supplied in the signature");
    }
    validateSignatureAndSamlKey(signature, samlKeyInfo);
    Credential trustCredential = new Credential();
    trustCredential.setPublicKey(samlKeyInfo.getPublicKey());
    trustCredential.setCertificates(samlKeyInfo.getCerts());
    Validator signatureValidator = new SignatureTrustValidator();
    try {
        signatureValidator.validate(trustCredential, requestData);
    } catch (WSSecurityException e) {
        throw new SignatureException("Error validating signature", e);
    }
}
Also used : WSDocInfo(org.apache.wss4j.dom.WSDocInfo) Credential(org.apache.wss4j.dom.validate.Credential) BasicX509Credential(org.opensaml.security.x509.BasicX509Credential) SAMLKeyInfo(org.apache.wss4j.common.saml.SAMLKeyInfo) WSSConfig(org.apache.wss4j.dom.engine.WSSConfig) KeyInfo(org.opensaml.xmlsec.signature.KeyInfo) SAMLKeyInfo(org.apache.wss4j.common.saml.SAMLKeyInfo) RequestData(org.apache.wss4j.dom.handler.RequestData) SignatureTrustValidator(org.apache.wss4j.dom.validate.SignatureTrustValidator) WSSecurityException(org.apache.wss4j.common.ext.WSSecurityException) WSSSAMLKeyInfoProcessor(org.apache.wss4j.dom.saml.WSSSAMLKeyInfoProcessor) Validator(org.apache.wss4j.dom.validate.Validator) SignatureValidator(org.opensaml.xmlsec.signature.support.SignatureValidator) SAMLSignatureProfileValidator(org.opensaml.saml.security.impl.SAMLSignatureProfileValidator) SignatureTrustValidator(org.apache.wss4j.dom.validate.SignatureTrustValidator)

Example 4 with WSSecurityException

use of org.apache.wss4j.common.ext.WSSecurityException in project ddf by codice.

the class IdpEndpoint method continueLogout.

private Response continueLogout(LogoutState logoutState, Cookie cookie, SamlProtocol.Binding incomingBinding) throws IdpException {
    if (logoutState == null) {
        throw new IdpException("Cannot continue a Logout that doesn't exist!");
    }
    try {
        SignableSAMLObject logoutObject;
        String relay = "";
        String entityId = "";
        SamlProtocol.Type samlType;
        Optional<String> nextTarget = logoutState.getNextTarget();
        if (nextTarget.isPresent()) {
            // Another target exists, log them out
            entityId = nextTarget.get();
            if (logoutState.getOriginalIssuer().equals(entityId)) {
                return continueLogout(logoutState, cookie, incomingBinding);
            }
            LogoutRequest logoutRequest = logoutMessage.buildLogoutRequest(logoutState.getNameId(), SystemBaseUrl.constructUrl("/idp/logout", true));
            logoutState.setCurrentRequestId(logoutRequest.getID());
            logoutObject = logoutRequest;
            samlType = SamlProtocol.Type.REQUEST;
            relay = "";
        } else {
            // No more targets, respond to original issuer
            entityId = logoutState.getOriginalIssuer();
            String status = logoutState.isPartialLogout() ? StatusCode.PARTIAL_LOGOUT : StatusCode.SUCCESS;
            logoutObject = logoutMessage.buildLogoutResponse(SystemBaseUrl.constructUrl("/idp/logout", true), status, logoutState.getOriginalRequestId());
            relay = logoutState.getInitialRelayState();
            LogoutState decode = logoutStates.decode(cookie.getValue(), true);
            samlType = SamlProtocol.Type.RESPONSE;
        }
        LOGGER.debug("Responding to [{}] with a [{}] and relay state [{}]", entityId, samlType, relay);
        EntityInformation.ServiceInfo entityServiceInfo = serviceProviders.get(entityId).getLogoutService(incomingBinding);
        if (entityServiceInfo == null) {
            LOGGER.info("Could not find entity service info for {}", entityId);
            return continueLogout(logoutState, cookie, incomingBinding);
        }
        switch(entityServiceInfo.getBinding()) {
            case HTTP_REDIRECT:
                return getSamlRedirectResponse(logoutObject, entityServiceInfo.getUrl(), relay, samlType);
            case HTTP_POST:
                return getSamlPostResponse(logoutObject, entityServiceInfo.getUrl(), relay, samlType);
            default:
                LOGGER.debug("No supported binding available for SP [{}].", entityId);
                logoutState.setPartialLogout(true);
                return continueLogout(logoutState, cookie, incomingBinding);
        }
    } catch (WSSecurityException | SimpleSign.SignatureException | IOException e) {
        LOGGER.debug("Error while processing logout", e);
    }
    throw new IdpException("Server error while processing logout");
}
Also used : WSSecurityException(org.apache.wss4j.common.ext.WSSecurityException) IOException(java.io.IOException) SamlProtocol(ddf.security.samlp.SamlProtocol) SignableSAMLObject(org.opensaml.saml.common.SignableSAMLObject) EntityInformation(ddf.security.samlp.impl.EntityInformation) LogoutRequest(org.opensaml.saml.saml2.core.LogoutRequest)

Example 5 with WSSecurityException

use of org.apache.wss4j.common.ext.WSSecurityException in project ddf by codice.

the class IdpEndpoint method doSoapLogin.

@POST
@Path("/login")
@Consumes({ "text/xml", "application/soap+xml" })
public Response doSoapLogin(InputStream body, @Context HttpServletRequest request) {
    if (!request.isSecure()) {
        throw new IllegalArgumentException("Authn Request must use TLS.");
    }
    SoapBinding soapBinding = new SoapBinding(systemCrypto, serviceProviders);
    try {
        String bodyStr = IOUtils.toString(body);
        AuthnRequest authnRequest = soapBinding.decoder().decodeRequest(bodyStr);
        String relayState = ((SoapRequestDecoder) soapBinding.decoder()).decodeRelayState(bodyStr);
        soapBinding.validator().validateRelayState(relayState);
        soapBinding.validator().validateAuthnRequest(authnRequest, bodyStr, null, null, null, strictSignature);
        boolean hasCookie = hasValidCookie(request, authnRequest.isForceAuthn());
        AuthObj authObj = determineAuthMethod(bodyStr, authnRequest);
        org.opensaml.saml.saml2.core.Response response = handleLogin(authnRequest, authObj.method, request, authObj, authnRequest.isPassive(), hasCookie);
        Response samlpResponse = soapBinding.creator().getSamlpResponse(relayState, authnRequest, response, null, soapMessage);
        samlpResponse.getHeaders().put("SOAPAction", Collections.singletonList("http://www.oasis-open.org/committees/security"));
        return samlpResponse;
    } catch (IOException e) {
        LOGGER.debug("Unable to decode SOAP AuthN Request", e);
    } catch (SimpleSign.SignatureException e) {
        LOGGER.debug("Unable to validate signature.", e);
    } catch (ValidationException e) {
        LOGGER.debug("Unable to validate request.", e);
    } catch (SecurityServiceException e) {
        LOGGER.debug("Unable to authenticate user.", e);
    } catch (WSSecurityException | IllegalArgumentException e) {
        LOGGER.debug("Bad request.", e);
    }
    return null;
}
Also used : SecurityServiceException(ddf.security.service.SecurityServiceException) ValidationException(ddf.security.samlp.ValidationException) WSSecurityException(org.apache.wss4j.common.ext.WSSecurityException) SoapRequestDecoder(org.codice.ddf.security.idp.binding.soap.SoapRequestDecoder) IOException(java.io.IOException) SoapBinding(org.codice.ddf.security.idp.binding.soap.SoapBinding) LogoutResponse(org.opensaml.saml.saml2.core.LogoutResponse) Response(javax.ws.rs.core.Response) SimpleSign(ddf.security.samlp.SimpleSign) AuthnRequest(org.opensaml.saml.saml2.core.AuthnRequest) Path(javax.ws.rs.Path) POST(javax.ws.rs.POST) Consumes(javax.ws.rs.Consumes)

Aggregations

WSSecurityException (org.apache.wss4j.common.ext.WSSecurityException)226 Element (org.w3c.dom.Element)72 Crypto (org.apache.wss4j.common.crypto.Crypto)50 Document (org.w3c.dom.Document)48 IOException (java.io.IOException)41 SamlAssertionWrapper (org.apache.wss4j.common.saml.SamlAssertionWrapper)38 Credential (org.apache.wss4j.dom.validate.Credential)37 RequestData (org.apache.wss4j.dom.handler.RequestData)34 Response (org.opensaml.saml.saml2.core.Response)31 X509Certificate (java.security.cert.X509Certificate)29 SAMLCallback (org.apache.wss4j.common.saml.SAMLCallback)25 DateTime (org.joda.time.DateTime)22 XMLObject (org.opensaml.core.xml.XMLObject)22 XMLStreamException (javax.xml.stream.XMLStreamException)21 SecurityToken (org.apache.cxf.ws.security.tokenstore.SecurityToken)21 SOAPException (javax.xml.soap.SOAPException)19 CallbackHandler (javax.security.auth.callback.CallbackHandler)18 Fault (org.apache.cxf.interceptor.Fault)18 ReceivedToken (org.apache.cxf.sts.request.ReceivedToken)17 QName (javax.xml.namespace.QName)15