Making a @WebService class spring aware

Hello,
I am trying to create a Webservice class in the app-portal. It is currently using the @WebService annotation. This along with some entries in the web.xml and a configuration similar to this ( https://www.mkyong.com/webservices/jax-ws/deploy-jax-ws-web-services-on-tomcat/ ) I am able to call the web service just fine, but I cant seem to go anywhere past this.

If I try and use the @Inject annotation to call any of the services that have been created in the Cuba environment, they are always null at runtime so it throws a Null Pointer Exception. I’m assuming this is because my webservice class is not in the spring container.

If I try and use the AppBeans.get() method like
private MyService myService = AppBeans.get(MyService .class);

This seems to work, however when I try and access this service I get a run time error of

13:46:14.231 ERROR c.h.cuba.core.sys.ServiceInterceptor - Exception:
java.lang.SecurityException: No security context bound to the current thread
        at com.haulmont.cuba.core.sys.AppContext.getSecurityContextNN(AppContext.java:201) ~[cuba-global-6.2.2.jar:6.2.2]
        at com.haulmont.cuba.core.sys.ServiceInterceptor.getUserSession(ServiceInterceptor.java:88) ~[cuba-core-6.2.2.jar:6.2.2]
        at com.haulmont.cuba.core.sys.ServiceInterceptor.aroundInvoke(ServiceInterceptor.java:70) ~[cuba-core-6.2.2.jar:6.2.2]
	............
        at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1476) [tomcat-coyote.jar:8.0.35]
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_92]
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_92]
        at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-util.jar:8.0.35]
        at java.lang.Thread.run(Thread.java:745) [na:1.8.0_92]
1:46:14 PM com.sun.xml.ws.server.sei.EndpointMethodHandler invoke
SEVERE: No security context bound to the current thread
com.haulmont.cuba.core.global.RemoteException:

I was wondering what is the best way to get this @WebService class to be loaded in the spring container, or make it spring container Aware or anything along those lines so it can access the Cube Platform Services? Or possibly somehow use the System Authentication (https://doc.cuba-platform.com/manual-6.2/system_authentication.html) to be able to access these services?

1 Like

Hi Alex,
You are right, your web service is not in the Spring container, so injection won’t work and you have to obtain other services through AppBeans. Besides, all invocation of middleware services from the client tier should be in a thread containing a SecurityContext. It is created automatically when you use standard UI or REST API, but for your new end-point you should provide it on your own.
System authentication as described in the docs works only on the middleware tier (core module), but your web service is probably created on the client tier (web module). The simplest way is to use the LoginService.getSystemSession() method added to the platform v.6.2. For example:


// your web service method
Configuration configuration = AppBeans.get(Configuration.class);
WebAuthConfig webAuthConfig = configuration.getConfig(WebAuthConfig.class);
LoginService loginService = AppBeans.get(LoginService.class);
UserSession userSession = loginService.getSystemSession(webAuthConfig.getTrustedClientPassword());
try {
    AppContext.setSecurityContext(new SecurityContext(userSession));
    // call middleware services here
} finally {
    AppContext.setSecurityContext(null);
}

Let me know if it doesn’t work for you.
We will also think about providing better integration with SOAP web services in the future - thanks for the hint.

1 Like

It mostly worked. Since the code was in app-portal (instead of app-web ), It could not resolve WebAuthConfig, I just had to pull the Password from the portal-app.properties.

After that it worked great. Thanks again for your help.