[SWS-711] Upgrade to wss4j 1.6 Created: 23/Jun/11  Updated: 30/May/14  Resolved: 09/May/12

Status: Resolved
Project: Spring Web Services
Component/s: None
Affects Version/s: 2.0.2
Fix Version/s: 2.1 RC1

Type: Improvement Priority: Minor
Reporter: Mark Diskin Assignee: Arjen Poutsma
Resolution: Complete Votes: 4
Labels: None
Remaining Estimate: Not Specified
Time Spent: 3d 2.1h
Original Estimate: Not Specified

Attachments: Text File spring-ws.patch    
Reference URL: http://forum.springsource.org/showthread.php?107632-When-will-WSS4J-1.6.0-be-supported

 Description   

From support issue - Reference #11620

wss4j 1.6.1 has made much improves to the WS-Security implememtation and key to us (sure others) is the work to ensure cross-implementation compliance with BSP 1.1 http://coheigea.blogspot.com/2011/03/wss4j-16-basic-security-profile-11.html.

This upgrade opens up the possibility for Spring-WS to support SAML authentication (I'll open a separate issue for that).



 Comments   
Comment by Arjen Poutsma [ 17/Oct/11 ]

Unfortunately, WSS4J 1.6 introduced some breaking, non-backwards compatible changes, making it non-trivial to upgrade.

Postponed to 2.1.

Comment by Patrick [ 20/Jan/12 ]

Yes, please upgrade. We depend on 3rd party software which now ships with WSS4J 1.6. That's a huge issue, because we're using (and want to keep using) Spring WS...

Comment by Edwin Stang [ 21/Jan/12 ]

Spring-WS 2.0.3.RELEASE with WSS4J 1.6.4 leads to the following exception for me:

java.lang.IllegalStateException: Failed to load ApplicationContext
	at org.springframework.test.context.TestContext.getApplicationContext(TestContext.java:157)
	at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:109)
	at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:75)
	at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:321)
	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:211)
	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:288)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:290)
	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:231)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)
	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
	at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
	at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:30)
	at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174)
	at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
	at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'wssInterceptor' defined in class path resource [META-INF/ctx.integration.ws.xml]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [org.springframework.ws.soap.security.wss4j.Wss4jSecurityInterceptor]: Constructor threw exception; nested exception is java.lang.NoSuchMethodError: org.apache.ws.security.WSSecurityEngine.getInstance()Lorg/apache/ws/security/WSSecurityEngine;
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:997)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:943)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:485)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
	at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:294)
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:225)
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:291)
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:585)
	at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:913)
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:464)
	at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:148)
	at de.invesdwin.gemeinsam.test.TestContextLoader.loadContext(TestContextLoader.java:78)
	at org.springframework.test.context.TestContext.loadApplicationContext(TestContext.java:130)
	at org.springframework.test.context.TestContext.getApplicationContext(TestContext.java:148)
	... 25 more
Caused by: org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [org.springframework.ws.soap.security.wss4j.Wss4jSecurityInterceptor]: Constructor threw exception; nested exception is java.lang.NoSuchMethodError: org.apache.ws.security.WSSecurityEngine.getInstance()Lorg/apache/ws/security/WSSecurityEngine;
	at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:162)
	at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:76)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:990)
	... 39 more
Caused by: java.lang.NoSuchMethodError: org.apache.ws.security.WSSecurityEngine.getInstance()Lorg/apache/ws/security/WSSecurityEngine;
	at org.springframework.ws.soap.security.wss4j.Wss4jSecurityInterceptor.<init>(Wss4jSecurityInterceptor.java:121)
	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
	at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
	at java.lang.reflect.Constructor.newInstance(Constructor.java:532)
	at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:147)
	... 41 more

Comment by Ivan Khoosty [ 12/Apr/12 ]

FYI,

Jboss 7.1.0.Final ships with wss4j 1.5.8 and xmlsec 1.4.5

