WS-Security is not working with CXF - endpoint address - security

I am trying to add UsernameToken based security in web services written using apache cxf version 2.2.12.
Once I deploy my application in weblogic, I am getting two URL's from which I can access my WSDL.
http://localhst:8080/myapp/services/MyService?wsdl
http://localhost:8080/myapp/MyService?wsdl
I am trying to consume webservice using soapUI client and problem is If I use 2nd URL, everything works fine, my ejb is getting injected properly etc but WSS4JInterceptor is not getting called at all.
If I change the URL in soapUI to use 1st one, then Interceptor is getting called but then my services is not getting injected and I am getting NULL as service object.
I have configured WSS4JInterceptor in my spring configuration file. I need to call this Interceptor before each request so that I can verify user token from request header.
Here is my beans.xml
<bean id="wss4jInConfiguration" class="org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor">
<property name="properties">
<map>
<entry key="action" value="UsernameToken Timestamp"/>
<entry key="passwordType" value="PasswordText" />
<entry>
<key>
<value>passwordCallbackRef</value>
</key>
<ref bean="passwordCallback"/>
</entry>
</map>
</property>
</bean>
<bean id="passwordCallback" class="my.interceptors.callbacks.handlers.PasswordCallbackHandler"/>
<jaxws:endpoint id="myservice" implementor="my.sample.application.MyServiceImpl"
address="/MyService">
<jaxws:ininterceptors>
<ref bean="wss4jInConfiguration" />
</jaxws:ininterceptors>
</jaxws:endpoint>
Here is my web.xml
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:WEB-INF/beans.xml
</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<servlet>
<servlet-name>CXFServlet</servlet-name>
<display-name>CXF Servlet</display-name>
<servlet-class>org.apache.cxf.transport.servlet.CXFServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>CXFServlet</servlet-name>
<url-pattern>/services/*</url-pattern>
</servlet-mapping>
</web-app>
I don't have currently access to my WSDL but here is the tag looks like.
<soap:address location="http://localhost:8080/MyServiceSoapPort" />
Any pointer what i am doing wrong.
NOTE: My services are working fine without call back on URL without /services/

My guess is that the Web service is actually deployed twice, once by CXF as configured in your beans.xml file and once by Weblogic as a Java EE 5 Web service. CXF doesn't perform injection (I assume that you are using #EJB), and Weblogic doesn't know anything about your WS-Security configuration.

Related

BeanLocator has not been set for servlet context My_portlet when using Service builder (Liferay)

Working on a MVC spring Liferay 6.2 portlet.
I have built a service xml file and built the project. It manages an entity (let's say MyEntity ).
When I call my addMyEntity(long id) method from my controller, an exception is thrown saying:
15:53:04,135 ERROR [http-bio-8080-exec-60][PortletBeanLocatorUtil:42] BeanLocator is null for servlet context My_portlet
com.liferay.portal.kernel.bean.BeanLocatorException: BeanLocator has not been set for servlet context My_portlet
It looks the portal cannot access to some beans resources.
My web.xml file includes the following:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring-context/portlet-application-context.xml</param-value>
</context-param>
<servlet>
<servlet-name>ViewRendererServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.ViewRendererServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>ViewRendererServlet</servlet-name>
<url-pattern>/WEB-INF/servlet/view</url-pattern>
</servlet-mapping>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
portlet-application-context.xml only includes these beans:
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="contentType" value="text/html;charset=UTF-8" />
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
</bean>
I think what the server is looking for are these beans that are stored in a portlet-spring.xml file:
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" default-destroy-method="destroy" default-init-method="afterPropertiesSet" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id="com.company.project.servicebuilder.dao.service.MyEntityLocalService" class="com.company.project.servicebuilder.dao.service.impl.MyEntityLocalServiceImpl" />
<bean id="com.company.project.servicebuilder.dao.service.MyEntityService" class="com.company.project.servicebuilder.dao.service.impl.MyEntityServiceImpl" />
<bean id="com.company.project.servicebuilder.dao.service.persistence.MyEntityPersistence" class="com.company.project.servicebuilder.dao.service.persistence.MyEntityPersistenceImpl" parent="basePersistence" />
</beans>
However, I see no reference to portlet-spring.xml in other files so I m afraid that these beans are never declared when the portlet is deployed.
Should it be referenced somewhere?
Any other suggestion than my hypothesis?
thx in advance.
Thanks to user "So Te" and to some wide research I solve this problem specifying pluginName in pom.xml in configuration tag and running service-builder again.
<configuration>
<autoDeployDir>${liferay.auto.deploy.dir}</autoDeployDir>
<appServerDeployDir>${liferay.app.server.deploy.dir}</appServerDeployDir>
<appServerLibGlobalDir>${liferay.app.server.lib.global.dir}</appServerLibGlobalDir>
<appServerPortalDir>${liferay.app.server.portal.dir}</appServerPortalDir>
<liferayVersion>${liferay.version}</liferayVersion>
<pluginType>portlet</pluginType>
<pluginName>${project.artifactId}-${project.version}</pluginName>
</configuration>
The message in the log file could be a bit misleading.
One possible condition when this message would occur: if using ServiceBuilder and the Liferay portlet plugin project name does not match the configured context root. If you trace the ServiceBuilder template logic for generating the ClpSerializer.java class and the runtime execution stack, you could make the connection. This is my experience in LR6.2 CE.
Try matching your context root (in Eclipse - right-click project name/Properties/Web Project Settings) and make it the same as your Liferay portlet project name - e.g. "test-portlet". Re-build your service and deploy it.
Post your degree of success.
This was my solution to the above issue, as I was importing existing projects and not paying attention to the project settings. After matching the two values I was able to deploy successfully and execute the portlet logic.
Cheers!
Try to remove the portlet and deploy it again, normal this problems are errors on the deploy.
I had this error when building my JUnit tests cases. I was having this error because Mockito standalone doesn't support static calls. To solution it, I had to use Mockito with PowerMock in order to allow static calls.

Spring Secutiry logout not destroying JSESSIONID defined in web-fragment

I am using Spring security to secure my rest API. Following are my configurations;
spring-secutiry.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:security="http://www.springframework.org/schema/security"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.1.xsd">
<security:http auto-config="true">
<!-- Authentication Type and Intercepter Configurations -->
<security:http-basic />
<security:intercept-url pattern="/**" />
<security:anonymous enabled="false" />
<security:session-management invalid-session-url="/">
<security:concurrency-control max-sessions="1" />
</security:session-management>
<security:logout logout-url="/signOff" invalidate-session="true"
delete-cookies="JSESSIONID" logout-success-url="/" />
</security:http>
<bean id="myAuthenticationProvider"
class="com.myauthenticator.spring.secutiry.MyAuthenticationProvider" />
<security:authentication-manager>
<security:authentication-provider ref="myAuthenticationProvider" />
</security:authentication-manager>
</beans>
There is no such implementation for custom logout. I am expecting Spring to intercept call to /signOff and destroys token and redirect me to / because of the configuration in logout-success-url which should challenge for a BASIC auth once more but its loading my home page.
It seems like my spring configurations are not correct i.e. not all calls are intercepted by Spring filter. I have following configurations in my web.xml to priorities my web-fragment which contains my Spring Security Filter;
web.xml
<absolute-ordering>
<name>MyAuthenticator</name>
<others/>
</absolute-ordering>
Note: My filter and custom authentication are implemented as a web-fragment which looks like as follows;
web-fragement.xml
<web-fragment
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
xmlns:webfragment="http://java.sun.com/xml/ns/javaee/web-fragment_3_0.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-fragment_3_0.xsd"
id="T24Authenticator" version="3.0">
<display-name>T24 Authentication Provider</display-name>
<name>MyAuthenticator</name>
<!-- Spring Security -->
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
.....
I think there is something wrong with my configurations! But I can't spot it, can anyone?

Error 500: javax.servlet.ServletException: Filter [SBTFilter]

I am following the lab manual: Getting started with IBM Connections Cloud. Last updated November 19 2014 by Jan Smolenski.
After I have setup the project and run the server (step 109) and open the mysocial.webapp url I get the message:
Error 500: javax.servlet.ServletException: Filter [SBTFilter]: Could not find required filter class - com.ibm.sbt.util.SBTFilter.class
In the console I read:
[ERROR ] SRVE0321E: The [SBTFilter] filter did not load during start up.
How can I include the sbtfilter during startup? Should I import additional libraries from the SDK or alter my configuration?
I run the samples exactly as declared in the lab manual...
There is a sample project called social.helloworld.webapp. You can look at the following web.xml
https://github.com/OpenNTF/SocialSDK/blob/master/samples/j2ee/templates/social.helloworld.webapp/src/main/webapp/WEB-INF/web.xml
Copy the Following Lines
<servlet>
<description>The service servlet handles requests from the toolkit to access external resources.</description>
<display-name>Social Business Toolkit Service Servlet</display-name>
<servlet-name>ServiceServlet</servlet-name>
<servlet-class>com.ibm.sbt.service.core.servlet.ServiceServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ServiceServlet</servlet-name>
<url-pattern>/service/*</url-pattern>
</servlet-mapping>
<servlet>
<description>This servlet initializes the specified JavaScript library for use by the Social Business Toolkit.</description>
<display-name>Social Business Toolkit Library Servlet</display-name>
<servlet-name>LibraryServlet</servlet-name>
<servlet-class>com.ibm.sbt.jslibrary.servlet.LibraryServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>LibraryServlet</servlet-name>
<url-pattern>/library/*</url-pattern>
</servlet-mapping>
<filter>
<description>This filter is responsible for creating the toolkit application and context objects for every servlet within this web application.</description>
<display-name>Social Business Toolkit Filter</display-name>
<filter-name>SBTFilter</filter-name>
<filter-class>com.ibm.sbt.util.SBTFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>SBTFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<resource-ref>
<description>Reference to a URL resource which points to the managed bean configuration for the Social Business Toolkit.</description>
<res-ref-name>url/ibmsbt-managedbeansxml</res-ref-name>
<res-type>java.net.URL</res-type>
<res-auth>Container</res-auth>
<res-sharing-scope>Shareable</res-sharing-scope>
</resource-ref>
<resource-ref>
<description>Reference to a URL resource which points to the configuration properties for the Social Business Toolkit.</description>
<res-ref-name>url/ibmsbt-sbtproperties</res-ref-name>
<res-type>java.net.URL</res-type>
<res-auth>Container</res-auth>
<res-sharing-scope>Shareable</res-sharing-scope>
</resource-ref>
and then restart your webapp
you can also make sure that the jar files exist.
Another good reference is... https://github.com/OpenNTF/SocialSDK/wiki/Building-your-first-social-enabled-jsp

Expose and access static XSD schema in Spring WS 2

I can't reach XSD schema. Here is my configuration:
web.xml
<servlet>
<servlet-name>spring-ws</servlet-name>
<servlet-class>org.springframework.ws.transport.http.MessageDispatcherServlet</servlet-class>
<init-param>
<param-name>transformWsdlLocations</param-name>
<param-value>true</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>spring-ws</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
spring-ws-servlet.xml
<sws:annotation-driven/>
<context:component-scan base-package="example.ws.endpoint"/>
<sws:dynamic-wsdl id="boo"
portTypeName="BooResource"
locationUri="/services/">
<sws:xsd location="classpath:example/ws/schema/Boo.xsd"/>
</sws:dynamic-wsdl>
WSDL is accessible on [http://localhost:port/spring-ws-server-0.1-SNAPSHOT/services/boo.wsdl], but how can I expose XSD and what will be the URL?
I've been able to expose my XSD's without using Spring-MVC for it by defining something like this in my #Configuration class:
private ClassPathResource messagesXsdResource = new ClassPathResource("messages.xsd");
#Bean
public SimpleXsdSchema messages() {
return new SimpleXsdSchema(messagesXsdResource);
}
You should take a look at this question as well, that explains how to do this in XML.
I'm afraid this is not possible, at least not automatically like your WSDLs are exposed. Spring WS doesn't intend to make your XSDs available like it does with the static and generated WSDLs. Of course, you can make your XSDs available through a simple servlet or through MVC (if you're using MVC as well).
If you're using Spring Boot, whatever you put under the public folder which you can create under resources, will be publicly available.
You can put your xsd there and point your wsdl to that definition:
<xsd:schema>
<xsd:import namespace="http://jaxws.com.your.ns" schemaLocation="/your.xsd"/>
</xsd:schema>
Now this will make your xsd available at http://localhost:8080/your.xsd

How to develop https site with Spring 3.x?

I am a newbie in Spring based web development.
Our site is Spring based and is currently http based (so quite insecure).
Since, the site is not live yet, we are sending login/password also through a normal JSON request to server and have focussed mostly on JSP, UI design, SQL queries etc.
Now, we want to shift to focus on security and shift to https as a first step.
I have read a no. of web-pages and some spring books but none seems to provide a clear answer on how Spring can be used to provide https security.
Can some one please help me in achieving the above?
Please let me know if my question is not clear. I will try to add more details ASAP.
Our web.xml is as follows:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="
http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
"
id="WebApp_ID" version="2.5">
<display-name>Spring3MVC</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>spring</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>*.html</url-pattern>
</servlet-mapping>
<!--> Mapping for serving static web-content <-->
<!--> The resources folder must be in parallel to WEB-INF <-->
<!--> The mvc:resources gives "not bound" exception unless bound to a namespace as above for xmlns:mvc <-->
<mvc:resources mapping="/resources/**" location="/resources/" />
<mvc:resources mapping="/scripts/**" location="/scripts/" />
</web-app>
There is only one controller right now for which, spring-servlet.xml is as follows:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:component-scan
base-package="console.controllerpkg" />
<bean id="viewResolver"
class="org.springframework.web.servlet.view.UrlBasedViewResolver">
<property name="viewClass"
value="org.springframework.web.servlet.view.JstlView" />
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
</bean>
</beans>
Thanks a lot in advance!
P.S. If you can recommend me a good example based site/book on spring, it would be much appreciated. Most of the sites/books I have seen lay much emphasis on theory but very little examples. That has left me a little confused.
As Dave says, you need to configure your container to serve SSL, and then deploy your spring app into that container. Learn about configuring Tomcat for SSL.
Alternately, and more flexibly you can front your container using Apache, and enable SSL there.
Spring is not 100% responsible for configuring SSL. For that you need to configure the container (jetty, tomcat, etc) to handle SSL.
Thanks for all the help guys.
I will re-iterate what I did just for my own record purposes.
First of all, the link provided by nont about 'Tomcat for SSL' was really helpful.
I read all about SSL and Tomcat there and this is what I did:
On the command prompt, enter:
keytool -genkey -alias tomcat -keyalg RSA
The above command asked me some simple questions needed for a Certificate. I used the password 'changeit' wherever asked (as that is the default password).
On finishing with the above command, it generated a keystore file in C:/Documents and Settings//.keystore
I copied this .keystore file to tomcat/conf/myKeyStore.jks
Then I added the following to conf/server.xml :
<Connector protocol="org.apache.coyote.http11.Http11Protocol"
port="8443" minSpareThreads="5"
maxSpareThreads="75"
enableLookups="true"
disableUploadTimeout="true"
acceptCount="100"
maxThreads="200" debug="5"
scheme="https" secure="true" SSLEnabled="true"
keystoreFile="${catalina.home}/conf/myKeyStore.jks"
keystoreType="JKS" keystorePass="changeit"
truststoreFile="${catalina.home}/conf/cacerts"
truststoreType="JKS" truststorePass="changeit"
SSLVerifyClient="require" SSLEngine="on" SSLVerifyDepth="2"
sslProtocol="TLS" />
And that's it!!
Next time, I ran tomcat my old http link did not work.
Then I tried adding sweet 's' to http with a port number of 8443 and lo! everything was up and running again.
Thanks nont for the wonderful link!!
Configure two different web sites, one for http and one for https, the one for http will have just a redirect to the https site.

Resources