首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使jcaptcha与Spring会话一起工作?

如何使jcaptcha与Spring会话一起工作?
EN

Stack Overflow用户
提问于 2019-01-04 22:08:03
回答 1查看 280关注 0票数 3

我们实现了由Redis支持的Spring会话,并有一个Tomcat服务器集群。当我们通过不设置jvmRoute关闭粘滞会话时,我们一直在jcaptcha服务中获得“文本验证失败”。我认为这是因为jcaptcha servlet对servlet一无所知,它拥有所有Spring会话过滤器,因此无法读取会话变量。我们如何使jcaptcha与Spring会话一起工作?

这是我们的设置:

Web.xml

代码语言:javascript
复制
<servlet>
    <servlet-name>my-servlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>throwExceptionIfNoHandlerFound</param-name>
        <param-value>true</param-value>
    </init-param>
    <load-on-startup>2</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>my-servlet</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

<servlet>
    <servlet-name>jcaptcha</servlet-name>
    <servlet-class>com.octo.captcha.module.servlet.image.SimpleImageCaptchaServlet</servlet-class>
</servlet>

<servlet-mapping>
    <servlet-name>jcaptcha</servlet-name>
    <url-pattern>/jcaptcha/jcaptcha.jpg</url-pattern>
</servlet-mapping>

CustomHttpSessionAppInitializer.java

代码语言:javascript
复制
public class CustomHttpSessionAppInitializer extends AbstractHttpSessionApplicationInitializer {}

RedisSessionConfig.java

代码语言:javascript
复制
@Configuration
@EnableRedisHttpSession
public class RedisSessionConfig {

    @Value("${spring.redis.host}")
    private String redisServerName;

    @Value("${spring.redis.port}")
    private Integer redisServerPort;

    @Value("${spring.redis.database}")
    private Integer redisServerDatabase;

    @Value("${spring.redis.password}")
    private String redisServerPassword;

    @Value("${spring.server.affinity}")
    private Boolean isServerAffinity = Boolean.FALSE;

    @Autowired
    private SessionIdentifierService sessionIdentifierService;

    @Bean
    public JedisConnectionFactory jedisConnectionFactory() {
        RedisStandaloneConfiguration config = new RedisStandaloneConfiguration(redisServerName, redisServerPort);
        config.setDatabase(redisServerDatabase);
        config.setPassword(RedisPassword.of(redisServerPassword));
        return new JedisConnectionFactory(config);
    }

    /*
     * We need to register every HttpSessionListener as a bean to translate SessionDestroyedEvent and SessionCreatedEvent into
     * HttpSessionEvent. Otherwise we will got a lot of warning messages about being Unable to publish Events for the session.
     * See Spring Session Docs at:
     * {@link} https://docs.spring.io/spring-session/docs/current/reference/html5/#httpsession-httpsessionlistener
     */
    @Bean
    public HttpSessionEventPublisher httpSessionEventPublisher() {
        return new HttpSessionEventPublisher();
    }

    @Bean
    public CookieSerializer cookieSerializer() {
        DefaultCookieSerializer serializer = new DefaultCookieSerializer();
        serializer.setCookieName("JSESSIONID");
        serializer.setUseBase64Encoding(false);
        if (isServerAffinity) {
            serializer.setJvmRoute(sessionIdentifierService.getJvmRoute());
        }
        return serializer;
    }

    @Bean
    public RedisTemplate<String, Object> redisTemplate() {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(jedisConnectionFactory());
        return template;
    }
}
EN

回答 1

Stack Overflow用户

发布于 2019-02-07 23:14:39

将jcaptcha与Spring会话集成应该没有问题。只要有从Redis加载会话的方法(在本例中是通过会话cookie ),并且会话存在,调用request.getSession()request.getSession(false)就会返回Redis支持的会话。

这可以在任何称为的过滤器和servlet中工作,这些过滤器和servlet的名称是 springSessionRepositoryFilter。如果您查看SessionRepositoryFilter的源代码,您将看到HttpServletRequestSessionRepositoryRequestWrapper交换。

因此,您的SimpleImageCaptchaServlet和用于验证用户响应的servlet都将获得一个SessionRepositoryRequestWrapper,该SessionRepositoryRequestWrapper似乎将允许您访问Redis支持的会话。

问题可能是您的配置;springSessionRepositoryFilter可能没有在容器中注册,特别是因为您同时使用web.xml和Servlet 3.0+ WebApplicationInitializer。如果您的应用程序工作正常,那么您的web.xml很可能运行良好。您是否使用WebApplicationInitializer加载您的web.xml?如果不是,那么可能是您的Java没有加载。确保您的web.xml以某种方式加载您的配置,可能是通过启用Java文件中的组件扫描(<context:component-scan/>)来加载您的Java以及:

代码语言:javascript
复制
<bean class="org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration"/>

要加载将创建筛选器的配置,必须将其添加到web.xml中:

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

查看关于XML配置的Spring会话引用

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

https://stackoverflow.com/questions/54046802

复制
相关文章

相似问题

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