2017-09-14 136 views
0

有沒有人成功地將RestEASY與Spring Security和Spring Session集成?我遇到了ContextLoadListener的問題。我能夠將RestEASY和Spring Security與以下web.xml集成。RestEASY,Spring Security,Spring Session集成

<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> 

閱讀文檔的春季會議後,在web.xml最終會看起來像這樣:

<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> 

具有這種配置的問題是,有是2不允許的ContextLoadListeners。所以,我嘗試創建一個源自Spring Security的類,併爲其添加Spring Session和RestEASY Context Listeners。

會話配置:

@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); 
}} 

這也不起作用。你最終與此異常:

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

我很茫然,此刻如何獲得這3個庫發揮很好。有沒有人做過這個?什麼是通用解決方案?你把所有東西都移到Java中,還是你能用XML來完成?

回答

0

終於搞明白了!

的web.xml

夫婦的事情,這裏要注意。

  • 此配置適用於Servlet 3.0容器。因此,請遵循一些Restesy set up for Servlet 3.0 Containers
  • 即使使用Servlet 3.0容器,也可以使用org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap和org.jboss.resteasy.plugins.spring.SpringContextLoaderListener。不要使用org.springframework.web.context.ContextLoaderListener。請參閱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> 

管理,安全的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

這裏創建一個自定義的對象,因此可以有多個應用程序部署 ,他們都使用相同的cookie。在這裏要小心,因爲這將 cookie設置爲'/',這意味着如果Cookie需要有不同的域 ,則此自定義對象將覆蓋域。

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 { 

}