Author: anil.saldhana(a)jboss.com
Date: 2011-07-13 15:35:11 -0400 (Wed, 13 Jul 2011)
New Revision: 1088
Added:
trust/trunk/jbossws/src/main/java/org/picketlink/trust/jbossws/util/JBossWSNativeStackUtil.java
trust/trunk/jbossws/src/main/java/org/picketlink/trust/jbossws/util/SecurityActions.java
Modified:
trust/trunk/jbossws/src/main/java/org/picketlink/trust/jbossws/handler/WSAuthorizationHandler.java
Log:
use native stack internals as reflection in the case the JBossWS stack does not set the
port name on the message context
Modified:
trust/trunk/jbossws/src/main/java/org/picketlink/trust/jbossws/handler/WSAuthorizationHandler.java
===================================================================
---
trust/trunk/jbossws/src/main/java/org/picketlink/trust/jbossws/handler/WSAuthorizationHandler.java 2011-07-13
19:34:25 UTC (rev 1087)
+++
trust/trunk/jbossws/src/main/java/org/picketlink/trust/jbossws/handler/WSAuthorizationHandler.java 2011-07-13
19:35:11 UTC (rev 1088)
@@ -32,7 +32,11 @@
import javax.security.auth.Subject;
import javax.servlet.ServletContext;
import javax.xml.namespace.QName;
+import javax.xml.soap.SOAPBody;
+import javax.xml.soap.SOAPException;
+import javax.xml.soap.SOAPMessage;
import javax.xml.ws.handler.MessageContext;
+import javax.xml.ws.handler.soap.SOAPMessageContext;
import org.jboss.security.AuthorizationManager;
import org.jboss.security.SecurityContext;
@@ -40,7 +44,9 @@
import org.jboss.security.callbacks.SecurityContextCallbackHandler;
import org.jboss.wsf.spi.invocation.SecurityAdaptor;
import org.picketlink.identity.federation.core.exceptions.ProcessingException;
+import org.picketlink.trust.jbossws.util.JBossWSNativeStackUtil;
import org.picketlink.trust.jbossws.util.JBossWSSERoleExtractor;
+import org.w3c.dom.Node;
/**
* An authorization handler for the POJO Web services
@@ -63,6 +69,7 @@
if(trace)
{
log.trace("Handling Inbound Message");
+ trace(msgContext);
}
ServletContext context = (ServletContext)
msgContext.get(MessageContext.SERVLET_CONTEXT);
//Read the jboss-wsse.xml file
@@ -70,12 +77,24 @@
if( is == null )
throw new RuntimeException( "unable to load jboss-wsse.xml");
- QName portName = (QName) msgContext.get(MessageContext.WSDL_PORT);
+ QName portName = (QName) msgContext.get(MessageContext.WSDL_PORT);
QName opName = (QName) msgContext.get(MessageContext.WSDL_OPERATION);
+
+ if(portName == null)
+ portName = JBossWSNativeStackUtil.getPortNameViaReflection(getClass(),
msgContext);
+ if(portName == null)
+ throw new RuntimeException("Unable to determine port name from the message
context");
+
+ if(opName == null)
+ opName = getOperationName(msgContext);
+
+ if(opName == null)
+ throw new RuntimeException("Unable to determine operation name from the
message context");
+
List<String> roles = null;
- String key = portName.getLocalPart()+"_" + opName.toString();
+ String key = portName.getLocalPart()+ "_" + opName.toString();
//First check in cache
if( cache.containsKey(key))
@@ -146,4 +165,25 @@
is = cl.getResourceAsStream("/WEB-INF/jboss-wsse.xml");
return is;
}
+
+ private QName getOperationName(MessageContext msgContext)
+ {
+ SOAPMessageContext soapMessageContext = (SOAPMessageContext) msgContext;
+ SOAPMessage soapMessage = soapMessageContext.getMessage();
+ SOAPBody soapBody;
+ try
+ {
+ soapBody = soapMessage.getSOAPBody();
+ Node child = soapBody.getFirstChild();
+ String childNamespace = child.getNamespaceURI();
+ String childName = child.getLocalName();
+ return new QName(childNamespace, childName);
+ }
+ catch (SOAPException e)
+ {
+ if(trace)
+ log.trace("Exception using backup method to get op name=",e);
+ }
+ return null;
+ }
}
\ No newline at end of file
Added:
trust/trunk/jbossws/src/main/java/org/picketlink/trust/jbossws/util/JBossWSNativeStackUtil.java
===================================================================
---
trust/trunk/jbossws/src/main/java/org/picketlink/trust/jbossws/util/JBossWSNativeStackUtil.java
(rev 0)
+++
trust/trunk/jbossws/src/main/java/org/picketlink/trust/jbossws/util/JBossWSNativeStackUtil.java 2011-07-13
19:35:11 UTC (rev 1088)
@@ -0,0 +1,70 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.picketlink.trust.jbossws.util;
+
+import java.lang.reflect.Method;
+
+import javax.xml.namespace.QName;
+import javax.xml.ws.handler.MessageContext;
+
+import org.jboss.logging.Logger;
+
+
+/**
+ * Utility class that uses reflection on the
+ * JBossWS Native Stack as backup strategy
+ *
+ * @author Anil.Saldhana(a)redhat.com
+ * @since Jul 13, 2011
+ */
+public class JBossWSNativeStackUtil
+{
+ protected static Logger log = Logger.getLogger(JBossWSNativeStackUtil.class);
+ protected static boolean trace = log.isTraceEnabled();
+
+ /**
+ * It is unfortunate that the {@link MessageContext} does not contain the port name.
+ * We will use reflection on the JBoss WS Native stack
+ * @param msgContext
+ * @return
+ */
+ public static QName getPortNameViaReflection(Class<?> callingClazz,
MessageContext msgContext)
+ {
+ try
+ {
+ Class<?> clazz =
SecurityActions.getClassLoader(callingClazz).loadClass("org.jboss.ws.core.jaxws.handler.SOAPMessageContextJAXWS");
+ Method endpointMDMethod = clazz.getMethod("getEndpointMetaData", new
Class[0]);
+ Object endpointMD = endpointMDMethod.invoke(msgContext, new Object[0]);
+
+ clazz =
SecurityActions.getClassLoader(callingClazz).loadClass("org.jboss.ws.metadata.umdm.EndpointMetaData");
+ Method portNameMethod = clazz.getMethod("getPortName", new Class[0]);
+
+ return (QName) portNameMethod.invoke(endpointMD, new Object[0]);
+ }
+ catch (Exception e)
+ {
+ if(trace)
+ log.trace("Exception using backup method to get port name=",e);
+ }
+ return null;
+ }
+}
\ No newline at end of file
Added:
trust/trunk/jbossws/src/main/java/org/picketlink/trust/jbossws/util/SecurityActions.java
===================================================================
---
trust/trunk/jbossws/src/main/java/org/picketlink/trust/jbossws/util/SecurityActions.java
(rev 0)
+++
trust/trunk/jbossws/src/main/java/org/picketlink/trust/jbossws/util/SecurityActions.java 2011-07-13
19:35:11 UTC (rev 1088)
@@ -0,0 +1,167 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2010, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.picketlink.trust.jbossws.util;
+
+import java.security.AccessController;
+import java.security.Principal;
+import java.security.PrivilegedAction;
+import java.security.acl.Group;
+import java.util.List;
+
+import javax.security.auth.Subject;
+
+import org.jboss.security.SecurityConstants;
+import org.jboss.security.SecurityContext;
+import org.jboss.security.SecurityContextAssociation;
+import org.jboss.security.SecurityContextFactory;
+import org.jboss.security.SimplePrincipal;
+import org.picketlink.identity.federation.bindings.jboss.subject.PicketLinkGroup;
+
+/**
+ * Privileged actions.
+ *
+ * @author <a href="mmoyses(a)redhat.com">Marcus Moyses</a>
+ * @author Anil Saldhana
+ * @version $Revision: 1 $
+ */
+class SecurityActions
+{
+ static SecurityContext createSecurityContext(final Principal p, final Object cred,
final Subject subject)
+ {
+ return AccessController.doPrivileged(new PrivilegedAction<SecurityContext>()
+ {
+ public SecurityContext run()
+ {
+ SecurityContext sc = null;
+ try
+ {
+ sc = SecurityContextFactory.createSecurityContext(p, cred, subject,
"SAML2_HANDLER");
+ }
+ catch (Exception e)
+ {
+ throw new RuntimeException(e);
+ }
+ return sc;
+ }
+ });
+ }
+
+ static void setSecurityContext(final SecurityContext sc)
+ {
+ AccessController.doPrivileged(new PrivilegedAction<Object>()
+ {
+ public Object run()
+ {
+ SecurityContextAssociation.setSecurityContext(sc);
+ return null;
+ }
+ });
+ }
+
+ static SecurityContext getSecurityContext()
+ {
+ return AccessController.doPrivileged(new PrivilegedAction<SecurityContext>()
+ {
+ public SecurityContext run()
+ {
+ return SecurityContextAssociation.getSecurityContext();
+ }
+ });
+ }
+ /**
+ * Get the {@link Subject} from the {@link SecurityContextAssociation}
+ * @return authenticated subject or null
+ */
+ static Subject getAuthenticatedSubject()
+ {
+ return AccessController.doPrivileged(new PrivilegedAction<Subject>()
+ {
+ public Subject run()
+ {
+ SecurityContext sc = SecurityContextAssociation.getSecurityContext();
+ if( sc != null )
+ return sc.getUtil().getSubject();
+ return null;
+ }
+ });
+ }
+
+ /**
+ * Get a system property
+ * @param key the property name
+ * @param defaultValue default value in absence of property
+ * @return
+ */
+ static String getSystemProperty( final String key, final String defaultValue)
+ {
+ return AccessController.doPrivileged(new PrivilegedAction<String>()
+ {
+ public String run()
+ {
+ return System.getProperty(key, defaultValue);
+ }
+ });
+ }
+
+ static ClassLoader getClassLoader( final Class<?> clazz)
+ {
+ return AccessController.doPrivileged(new PrivilegedAction<ClassLoader>()
+ {
+ public ClassLoader run()
+ {
+ return clazz.getClassLoader();
+ }
+ });
+ }
+
+ static ClassLoader getContextClassLoader()
+ {
+ return AccessController.doPrivileged(new PrivilegedAction<ClassLoader>()
+ {
+ public ClassLoader run()
+ {
+ return Thread.currentThread().getContextClassLoader();
+ }
+ });
+ }
+
+ /**
+ * Given a {@link List} of role names, construct a group principal of type {@link
Group}
+ * @param roles
+ * @return
+ */
+ static Group group(final List<String> roles)
+ {
+ return AccessController.doPrivileged(new PrivilegedAction<Group>()
+ {
+ public Group run()
+ {
+ Group theGroup = new PicketLinkGroup(SecurityConstants.ROLES_IDENTIFIER);
+ for(String role: roles)
+ {
+ theGroup.addMember(new SimplePrincipal(role));
+ }
+ return theGroup;
+ }
+ });
+ }
+}
\ No newline at end of file