Hi David, > Just for completeness, the solution described here *almost* works. You > can't only have a custom by-number action, such as setting "action" to the > magic number (e.g. 16384) that you also put into the custom action map, and > the reason is because of a "bug" in the aforementioned > WSSecurityUtil.decodeAction. Without having at least one "standard" > action, such as Timestamp, the doAction bitmask will be left as 0, ie. > NO_SECURITY and the entire action handling will be short-circuited.
I've fixed this in CXF. If you could try it with the latest SNAPSHOT code that'd be great. Colm. On Fri, Mar 16, 2012 at 8:27 PM, David Mansfield <[email protected]> wrote: > > > On 03/16/2012 11:26 AM, David Mansfield wrote: >> >> >> >> On 03/16/2012 05:24 AM, Colm O hEigeartaigh wrote: >>>> >>>> Should I use 0x01 (i.e. USERNAME_TOKEN) or am I supposed to register my >>>> own. >>>> Looking at the source code it doesn't really look possible to use a >>>> custom >>>> value here (take a look at WSSecurityUtil.decodeAction). If I have to >>>> replace something, it might as well be "UsernameToken"/0x01, I guess. >>> >>> You can use a custom value. WSSecurityUtil.decodeAction contains the >>> following code: >>> >>> int parsedAction = Integer.parseInt(single[i]); >>> if (wssConfig.getAction(parsedAction) == null) { >>> throw new WSSecurityException( >>> "Unknown action defined: " + single[i] >>> ); >>> } >>> actions.add(new Integer(parsedAction)); >> >> >> You're right, but there cannot be a separate "readable" name, so someone >> looking at the spring xml won't see "action" => "SessionToken" they'll see >> "action" => "32768" or similar which I need to comment extensively. The >> point of "registering" a custom action integer with a string name mapping >> would be so that in so doing the configuration would be self-documenting. >> >> But please don't take this as an ungrateful complaint! You have been >> extremely helpful, and the code extension points are hopefully right on >> target. Thanks again! >> >> > Just for completeness, the solution described here *almost* works. You > can't only have a custom by-number action, such as setting "action" to the > magic number (e.g. 16384) that you also put into the custom action map, and > the reason is because of a "bug" in the aforementioned > WSSecurityUtil.decodeAction. Without having at least one "standard" > action, such as Timestamp, the doAction bitmask will be left as 0, ie. > NO_SECURITY and the entire action handling will be short-circuited. > > It just so happens that my service provider cannot process "Timestamp" so I > now must try to work around this further (mustUnderstand is not > understood!). > > However, I can confirm that the proper elements are being added when I > include Timestamp as well. So in principle this is all working. > >>> Colm. >>> >>> On Thu, Mar 15, 2012 at 5:53 PM, David Mansfield<[email protected]> >>> wrote: >>>> >>>> On 03/15/2012 11:07 AM, Colm O hEigeartaigh wrote: >>>>> >>>>> Hi David, >>>>> >>>>>> I have also looked at the "custom actions" but I don't understand >>>>>> what >>>>>> the >>>>>> statement "integer representing the WSS4J action identifier" means, >>>>>> nor >>>>>> what >>>>>> indeed a WSS4J action is, or how to make one. >>>>> >>>>> You could take a look at the following unit test "testCustomAction": >>>>> >>>>> >>>>> >>>>> http://svn.apache.org/viewvc/cxf/trunk/rt/ws/security/src/test/java/org/apache/cxf/ws/security/wss4j/WSS4JOutInterceptorTest.java?view=markup >>>>> >>>>> You need to implement your own Action implementation to insert the >>>>> token in the security header: >>>>> >>>>> >>>>> >>>>> http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/main/java/org/apache/ws/security/action/Action.java?view=markup >>>>> >>>>> Then you need to tell WSS4J to use this Action implementation >>>>> corresponding to a given integer. From the test: >>>>> >>>>> CountingUsernameTokenAction action = new CountingUsernameTokenAction(); >>>>> Map<Object, Object> customActions = new HashMap<Object, Object>(1); >>>>> customActions.put(WSConstants.UT, action); >>>>> >>>>> ... >>>>> msg.put(WSHandlerConstants.ACTION, WSHandlerConstants.USERNAME_TOKEN); >>>>> msg.put(WSS4JOutInterceptor.WSS4J_ACTION_MAP, customActions); >>>> >>>> Ok. Getting there. Still a few questions: >>>> >>>> So these two lines set the "action" equal to "UsernameToken" (which >>>> translates elsewhere to 0x01), then supply a custom action map using a >>>> custom Action implementation for 0x01. >>>> >>>> Should I use 0x01 (i.e. USERNAME_TOKEN) or am I supposed to register my >>>> own. >>>> Looking at the source code it doesn't really look possible to use a >>>> custom >>>> value here (take a look at WSSecurityUtil.decodeAction). If I have to >>>> replace something, it might as well be "UsernameToken"/0x01, I guess. >>>> >>>> The other big problem is that all of these manipulations occur (in the >>>> test >>>> case you linked) on the "SoapMessage". It seems like the docs example >>>> works by configuring some "properties" map of the WSS4JOutInterceptor. >>>> So >>>> if I can translate what you said, I get: >>>> >>>> <bean id="sessionTokenAction" >>>> class="com.example.subclass.of.action.MySessionTokenAction" /> >>>> >>>> <bean id="sessionTokenInterceptor" >>>> class="org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor"> >>>> <constructor-arg> >>>> <map> >>>> <!-- Redefines the action for UsernameToken to use a custom impl. and >>>> turns on the action --> >>>> <entry key="action" value="UsernameToken" /> <!-- turn on the >>>> UsernameToken i.e. 0x01 --> >>>> <entry key="wss4j.action.map"> >>>> <map key-type="java.lang.Integer" value-type="java.lang.Object"> >>>> <entry key="0x01" value-ref="sessionTokenAction"/> >>>> </map> >>>> </entry> >>>> </map> >>>> </constructor-arg> >>>> </bean> >>>> >>>> <bean id="greeterServiceFactory" >>>> class="org.apache.cxf.jaxws.JaxWsProxyFactoryBean"> >>>> ... >>>> <property name="outInterceptors"> >>>> <list> >>>> <ref bean="securityTokenInterceptor" /> >>>> </list> >>>> </property> >>>> </bean> >>>> >>>> >>>> And than services retrieved from spring will have the custom mapping >>>> applied. >>>> >>>>> The integer you associate with the action needs to be added via >>>>> WSHandlerConstants.ACTION. The example above is a tad confusing, as it >>>>> overrides the UsernameTokenAction rather than specifying a new action. >>>>> >>>>> Colm. >>>>> >>>>> On Thu, Mar 15, 2012 at 2:43 PM, David Mansfield<[email protected]> >>>>> wrote: >>>>>> >>>>>> Hi. This is my first post! >>>>>> >>>>>> I am working with a web service that has employed a "custom" security >>>>>> solution roughly based on STS. After I receive a "token" from their >>>>>> STS >>>>>> (using their custom library) I have to embed the opaque token in a >>>>>> custom >>>>>> header inside the wsse:Security soap header. Roughly like: >>>>>> >>>>>> <wsse:Security> >>>>>> <SecurityToken> >>>>>> <TokenValue>4321fade4321fade</TokenValue> >>>>>> </SecurityToken> >>>>>> </wsse:Security> >>>>>> >>>>>> (along with timestamping). >>>>>> >>>>>> The SecurityToken element is associated with their namespace. >>>>>> >>>>>> The session token will be common for _all_ requests using the service, >>>>>> but >>>>>> it will change over time as a session has a TTL (i.e. once a day the >>>>>> session >>>>>> token will need to be updated). >>>>>> >>>>>> I have looked at the WSS4JOutInterceptor but it seems to only be able >>>>>> to >>>>>> handle "standard" things like UsernameToken. >>>>>> >>>>>> I have also looked at the "custom actions" but I don't understand >>>>>> what >>>>>> the >>>>>> statement "integer representing the WSS4J action identifier" means, >>>>>> nor >>>>>> what >>>>>> indeed a WSS4J action is, or how to make one. >>>>>> >>>>>> Can someone point me in the right direction? >>>>>> >>>>>> Thanks, >>>>>> David Mansfield >>>>>> Cobite, INC. >>>>>> >>>>>> >>>>> >>> >>> > -- Colm O hEigeartaigh Talend Community Coder http://coders.talend.com
