简体   繁体   English

RestEASY,Spring安全性,Spring会话集成

[英]RestEASY, Spring Security, Spring Session Integration

Has anyone successfully integrated RestEASY with Spring Security and Spring Session? 是否有人成功将RestEASY与Spring Security和Spring Session集成在一起? I am running into problems with the ContextLoadListener. 我遇到了ContextLoadListener问题。 I was able to integrate RestEASY and Spring Security with the following web.xml. 我能够将RestEASY和Spring Security与以下web.xml集成。

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

After reading the documentation for Spring Session, the web.xml would end up looking something like this: 阅读了Spring Session的文档后,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>

The problem with this configuration is that there are 2 ContextLoadListeners which is not allowed. 此配置的问题是不允许有2个ContextLoadListeners。 So, then I tried creating a Class which would stem from Spring Security and add Spring Session and RestEASY Context Listeners to it. 因此,然后我尝试创建一个源于Spring Security的类,并向其中添加Spring Session和RestEASY上下文侦听器。

Session Configuration: 会话配置:

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

ContextLoadListener: ContextLoadListener:

public class SecurityInitializer extends AbstractSecurityWebApplicationInitializer {

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

This doesn't work either. 这也不起作用。 You end with this exception: 您以以下异常结束:

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

I am at a loss, at the moment, of how to get these 3 libraries to play nicely. 目前,我不知道如何使这3个库正常运行。 Has anyone done this? 有人这样做吗? What was the general solution? 一般的解决方案是什么? Do you move everything into Java, or are you able to do it in XML? 您是否将所有内容都移到Java中,或者是否可以XML格式?

Finally figured it out!! 终于想通了!!

web.xml web.xml

Couple of things to note here. 这里要注意的几件事。

  • This config is for Servlet 3.0 containers. 此配置适用于Servlet 3.0容器。 So follow some of the Restesy set up for Servlet 3.0 Containers 因此,请遵循针对Servlet 3.0容器的一些Restesy设置
  • Use the org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap and org.jboss.resteasy.plugins.spring.SpringContextLoaderListener even though a Servlet 3.0 container is used. 即使使用了Servlet 3.0容器,也请使用org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap和org.jboss.resteasy.plugins.spring.SpringContextLoaderListener。 Do not use the org.springframework.web.context.ContextLoaderListener. 不要使用org.springframework.web.context.ContextLoaderListener。 See the Spring Integration for Resteasy . 有关Resteasy的信息,请参见Spring集成
<?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 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-security-context.xml admin-security-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 CustomJdbcHttpSessionConfiguration.java

Creating a custom object here so there can be multiple apps deployed and all of them use the same cookie. 在此处创建一个自定义对象,以便可以部署多个应用程序,并且所有应用程序都使用相同的cookie。 Be careful here because this sets the cookie to '/' which means if there needs to be different domains for cookies, this custom object will override the domains. 请注意此处,因为这会将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 AdminApplication.java

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

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM