Implementing an oauth2
system, I am having some problems with the following code:
import org.springframework.security.oauth2.provider.endpoint.FrameworkEndpointHandlerMapping;
import org.springframework.web.servlet.HandlerMapping;
...
HandlerMapping.class.isAssignableFrom(FrameworkEndpointHandlerMapping.class);
Indeed, as the class FrameworkEndpointHandlerMapping
is implementing the interface HandlerMapping
, this function should always return true
. It is the case when I run a unit test on this function. However, during the startup of the server, this function returns false
(checked using the debugger). This is a huge problem because when the DispatcherServlet
is instantiated, it searches for the class implementing HandlerMapping
and my FrameworkEndpointHandlerMapping
is discarded leading to bugs in the application.
I have searched for other questions like this one but most of them answer that the isAssignableFrom
method is not used correctly (mix of the class and the parameter of the function). This is not the case here since the JUnit is working.
Suspecting the imported jar
files to be the problem, I have limited them to the following ones:
- spring-beans-4.1.4.RELEASE.jar
- spring-security-oauth2-2.0.6.RELEASE.jar
- spring-webmvc-4.1.4.RELEASE.jar (also tried with the 4.0.9)
- spring-core-4.1.4.RELEASE.jar
- ...
Do you have any idea of a solution to explore please?
For more information, here are the sources:
My own DispatcherServlet
(the constructor with the String
as a parameter is called by the JUnit test and the default constructor is called during the startup of the system)
import org.junit.Assert;
import org.springframework.security.oauth2.provider.endpoint.FrameworkEndpointHandlerMapping;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;
import org.springframework.web.servlet.HandlerMapping;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
public class MobileDispatcherServlet extends DispatcherServlet
{
private static final long serialVersionUID = 1L;
public MobileDispatcherServlet()
{
super();
HandlerMapping.class.isAssignableFrom(FrameworkEndpointHandlerMapping.class);
}
public MobileDispatcherServlet(final WebApplicationContext webApplicationContext)
{
super(webApplicationContext);
final FrameworkEndpointHandlerMapping handlerMapping = webApplicationContext.getBean(FrameworkEndpointHandlerMapping.class);
HandlerMapping.class.isAssignableFrom(handlerMapping.getClass());
}
public MobileDispatcherServlet(final String test)
{
Assert.assertTrue(HandlerMapping.class.isAssignableFrom(FrameworkEndpointHandlerMapping.class));
}
}
The oauth
configuration file:
<?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:context="http://www.springframework.org/schema/context"
xmlns:security="http://www.springframework.org/schema/security"
xmlns:oauth="http://www.springframework.org/schema/security/oauth2"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd
http://www.springframework.org/schema/security/oauth2 http://www.springframework.org/schema/security/spring-security-oauth2.xsd">
<!-- Root of the configuration -->
<!-- The FrameworkEndpointHandlerMapping is created here -->
<oauth:authorization-server client-details-service-ref="clientDetails"
token-services-ref="tokenServices"
user-approval-handler-ref="userApprovalHandler"
authorization-endpoint-url="/oauth/authorize.action"
token-endpoint-url="/oauth/token.action" >
<oauth:authorization-code authorization-code-services-ref="authorizationCodeServices" disabled="false" />
<oauth:refresh-token />
</oauth:authorization-server>
...
</beans>
The web.xml
:
<web-app id="sitestorefront" version="3.0" 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.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app.xsd"
metadata-complete="true">
...
<context-param>
<description>
The 'contextConfigLocation' param specifies where your configuration files are located.
The 'WEB-INF/config/web-application-config.xml' file includes several other XML config
files to build up the configuration for the application.
</description>
<param-name>contextConfigLocation</param-name>
<param-value>WEB-INF/config/web-application-config.xml</param-value>
</context-param>
<context-param>
<param-name>tagpoolMaxSize</param-name>
<param-value>50</param-value>
</context-param>
<servlet>
<description>
DispatcherServlet
</description>
<servlet-name>DispatcherServlet</servlet-name>
<servlet-class>be.sbh.site.storefront.oauth2.MobileDispatcherServlet</servlet-class>
<init-param>
<description>
Specifies the location for Spring MVC to load an additional XML configuration file.
Because hybris is already configured with the XML spring configuration files to load
we must set this param value to EMPTY in order to prevent loading of the default
/WEB-INF/applicationContext.xml file.
</description>
<param-name>contextConfigLocation</param-name>
<param-value></param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>DispatcherServlet</servlet-name>
<!-- Map all requests to the DispatcherServlet -->
<url-pattern>/</url-pattern>
</servlet-mapping>
...
</web-app>
The web-application-config.xml
imports all the configuration files (among them, the oauth
configuration file). One of them has a <mvc:annotation-driven />
to enable the mvc annotations.
I tried to limit my sources to the ones that seems relevant to me. If you need more, do not hesitate to ask me.
Thank you for reading this question,
Laurent