Skip to content

Commit

Permalink
Proper initialization of WSS. ModelClientUtil. Improved WS tests.
Browse files Browse the repository at this point in the history
  • Loading branch information
semancik committed Mar 31, 2015
1 parent dbf6cec commit 6679d76
Show file tree
Hide file tree
Showing 13 changed files with 528 additions and 90 deletions.
Expand Up @@ -15,7 +15,11 @@
*/
package com.evolveum.midpoint.model.client;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
import java.util.HashMap;
import java.util.List;
Expand Down Expand Up @@ -73,6 +77,7 @@ public class ModelClientUtil {
public static final QName TYPES_CLEAR_VALUE = new QName(NS_TYPES, "clearValue");

private static final DocumentBuilder domDocumentBuilder;
private static final JAXBContext jaxbContext;

public static JAXBContext instantiateJaxbContext() throws JAXBException {
return JAXBContext.newInstance("com.evolveum.midpoint.xml.ns._public.common.api_types_3:" +
Expand Down Expand Up @@ -240,18 +245,49 @@ public static ObjectDeltaOperationType findInDeltaOperationList(ObjectDeltaOpera
}
return null;
}

static {

public static <O> O unmarshallResource(String path) throws JAXBException, FileNotFoundException {
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();

InputStream is = null;
JAXBElement<O> element = null;
try {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
domDocumentBuilder = factory.newDocumentBuilder();
} catch (ParserConfigurationException ex) {
throw new IllegalStateException("Error creating XML document " + ex.getMessage());
is = ModelClientUtil.class.getClassLoader().getResourceAsStream(path);
if (is == null) {
throw new FileNotFoundException("System resource "+path+" was not found");
}
element = (JAXBElement<O>) unmarshaller.unmarshal(is);
} finally {
if (is != null) {
IOUtils.closeQuietly(is);
}
}
if (element == null) {
return null;
}
return element.getValue();
}

public static <O extends ObjectType> String toString(O obj) {
public static <O> O unmarshallFile(File file) throws JAXBException, FileNotFoundException {
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();

InputStream is = null;
JAXBElement<O> element = null;
try {
is = new FileInputStream(file);
element = (JAXBElement<O>) unmarshaller.unmarshal(is);
} finally {
if (is != null) {
IOUtils.closeQuietly(is);
}
}
if (element == null) {
return null;
}
return element.getValue();
}

public static <O extends ObjectType> String toString(O obj) {
if (obj == null) {
return null;
}
Expand All @@ -276,4 +312,22 @@ public static String toString(PolyStringType poly) {
return getOrig(poly);
}


static {
try {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
domDocumentBuilder = factory.newDocumentBuilder();
} catch (ParserConfigurationException e) {
throw new IllegalStateException("Error creating XML document " + e.getMessage());
}

try {
jaxbContext = ModelClientUtil.instantiateJaxbContext();
} catch (JAXBException e) {
throw new IllegalStateException("Error creating JAXB context " + e.getMessage());
}
}


}
Expand Up @@ -130,8 +130,9 @@ public void getObject(QName objectType, String oid, SelectorQualifiedGetOptionsT
return;
} catch (Exception ex) {
LoggingUtils.logException(LOGGER, "# MODEL getObject() failed", ex);
auditLogout(task);
throw createSystemFault(ex, operationResult);
} finally {
auditLogout(task);
}
}

Expand All @@ -156,8 +157,9 @@ public void searchObjects(QName objectType, QueryType query, SelectorQualifiedGe
objectListHolder.value = listType;
} catch (Exception ex) {
LoggingUtils.logException(LOGGER, "# MODEL searchObjects() failed", ex);
auditLogout(task);
throw createSystemFault(ex, operationResult);
} finally {
auditLogout(task);
}
}

Expand Down Expand Up @@ -185,8 +187,9 @@ public ObjectDeltaOperationListType executeChanges(ObjectDeltaListType deltaList
return retval;
} catch (Exception ex) {
LoggingUtils.logException(LOGGER, "# MODEL executeChanges() failed", ex);
auditLogout(task);
throw createSystemFault(ex, operationResult);
} finally {
auditLogout(task);
}
}

Expand All @@ -207,8 +210,9 @@ public void findShadowOwner(String accountOid, Holder<UserType> userHolder, Hold
return;
} catch (Exception ex) {
LoggingUtils.logException(LOGGER, "# MODEL findShadowOwner() failed", ex);
auditLogout(task);
throw createSystemFault(ex, operationResult);
} finally {
auditLogout(task);
}
}

