1
votes

I'am using Hazelcast 3.4 with Spring security 3.2.5. When I deploy the application and try to log in, the login is successful but an exception is thrown, resulting in an error page. Regardless of the error page I am logged in and my session is "alive". But after each login I always get the execption and as a result a land on the error page (which I have set up to appear in case of an unhandled exception).

My Hazelcast config in the web.xml:

     <filter>
    <filter-name>hazelcast-filter</filter-name>
    <filter-class>com.hazelcast.web.spring.SpringAwareWebFilter</filter-class>
    <init-param>
        <param-name>map-name</param-name>
        <param-value>at-sessions</param-value>
    </init-param>

    <init-param>
        <param-name>sticky-session</param-name>
        <param-value>true</param-value>
    </init-param>
    <init-param>
        <param-name>cookie-name</param-name>
        <param-value>hsessionId</param-value>
    </init-param>
    <init-param>
        <param-name>cookie-http-only</param-name>
        <param-value>true</param-value>
    </init-param>
    <init-param>
        <param-name>instance-name</param-name>
        <param-value>hazelcastInstance</param-value>
    </init-param>
    <init-param>
        <param-name>shutdown-on-destroy</param-name>
        <param-value>false</param-value>
    </init-param>
</filter>

<listener>
    <listener-class>com.hazelcast.web.SessionListener</listener-class>
</listener> 


 <filter-mapping>
    <filter-name>hazelcast-filter</filter-name>
    <url-pattern>/*</url-pattern>
    <dispatcher>FORWARD</dispatcher>
    <dispatcher>INCLUDE</dispatcher>
    <dispatcher>REQUEST</dispatcher>
</filter-mapping>

My hazelcast config in the Spring context xml:

<hz:hazelcast id="hazelcastInstance">
    <hz:config>
        <hz:instance-name>hazelcastInstance</hz:instance-name>
        <hz:group name="${hazelcast.group.name}" password="${hazelcast.group.password}"/>
        <hz:properties>
            <hz:property name="hazelcast.jmx">true</hz:property>
            <hz:property name="hazelcast.logging.type">slf4j</hz:property>
        </hz:properties>
        <hz:network port="${hazelcast.port}">
            <hz:join>
                <hz:multicast enabled="false"/>
                <hz:tcp-ip enabled="${hazelcast.tcp.ip.enabled}">
                    <hz:members>${hazelcast.tcp.ip.members}</hz:members>
                </hz:tcp-ip>
                <hz:aws enabled="${hazelcast.aws.enabled}"
                    access-key="${hazelcast.aws.access.key}"
                    secret-key="${hazelcast.aws.secret.key}"
                    region="${hazelcast.aws.region}"
                    tag-key="${hazelcast.aws.tag.key}"
                    tag-value="${hazelcast.aws.tag.value}"
                />
            </hz:join>
        </hz:network>
        <hz:map name="at-sessions"
            in-memory-format="${hazelcast.sessions.in.memory.format}"
            backup-count="${hazelcast.sessions.backup.count}"
            async-backup-count="${hazelcast.sessions.async.backup.count}"
            time-to-live-seconds="${hazelcast.sessions.ttl.seconds}"
            max-idle-seconds="${hazelcast.sessions.max.idle.seconds}"
            eviction-policy="LRU"
            max-size-policy="USED_HEAP_PERCENTAGE"
            max-size="${hazelcast.sessions.max.size}"
            eviction-percentage="${hazelcast.sessions.eviction.percentage}"
            merge-policy="${hazelcast.sessions.merge.policy}"
        />
    </hz:config>

</hz:hazelcast>

I get the following exception:

Caused by: javax.servlet.ServletException: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.springframework.security.core.session.SessionRegistry] is defined
    at org.apache.jsp.WEB_002dINF.views.common.general_002derror_jsp._jspService(general_002derror_jsp.java:195) ~[na:na]
    at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70) ~[jasper.jar:7.0.57]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:727) [servlet-api.jar:na]
    at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:432) ~[jasper.jar:7.0.57]
    ... 97 common frames omitted

Without Hazelcast the login is working completely fine. Any help would be greatly appreciated.

3

3 Answers

2
votes

I've got the same issue. The cause was I'm using the Spring Java Config for Spring Security using the DSL. Using the current Spring Security 4.0.1, the Configurer will create a SessionRegistry only on demand and (it looks like) not as a registered bean component.

I have fixed this with an explicit definition of the SessionRegistry.

    http
        .sessionManagement()
            .sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
            .sessionFixation()
                .migrateSession()
                .maximumSessions(10)
                .sessionRegistry(sessionRegistry()) // << this here!
                .and()
            .and()

and

@Bean
public SessionRegistry sessionRegistry() {
    return new SessionRegistryImpl();
}

Unless Hazelcast's WebFilter is used, this is not required since Spring's SessionManagementConfigurer will ensure an instance of SessionRegistry will be created. But it cannot be found using the type SessionRegistry.

0
votes

It seems that all is Ok. You have configured all regarding the specifications.

HazelCast Documentation

You don't have the most common errors in this configurations that is the use of com.hazelcast.web.Webfilter, instead of com.hazelcast.web.SpringAwareWebFilter in your filter definition.

Furthermore you could check if your definition of the "sessionRegistry" bean is done in that way.

<beans:property name="sessionRegistry" ref="sessionRegistry"/> 

In any case, you could to take a look to the Hazelcast Code Samples in order to compare step by step all your configuration.

HazelCast Code Samples

I hope it's useful to you. Regards.

0
votes

If you use xml configuration for spring context, make sure to define

<bean id="sessionRegistry"
  class="org.springframework.security.core.session.SessionRegistryImpl" />

in spring-security.xml (or whatever file you use to configure spring security context)