首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >RestEASY、Spring Security、Spring Session集成

RestEASY、Spring Security、Spring Session集成
EN

Stack Overflow用户
提问于 2017-09-15 05:10:22
回答 1查看 588关注 0票数 0

有人成功地将RestEASY与Spring Security和Spring Session集成在一起了吗?我遇到了ContextLoadListener的问题。我能够用下面的web.xml集成RestEASY和Spring Security。

代码语言:javascript
复制
<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>

在阅读了Spring Session的文档之后,web.xml最终会看起来像这样:

代码语言:javascript
复制
<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上下文侦听器。

会话配置:

代码语言:javascript
复制
@Configuration
@EnableJdbcHttpSession
public class SessionConfig {
    @Bean
    public PlatformTransactionManager transactionManager(final DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }}

ContextLoadListener:

代码语言:javascript
复制
public class SecurityInitializer extends AbstractSecurityWebApplicationInitializer {

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

这也不起作用。您将以以下异常结束:

代码语言:javascript
复制
java.lang.NoSuchMethodException: org.springframework.security.access.SecurityConfig.<init>()

目前,我对如何让这3个库发挥作用感到困惑。有人这么做过吗?一般的解决方案是什么?您是将所有内容都迁移到Java中,还是能够在XML中完成?

EN

回答 1

Stack Overflow用户

发布于 2017-10-13 06:51:57

终于弄明白了!!

web.xml

这里有几件事需要注意。

  • 此配置适用于Servlet3.0容器。因此,即使使用Servlet3.0容器,也要遵循一些Restesy set up for Servlet 3.0 Containers
  • Use、org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap和org.jboss.resteasy.plugins.spring.SpringContextLoaderListener。不要使用org.springframework.web.context.ContextLoaderListener.请参阅Spring Integration for Resteasy.

代码语言:javascript
复制
<?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

代码语言:javascript
复制
<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-security-context.xml

代码语言:javascript
复制
<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需要不同的域,此自定义对象将覆盖这些域。

代码语言:javascript
复制
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

代码语言:javascript
复制
@ApplicationPath("service")
public class AdminApplication extends Application {

}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46228270

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档