Expand All @@ -223,8 +227,9 @@ public OperationResultType testResource(String resourceOid) throws FaultMessage
return handleOperationResult(testResult);
} catch (Exception ex) {
LoggingUtils.logException(LOGGER, "# MODEL testResource() failed", ex);
auditLogout(task);
throw createSystemFault(ex, null);
} finally {
auditLogout(task);
}
}

Expand All @@ -238,8 +243,9 @@ public ExecuteScriptsResponseType executeScripts(ExecuteScriptsType parameters)
return doExecuteScripts(scriptsToExecute, parameters.getOptions(), task, result);
} catch (Exception ex) {
LoggingUtils.logException(LOGGER, "# MODEL executeScripts() failed", ex);
auditLogout(task);
throw createSystemFault(ex, null);
} finally {
auditLogout(task);
}
}

Expand Down Expand Up @@ -454,8 +460,5 @@ public TaskType notifyChange(ResourceObjectShadowChangeDescriptionType changeDes
private TaskType handleTaskResult(Task task) {
return task.getTaskPrismObject().asObjectable();
}





}
Expand Up @@ -46,6 +46,7 @@
import org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor;
import org.apache.ws.commons.schema.utils.DOMUtil;
import org.apache.wss4j.common.ext.WSSecurityException;
import org.apache.wss4j.common.ext.WSSecurityException.ErrorCode;
import org.apache.wss4j.dom.util.WSSecurityUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
Expand Down Expand Up @@ -123,7 +124,7 @@ public void handleMessage(SoapMessage message) throws Fault {
SOAPMessage saajSoapMessage = securityHelper.getSOAPMessage(message);
if (saajSoapMessage == null) {
LOGGER.error("No soap message in handler");
throw new Fault(new WSSecurityException(WSSecurityException.ErrorCode.FAILURE));
throw createFault(WSSecurityException.ErrorCode.FAILURE);
}
String username = null;
try {
Expand All @@ -133,15 +134,15 @@ public void handleMessage(SoapMessage message) throws Fault {
if (StringUtils.isBlank(username)) {
message.setContextualProperty(SecurityHelper.CONTEXTUAL_PROPERTY_AUDITED_NAME, true);
securityHelper.auditLoginFailure(username, "Empty username", SchemaConstants.CHANNEL_WEB_SERVICE_URI);
throw new Fault(new WSSecurityException(WSSecurityException.ErrorCode.FAILED_AUTHENTICATION));
throw createFault(WSSecurityException.ErrorCode.FAILED_AUTHENTICATION);
}

MidPointPrincipal principal = userDetailsService.getPrincipal(username);
LOGGER.trace("Principal: {}", principal);
if (principal == null) {
message.setContextualProperty(SecurityHelper.CONTEXTUAL_PROPERTY_AUDITED_NAME, true);
securityHelper.auditLoginFailure(username, "No user", SchemaConstants.CHANNEL_WEB_SERVICE_URI);
throw new Fault(new WSSecurityException(WSSecurityException.ErrorCode.FAILED_AUTHENTICATION));
throw createFault(WSSecurityException.ErrorCode.FAILED_AUTHENTICATION);
}
Authentication authentication = new UsernamePasswordAuthenticationToken(principal, null);
SecurityContextHolder.getContext().setAuthentication(authentication);
Expand All @@ -166,34 +167,38 @@ public void handleMessage(SoapMessage message) throws Fault {
new Object[]{username, e.getMessage(), e});
message.setContextualProperty(SecurityHelper.CONTEXTUAL_PROPERTY_AUDITED_NAME, true);
securityHelper.auditLoginFailure(username, "Schema error: "+e.getMessage(), SchemaConstants.CHANNEL_WEB_SERVICE_URI);
throw new Fault(e);
throw createFault(WSSecurityException.ErrorCode.FAILURE);
}
if (!isAuthorized) {
LOGGER.debug("Access to web service denied for user '{}': not authorized",
new Object[]{username});
message.setContextualProperty(SecurityHelper.CONTEXTUAL_PROPERTY_AUDITED_NAME, true);
securityHelper.auditLoginFailure(username, "Not authorized", SchemaConstants.CHANNEL_WEB_SERVICE_URI);
throw new Fault(new WSSecurityException(WSSecurityException.ErrorCode.FAILED_AUTHENTICATION));
throw createFault(WSSecurityException.ErrorCode.FAILED_AUTHENTICATION);
}

} catch (WSSecurityException e) {
LOGGER.debug("Access to web service denied for user '{}': security exception: {}",
new Object[]{username, e.getMessage(), e});
message.setContextualProperty(SecurityHelper.CONTEXTUAL_PROPERTY_AUDITED_NAME, true);
securityHelper.auditLoginFailure(username, "Security exception: "+e.getMessage(), SchemaConstants.CHANNEL_WEB_SERVICE_URI);
throw new Fault(e);
throw new Fault(e, e.getFaultCode());
} catch (ObjectNotFoundException e) {
LOGGER.debug("Access to web service denied for user '{}': object not found: {}",
new Object[]{username, e.getMessage(), e});
message.setContextualProperty(SecurityHelper.CONTEXTUAL_PROPERTY_AUDITED_NAME, true);
securityHelper.auditLoginFailure(username, "No user", SchemaConstants.CHANNEL_WEB_SERVICE_URI);
throw new Fault(new WSSecurityException(WSSecurityException.ErrorCode.FAILED_AUTHENTICATION));
throw createFault(WSSecurityException.ErrorCode.FAILED_AUTHENTICATION);
}

LOGGER.debug("Access to web service allowed for user '{}'", username);
}