Jboss 7.1.1.Final ships with wss4j 1.6.5 and xmlsec 1.5.1 (https://issues.jboss.org/browse/JBWS-3439)

this means that any webapp using spring-ws cannot run on Jboss 7.1.1.Final, as xmlsec 1.5.1 gets loaded as part of java ee module dependency, so spring-ws bundled xmlsec 1.4.3 gets ignored... there is an api change from 1.4 to 1.5, which breaks the deployment.

Comment by Mark Diskin [ 02/May/12 ]

Hi Arjen,

I have created another approach for the wssj authenication integration using spring/spring security servlet filters. This allows for the requests to be stateless (I create the UserDetails after the SAML2 validation from the attributes provided) and able to then use the Roles (GrantedAuthority) in the spring security filter rules, etc... which was not something I could do with the springws interceptor approach. Did you want me to budndle this up under this or another case if you want to consider it?

Comment by Arjen Poutsma [ 02/May/12 ]

@Mark

Sure, feel free to attach it to another issue. Even if I won't make it part of the main distribution, it might be helpful to other people.

Thanks!

Comment by jaminh [ 02/May/12 ]

I have started working on getting Spring WS to build with WSS4J 1.6.5. I have gotten to a point where everything will at least build but I haven't tried testing beyond getting timestamp validation to work. It seems like in WSS4J 1.6 they are trying to split up the securement and validation so I tried to adjust some of the callback handlers accordingly. Also something to keep in mind is the Crypto interface was changed significantly in WSS4J 1.6 so any custom Crypto implementations are probably going to break when upgrading, but I believe it still comes with the basic Merlin implementation. I will attach a patch in case other people want to try to build on that. In the meantime I will keep working on it as much as I can.

Comment by Arjen Poutsma [ 03/May/12 ]

@jaminh: Thanks for the patch, it will certainly help.

Things are a bit tricky, however, because I don't want to force people to upgrade their wss4j version in a bug-fix release of Spring-WS (2.0.5). Forcing an upgrade would be fine for a 2.1 version of SWS, but 2.1 is still far off.

So we'll have to resort to some reflection trickery in order to make our wss4j support work for both 1.5.x and 1.6.x. We have this kind of tricks in other places as well, for instance the Quartz support in SPR. It's not easy, but hopefully it will work.

Comment by Mark Diskin [ 03/May/12 ]

Any thoughts on doing parallel releases (2.0.5,2.1) with the wss4j in the 2.1 (or 2.1rc) and moving some of the other work into a 2.2?

Comment by Arjen Poutsma [ 03/May/12 ]

@mark: yeah, that's an option as well, but I am only willing to take that route as a last resort, after trying the reflection-based approach. It's quite uncommon for a Spring project to release a minor version with only library upgrades, and without any new features in it.

Comment by Arjen Poutsma [ 04/May/12 ]

After some investigation, I've decided that the reflection-based approach is just too much hassle. Instead, I am going to follow Mark's suggestion, and release 2.0.5 without it (hopefully today). Shortly after that (next week, perhaps), I will push out 2.1 RC1, which will contain a fix for this issue and a couple of other library upgrades. Since 2.1 will contain library upgrades, I expect a short release cycle, and hopefully we'll see a 2.1 GA shortly after the RC. All other 2.1 M1 issues have been moved to 2.2 M1.

Comment by Mark Diskin [ 04/May/12 ]

In the meantime I've dropped the spring-ws-security dependancy, that way I'm able to bring in the latest wss4j 1.6 and handle the SAML2 SenderVoucher in my Security filter and still use the springws 2.0.x jars.

Comment by Arjen Poutsma [ 09/May/12 ]

I've upgraded SVN to use WSS4J 1.6, with the help of the patch provided jaminh (Thanks!). It compiles, and all tests run fine. That said, because the way WSS4J has changed internally, there are some breaking changes:

  • SpringDigestPasswordValidationCallbackHandler and SpringPlainTestPasswordValidationCallbackHandler have been merged into SpringSecurityPasswordValidationCallbackHandler, which works the same way as the SpringDigestPasswordValidationCallbackHandler (i.e. supply it with a UserDetailsService).
  • The Wss4jSecurityInterceptor no longer has the securementCallbackHandler property, as it's no longer used by WS4J.

Furthermore, the Wss4jSecurityInterceptor has some additional properties: enableRevocation and bspCompliant. Check the javadocs to see what these do.

I've just triggered a snapshot build, and it would be great if you guys could check it out if everything still works for you. This page shows you how to get snapshots.

If everything looks good, I will release 2.1.0-RC1 this Friday (11th May) followed by the GA release the following week.

Comment by Arjen Poutsma [ 15/May/12 ]

I've just pushed out version 2.1.0.RC1. Please give it a go and tell me if you find anything.

Comment by Pavel Kotlov [ 18/Jun/12 ]

Combination of spring-ws-2.1.0 and wss4j-1.6.6 still results in this error:

Could not instantiate bean class [org.springframework.ws.soap.security.wss4j.Wss4jSecurityInterceptor]: Constructor threw exception; 
nested exception is java.lang.NoSuchMethodError: org.apache.ws.security.WSSecurityEngine.getInstance()Lorg/apache/ws/security/WSSecurityEngine;

Using wss4j-1.5.12 solves the problem for me. Well perhaps not for everyone...

Comment by Vanshaj [ 30/May/14 ]

I am using Spring-ws 2.1.4 along with wss4j 1.6.4 and getting the same problem while using wss4j 1.5.x, its working fine.

Looks like the issue still exists with wss4j 1.6.x.

Generated at Mon Dec 18 16:31:24 UTC 2017 using JIRA 6.4.14#64029-sha1:ae256fe0fbb912241490ff1cecfb323ea0905ca5.