2017-09-14 1 views
0

Est-ce que quelqu'un a réussi à intégrer RestEASY avec Spring Security et Spring Session? Je rencontre des problèmes avec ContextLoadListener. J'ai été capable d'intégrer RestEASY et Spring Security avec le web.xml suivant.RestEASY, Spring Security, Intégration de session de printemps

<web-app> 
<display-name>Admin Service</display-name> 
<context-param> 
    <param-name>resteasy.servlet.mapping.prefix</param-name> 
    <param-value>/admin</param-value> 
</context-param> 
<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> 
<listener> 
    <listener-class>org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap</listener-class> 
</listener> 
<listener> 
    <listener-class>org.jboss.resteasy.plugins.spring.SpringContextLoaderListener</listener-class> 
</listener> 
<servlet> 
    <servlet-name>AdminService</servlet-name> 
    <servlet-class>org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher</servlet-class> 
    <init-param> 
     <param-name>javax.ws.rs.Application</param-name> 
     <param-value>com.etouchpoint.admin.service.AdminApplication</param-value> 
    </init-param> 
</servlet> 
<servlet-mapping> 
    <servlet-name>AdminService</servlet-name> 
    <url-pattern>/admin/*</url-pattern> 
</servlet-mapping> 

Après avoir lu la documentation pour la session de printemps, le web.xml finirait regarder quelque chose comme ceci:

<web-app> 
<display-name>Admin Service</display-name> 

<!-- Context for Spring HttpSession --> 
<context-param> 
    <param-name>contextConfigLocation</param-name> 
    <param-value>/WEB-INF/spring/session.xml</param-value> 
</context-param> 

<!-- Context for RestEasy --> 
<context-param> 
    <param-name>resteasy.servlet.mapping.prefix</param-name> 
    <param-value>/admin</param-value> 
</context-param> 

<!-- Filter and Mapping for Spring Session --> 
<filter> 
    <filter-name>springSessionRepositoryFilter</filter-name> 
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> 
</filter> 
<filter-mapping> 
    <filter-name>springSessionRepositoryFilter</filter-name> 
    <url-pattern>/*</url-pattern> 
</filter-mapping> 

<!-- Filter and Mapping for 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> 

<!-- Listener for Spring Session --> 
<listener> 
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 
</listener> 

<!-- Listeners for RestEasy --> 
<listener> 
    <listener-class>org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap</listener-class> 
</listener> 
<listener> 
    <listener-class>org.jboss.resteasy.plugins.spring.SpringContextLoaderListener</listener-class> 
</listener> 

<servlet> 
    <servlet-name>AdminService</servlet-name> 
    <servlet-class>org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher</servlet-class> 
    <init-param> 
     <param-name>javax.ws.rs.Application</param-name> 
     <param-value>com.etouchpoint.admin.service.AdminApplication</param-value> 
    </init-param> 
</servlet> 

<servlet-mapping> 
    <servlet-name>AdminService</servlet-name> 
    <url-pattern>/admin/*</url-pattern> 
</servlet-mapping> 

Le problème avec cette configuration est que sont 2 ContextLoadListeners qui n'est pas autorisé. Alors, j'ai essayé de créer une classe qui proviendrait de Spring Security et j'ajouterais Spring Session et RestEASY Context Listeners.

session Configuration:

@Configuration 
@EnableJdbcHttpSession 
public class SessionConfig { 
    @Bean 
    public PlatformTransactionManager transactionManager(final DataSource dataSource) { 
     return new DataSourceTransactionManager(dataSource); 
    }} 

ContextLoadListener:

public class SecurityInitializer extends AbstractSecurityWebApplicationInitializer { 

public SecurityInitializer() { 
    super(SecurityConfig.class, SessionConfig.class, SpringContextLoaderListener.class); 
}} 

Cela ne fonctionne pas non plus. Vous finissez avec cette exception:

java.lang.NoSuchMethodException: org.springframework.security.access.SecurityConfig.<init>() 

Je suis à une perte, au moment, de la façon d'obtenir ces 3 bibliothèques pour jouer bien. Est-ce que quelqu'un a fait ça? Quelle était la solution générale? Est-ce que vous déplacez tout en Java, ou êtes-vous capable de le faire en XML?

Répondre

0

Enfin compris!

web.xml

Couple de choses à noter ici.

  • Cette configuration est destinée aux conteneurs Servlet 3.0. Suivez donc certains des Restesy set up for Servlet 3.0 Containers
  • Utilisez les fichiers org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap et org.jboss.resteasy.plugins.spring.SpringContextLoaderListener même si un conteneur Servlet 3.0 est utilisé. N'utilisez pas org.springframework.web.context.ContextLoaderListener. Voir le Spring Integration for Resteasy.
<?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" 
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" 
    version="3.0"> 

    <display-name>Admin</display-name> 

    <!-- Filter for Spring Session --> 
    <filter> 
     <filter-name>springSessionRepositoryFilter</filter-name> 
     <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> 
    </filter> 
    <filter-mapping> 
     <filter-name>springSessionRepositoryFilter</filter-name> 
     <url-pattern>/*</url-pattern> 
     <dispatcher>REQUEST</dispatcher> 
     <dispatcher>ERROR</dispatcher> 
    </filter-mapping> 

    <!-- Filter for 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> 

    <!-- Listener for Resteasy --> 
    <listener> 
     <listener-class>org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap</listener-class> 
    </listener> 
    <listener> 
     <listener-class>org.jboss.resteasy.plugins.spring.SpringContextLoaderListener</listener-class> 
    </listener> 

</web-app> 

applicationContext.xml

<beans 
    xmlns="http://www.springframework.org/schema/beans" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:util="http://www.springframework.org/schema/util" 
    xsi:schemaLocation=" 
     http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd 
     http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.2.xsd"> 

    <!-- This context will contain all of the spring configs --> 
    <import resource="classpath:admin-context.xml" /> 

    <!-- This context will contain all of the spring session/security configs --> 
    <import resource="classpath:admin-security-context.xml" /> 

</beans> 

admin-sécurité context.xml

<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:util="http://www.springframework.org/schema/util" 
    xsi:schemaLocation=" 
     http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd 
     http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd 
     http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd 
     http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.2.xsd"> 

    <context:annotation-config/> 

    <bean class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> 
     <constructor-arg ref="dataSource"/> 
    </bean> 

    <bean class="....CustomJdbcHttpSessionConfiguration" /> 

    <bean id="adminAuthenticationSuccessHandler" class="org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler"> 
     <property name="defaultTargetUrl" value="/index.html" /> 
     <property name="alwaysUseDefaultTargetUrl" value="true" /> 
     <property name="useReferer" value="true" /> 
    </bean> 

    <bean id="adminLoginFailureHandler" class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler"> 
     <property name="defaultFailureUrl" value="/login.html" /> 
     <property name="forwardToDestination" value="true" /> 
    </bean> 

    <security:http pattern="/static/**" security="none" /> 
    <security:http pattern="/favicon.ico" security="none" /> 
    <security:http pattern="/robots.txt" security="none" /> 

    <security:http> 
     <security:csrf disabled="true"/> 

     <security:intercept-url pattern="/login.html" access="hasAnyRole('ANONYMOUS')" requires-channel="any" /> 
     <security:intercept-url pattern="/login" access="hasAnyRole('ANONYMOUS')" requires-channel="any" /> 

     <security:intercept-url pattern="/**" access="hasAnyRole('ADMIN')" requires-channel="any" /> 

     <!-- All of these parameters are needed for login to work correctly -->  
     <security:form-login login-page="/login.html" login-processing-url="/login" authentication-success-handler-ref="adminAuthenticationSuccessHandler" authentication-failure-handler-ref="adminLoginFailureHandler" username-parameter="username" password-parameter="password"/> 

     <!-- Change cookie name to 'SESSION' because that is what is used with Spring Session --> 
     <!-- And all parameters are needed --> 
     <security:logout logout-url="/logout" invalidate-session="true" delete-cookies="SESSION" logout-success-url="/login.html" /> 

    </security:http> 

    <security:authentication-manager> 
     <security:authentication-provider user-service-ref="userDetailsService"> 
      <security:password-encoder hash="sha" /> 
     </security:authentication-provider> 
    </security:authentication-manager> 

</beans> 

CustomJdbcHttpSessionConfiguration.java

Création d'un objet personnalisé ici, donc il peut y avoir plusieurs applications déployées et tous utilisent le même cookie.Soyez prudent ici car cela définit le cookie à '/', ce qui signifie que s'il doit y avoir différents domaines pour les cookies, cet objet personnalisé remplacera les domaines.

public class CustomJdbcHttpSessionConfiguration extends JdbcHttpSessionConfiguration { 

    @Bean 
    public CookieSerializer cookieSerializer() { 

     final DefaultCookieSerializer serializer = new DefaultCookieSerializer(); 
     serializer.setCookieName("SESSION"); // <1> 
     serializer.setCookiePath("/"); // <2> 
     serializer.setDomainNamePattern("^.+?\\.(\\w+\\.[a-z]+)$"); // <3> 

     return serializer; 
    } 

} 

AdminApplication.java

@ApplicationPath("service") 
public class AdminApplication extends Application { 

}