@Override
private Fault createFault(ErrorCode code) {
return new Fault(new WSSecurityException(code), code.getQName());
}

@Override
public void handleFault(SoapMessage message) {
// Nothing to do
}
Expand Down
5 changes: 5 additions & 0 deletions repo/system-init/pom.xml
Expand Up @@ -64,6 +64,11 @@
<artifactId>common</artifactId>
<version>3.2-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-ws-security</artifactId>
<version>${cxf.version}</version>
</dependency>

<!-- this dependency is here, because we don't have hammer factory factory for cache repository in system init-->
<dependency>
Expand Down
Expand Up @@ -29,6 +29,7 @@
import com.evolveum.midpoint.util.logging.TraceManager;

import org.apache.commons.configuration.*;
import org.apache.wss4j.dom.WSSConfig;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;

Expand Down Expand Up @@ -175,6 +176,11 @@ public void init() {
LOGGER.info("Safe mode is ON; setting tolerateUndeclaredPrefixes to TRUE");
QNameUtil.setTolerateUndeclaredPrefixes(true);
}

// Make sure that this is called very early in the startup sequence.
// This is needed to properly initialize the resources
// (the "org/apache/xml/security/resource/xmlsecurity" resource bundle error)
WSSConfig.init();
}

/**
Expand Down
Expand Up @@ -303,60 +303,17 @@ private static String createUserGuybrush(ModelPortType modelPort, RoleType role)
}

private static String createUserFromSystemResource(ModelPortType modelPort, String resourcePath) throws FileNotFoundException, JAXBException, FaultMessage {
UserType user = unmarshallResource(resourcePath);
UserType user = ModelClientUtil.unmarshallResource(resourcePath);

return createUser(modelPort, user);
}

private static String createRoleFromSystemResource(ModelPortType modelPort, String resourcePath) throws FileNotFoundException, JAXBException, FaultMessage {
RoleType role = unmarshallResource(resourcePath);
RoleType role = ModelClientUtil.unmarshallResource(resourcePath);

return createRole(modelPort, role);
}

private static <T> T unmarshallFile(File file) throws JAXBException, FileNotFoundException {
JAXBContext jc = ModelClientUtil.instantiateJaxbContext();
Unmarshaller unmarshaller = jc.createUnmarshaller();

InputStream is = null;
JAXBElement<T> element = null;
try {
is = new FileInputStream(file);
element = (JAXBElement<T>) unmarshaller.unmarshal(is);
} finally {
if (is != null) {
IOUtils.closeQuietly(is);
}
}
if (element == null) {
return null;
}
return element.getValue();
}

private static <T> T unmarshallResource(String path) throws JAXBException, FileNotFoundException {
JAXBContext jc = ModelClientUtil.instantiateJaxbContext();
Unmarshaller unmarshaller = jc.createUnmarshaller();

InputStream is = null;
JAXBElement<T> element = null;
try {
is = Main.class.getClassLoader().getResourceAsStream(path);
if (is == null) {
throw new FileNotFoundException("System resource "+path+" was not found");
}
element = (JAXBElement<T>) unmarshaller.unmarshal(is);
} finally {
if (is != null) {
IOUtils.closeQuietly(is);
}
}
if (element == null) {
return null;
}
return element.getValue();
}

private static String createUser(ModelPortType modelPort, UserType userType) throws FaultMessage {
ObjectDeltaType deltaType = new ObjectDeltaType();
deltaType.setObjectType(ModelClientUtil.getTypeQName(UserType.class));
Expand Down

0 comments on commit 6679d76

Please sign in to comment.