Spring sessionRegistry提供了零个登录用户的列表

Spring sessionRegistry提供了零个登录用户的列表,spring,spring-security,spring-session,Spring,Spring Security,Spring Session,我从这篇文章中引用了一些内容来编写一个登录页面 但我根据最新文档更改了sessionRegistry配置 我得到的主体列表为0 这是我的配置文件 <?xml version="1.0" encoding="UTF-8"?> <beans:beans xmlns:security="http://www.springframework.org/schema/security" xmlns:xsi="http://www.w3.org/2

我从这篇文章中引用了一些内容来编写一个登录页面

但我根据最新文档更改了sessionRegistry配置

我得到的主体列表为0

这是我的配置文件

        <?xml version="1.0" encoding="UTF-8"?>
    <beans:beans xmlns:security="http://www.springframework.org/schema/security"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:beans="http://www.springframework.org/schema/beans"
        xmlns:context="http://www.springframework.org/schema/context"
        xmlns:mvc="http://www.springframework.org/schema/mvc"
        xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
            http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
            http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.2.xsd">

        <!-- DispatcherServlet Context: defines this servlet's request-processing 
            infrastructure -->

        <!-- Enables the Spring MVC @Controller programming model -->
        <mvc:annotation-driven />

    <!-- Handles HTTP GET requests for /resources/** by efficiently serving 
        up static resources in the ${webappRoot}/resources directory -->
    <!-- <mvc:resources mapping="/resources/**" location="/resources/" /> -->

    <!-- Resolves views selected for rendering by @Controllers to .jsp resources 
        in the /WEB-INF/views directory -->
    <beans:bean
        class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <beans:property name="prefix" value="/WEB-INF/views/" />
        <beans:property name="suffix" value=".jsp" />
    </beans:bean>

    <context:component-scan base-package="com.project.session" />

    <security:http auto-config="false" entry-point-ref="authenticationEntryPoint" use-expressions="true" >



        <security:intercept-url pattern="/krams/auth/login" access="permitAll" />
        <security:intercept-url pattern="/krams/main/admin" access="hasRole('ROLE_ADMIN')" />
        <security:intercept-url pattern="/krams/main/common"    access="hasRole('ROLE_USER')" />
        <security:intercept-url pattern="/krams/main/users" access="hasRole('ROLE_USER')" />

        <security:logout 
                invalidate-session="true"
            logout-success-url="/krams/auth/login" 
            logout-url="/krams/auth/logout" />


        <security:custom-filter position="FORM_LOGIN_FILTER" ref="myAuthFilter" />
                <security:custom-filter position="CONCURRENT_SESSION_FILTER" ref="concurrencyFilter" />
        <security:session-management    session-authentication-strategy-ref="sas" />

    </security:http>



    <beans:bean id="myAuthFilter"   class="org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter">
        <beans:property name="sessionAuthenticationStrategy"
            ref="sas" />
        <beans:property name="authenticationManager" ref="authenticationManager" />
        <beans:property name="authenticationSuccessHandler"
            ref="customAuthenticationSuccessHandler" />
        <beans:property name="authenticationFailureHandler"
            ref="customAuthenticationFailureHandler" />
    </beans:bean>


    <beans:bean id="customAuthenticationFailureHandler" class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler">
        <beans:property name="defaultFailureUrl" value="/krams/auth/login?error=true"></beans:property>
    </beans:bean>

    <beans:bean id="customAuthenticationSuccessHandler" class="org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler">
        <beans:property name="defaultTargetUrl" value="/krams/main/common"></beans:property>
    </beans:bean>





    <beans:bean id="concurrencyFilter"  class="org.springframework.security.web.session.ConcurrentSessionFilter">
        <beans:property name="sessionRegistry" ref="sessionRegistry" />
        <beans:property name="expiredUrl" value="/krams/auth/session-expired" />
    </beans:bean>


    <beans:bean id="authenticationEntryPoint"   class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
        <beans:property name="loginFormUrl" value="/krams/auth/login"></beans:property>
    </beans:bean>
    <security:authentication-manager alias="authenticationManager">
        <security:authentication-provider user-service-ref="myUserDetailService">
            <!-- <security:password-encoder hash="sha" /> -->
        </security:authentication-provider>
    </security:authentication-manager>

    <security:user-service id="myUserDetailService">
        <security:user name="john" password="admin1234"
            authorities="ROLE_USER" />
        <security:user name="jane" password="admin1234"
            authorities="ROLE_USER" />
    </security:user-service>

<!--    <beans:bean id="sas"    class="org.springframework.security.web.authentication.session.CompositeSessionAuthenticationStrategy">
        <beans:constructor-arg>
            <beans:list>
                <beans:bean
                    class="org.springframework.security.web.authentication.session.ConcurrentSessionControlAuthenticationStrategy">
                    <beans:constructor-arg ref="sessionRegistry" />
                    <beans:property name="maximumSessions" value="1" />
                    <beans:property name="exceptionIfMaximumExceeded"
                        value="true" />
                </beans:bean>
                <beans:bean
                    class="org.springframework.security.web.authentication.session.SessionFixationProtectionStrategy">
                </beans:bean>
                <beans:bean
                    class="org.springframework.security.web.authentication.session.RegisterSessionAuthenticationStrategy">
                    <beans:constructor-arg ref="sessionRegistry" />
                </beans:bean>
            </beans:list>
        </beans:constructor-arg>
    </beans:bean> -->

    <beans:bean id="sas" class="org.springframework.security.web.authentication.session.ConcurrentSessionControlStrategy">
            <beans:property name = "maximumSessions" value="-1" />
            <beans:constructor-arg name="sessionRegistry" ref="sessionRegistry" />
    </beans:bean>

    <beans:bean id="sessionRegistry" class="org.springframework.security.core.session.SessionRegistryImpl" />
</beans:beans>
这里是web.xml

 <?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

<!-- The definition of the Root Spring Container shared by all Servlets and Filters -->
<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/spring/root-context.xml,/WEB-INF/spring/appServlet/servlet-context.xml</param-value>
</context-param>

<!-- Creates the Spring Container shared by all Servlets and Filters -->
<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<listener>
    <listener-class>org.springframework.security.web.session.HttpSessionEventPublisher</listener-class>
</listener>

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

<!-- Processes application requests -->
<servlet>
    <servlet-name>appServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>appServlet</servlet-name>
    <url-pattern>/krams/*</url-pattern>
</servlet-mapping>

上下文配置位置
/WEB-INF/spring/root-context.xml,/WEB-INF/spring/appServlet/servlet-context.xml
org.springframework.web.context.ContextLoaderListener
org.springframework.security.web.session.HttpSessionEventPublisher
springSecurityFilterChain
org.springframework.web.filter.DelegatingFilterProxy
springSecurityFilterChain
/*
appServlet
org.springframework.web.servlet.DispatcherServlet
上下文配置位置
/WEB-INF/spring/appServlet/servlet-context.xml
1.
appServlet
/克拉姆斯/*

有谁能告诉我我在哪里犯了错误吗?
是否有任何配置丢失或错误?

您的
ContextLoaderListener
DispatcherServlet
正在加载相同的配置。这会导致两次加载整个应用程序,这反过来会导致Spring安全性使用不同的
SessionRegistry
实例,然后是控制器,后者总是空的

您应该将配置拆分为一个由
ContextLoaderListener加载的配置和一个由
DispatcherServlet加载的配置

ContextLoaderListener
应该包含所有全局内容,如服务、存储库、基础结构bean(数据源、连接工厂等)和您的安全配置。另外,我要说的是,您当前的配置太多了,只需使用
security
名称空间就可以实现同样的配置。考虑到这一点,配置应该如下所示

<?xml version="1.0" encoding="UTF-8"?>
<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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd">

    <context:component-scan base-package="com.project.session">
        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>

    <security:http use-expressions="true">

        <security:intercept-url pattern="/krams/auth/login" access="permitAll"/>
        <security:intercept-url pattern="/krams/main/admin" access="hasRole('ROLE_ADMIN')"/>
        <security:intercept-url pattern="/krams/main/common" access="hasRole('ROLE_USER')"/>
        <security:intercept-url pattern="/krams/main/users" access="hasRole('ROLE_USER')"/>

        <security:form-login login-page="/krams/auth/login"
                             default-target-url="/krams/main/common"
                             authentication-failure-url="/krams/auth/login?error=true"/>
        <security:logout invalidate-session="true" logout-success-url="/krams/auth/login"
                         logout-url="/krams/auth/logout"/>

        <security:session-management>
            <security:concurrency-control max-sessions="1" session-registry-alias="sessionRegistry" expired-url="/krams/auth/session-expired"/>
        </security:session-management>

    </security:http>



    <security:authentication-manager alias="authenticationManager">
        <security:authentication-provider>
            <security:user-service>
                <security:user name="john" password="admin1234" authorities="ROLE_USER"/>
                <security:user name="jane" password="admin1234" authorities="ROLE_USER"/>
            </security:user-service>
        </security:authentication-provider>
    </security:authentication-manager>
</beans>

这将导致您的bean加载一次,并且您的控制器应该获得正确的
SessionRegistry
实例。

您可以更新第一个链接吗?似乎已断开。@bphilipnyc Hi更正了链接问题。您正在加载两次相同的配置,复制您的bean。控制器中使用的bean与Spring Security使用的实例不同。拆分配置,不要两次加载所有内容。@M.Deinum您是指sessionRegistry bean吗?那我怎么装呢?我尝试使用资源(“sessionRegistry”)SessionRegistryImpl impl;也一样,但那不太管用。你能再澄清一点吗?关于所有配置都加载了两次这一事实,有什么不清楚的?
ContextLoaderListener
DispatcherServlet
都加载相同的配置,这意味着您正在复制所有内容。您基本上是两次加载整个应用程序。您需要将核心部分(安全、服务、存储库、数据源等)和web相关部分(视图解析程序、控制器等)分开,分别由
ContextLoaderListener
DispatcherServlet
加载。这将只加载一次,您将获得正确的实例。如何使用spring引导和注释实现这一点?
<?xml version="1.0" encoding="UTF-8"?>
<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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd">

    <context:component-scan base-package="com.project.session">
        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>

    <security:http use-expressions="true">

        <security:intercept-url pattern="/krams/auth/login" access="permitAll"/>
        <security:intercept-url pattern="/krams/main/admin" access="hasRole('ROLE_ADMIN')"/>
        <security:intercept-url pattern="/krams/main/common" access="hasRole('ROLE_USER')"/>
        <security:intercept-url pattern="/krams/main/users" access="hasRole('ROLE_USER')"/>

        <security:form-login login-page="/krams/auth/login"
                             default-target-url="/krams/main/common"
                             authentication-failure-url="/krams/auth/login?error=true"/>
        <security:logout invalidate-session="true" logout-success-url="/krams/auth/login"
                         logout-url="/krams/auth/logout"/>

        <security:session-management>
            <security:concurrency-control max-sessions="1" session-registry-alias="sessionRegistry" expired-url="/krams/auth/session-expired"/>
        </security:session-management>

    </security:http>



    <security:authentication-manager alias="authenticationManager">
        <security:authentication-provider>
            <security:user-service>
                <security:user name="john" password="admin1234" authorities="ROLE_USER"/>
                <security:user name="jane" password="admin1234" authorities="ROLE_USER"/>
            </security:user-service>
        </security:authentication-provider>
    </security:authentication-manager>
</beans>
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

       <!-- DispatcherServlet Context: defines this servlet's request-processing
           infrastructure -->

       <!-- Enables the Spring MVC @Controller programming model -->
       <mvc:annotation-driven />

       <!-- Handles HTTP GET requests for /resources/** by efficiently serving
           up static resources in the ${webappRoot}/resources directory -->
       <!-- <mvc:resources mapping="/resources/**" location="/resources/" /> -->

       <!-- Resolves views selected for rendering by @Controllers to .jsp resources
           in the /WEB-INF/views directory -->
       <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
              <property name="prefix" value="/WEB-INF/views/" />
              <property name="suffix" value=".jsp" />
       </bean>

       <context:component-scan base-package="com.project.session" use-default-filters="false">
           <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" />
       </context:component-scan>


</beans>