【问题标题】:Spring mvc sessionRegistry returns empty list of principalsSpring mvc sessionRegistry 返回空的委托人列表
【发布时间】:2021-05-16 11:36:11
【问题描述】:

为了更改经过身份验证的用户的权限,我需要检索所有这些用户,因此我使用了 SessionRegistry,如 link 所示。

但是sessionRegistry.getAllPrincipals() 方法返回一个空列表。

我的项目配置如下:

Web.xml:

<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>loyfeey</display-name>
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/spring-servlet.xml</param-value>
    </context-param>
    <!-- <context-param> <param-name>contextConfigLocation</param-name> <param-value>com.mkyong.web.config</param-value> 
        </context-param> -->
    <listener>
        <listener-class>
            org.springframework.security.web.session.HttpSessionEventPublisher</listener-class>
    </listener>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <servlet>
        <servlet-name>spring</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>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>spring</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
    <filter>
        <filter-name>encodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
        <init-param>
            <param-name>forceEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>

    <filter-mapping>
        <filter-name>encodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    <error-page>
        <location>/errors</location>
    </error-page>

    <session-config>
        <session-timeout>30</session-timeout>
        <cookie-config>
            <!-- if true then browser script won't be able to access the cookie -->
            <http-only>false</http-only>
            <!--!if true then the cookie will be sent only over HTTPS connection -->
            <secure>false</secure>
        </cookie-config>
        <tracking-mode>COOKIE</tracking-mode>
    </session-config>
</web-app> 

WebSecurityConfigurerAdapter

@Configuration
@EnableWebSecurity
@Transactional
@Service
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private CompteDetailsService compteDetailsService;

    @Autowired
    private IMatcherService matcherDetailsService;

    @Autowired
    private CustomLogoutSuccessHandler logoutSuccessHandler;

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

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {

        auth.userDetailsService(compteDetailsService).passwordEncoder(passwordEncoder());
    }


    @Override
    protected void configure(HttpSecurity http) throws Exception {



        http.csrf().disable();

        http.authorizeRequests().antMatchers(/*some paths*/).permitAll();

        http.authorizeRequests().antMatchers("/**").access("hasRole('ROLE_ADMIN')");
        
    
        List<Matcher> matchers = matcherDetailsService.getMatchersConfig();

        for (Matcher matcher : matchers) {
            http.authorizeRequests()//
                    .antMatchers("/" + matcher.getPath())//
                    .hasAnyAuthority(matcher.getPermission().toString());

        }
        http.authorizeRequests().anyRequest().denyAll();


        http.authorizeRequests().and().formLogin()
                .loginProcessingUrl("/login") 
                .loginPage("/")
                .defaultSuccessUrl("/authentification/successful")
                .failureUrl("/?error=true")
                .usernameParameter("login")
                .passwordParameter("password");

        
        http.authorizeRequests().and().logout()
                .logoutUrl("/authentification/logout")
                 .logoutSuccessUrl("/");
                .logoutSuccessHandler(logoutSuccessHandler);
         
    
   http.authorizeRequests().and().exceptionHandling().accessDeniedPage("/authentification/accessDenied");
        SessionRegistry sr = sessionRegistry();

        http.sessionManagement().maximumSessions(1).sessionRegistry(sessionRegistry());
    }
}

如果有人可以帮我找出我缺少的东西

【问题讨论】:

  • 您的应用程序被加载了两次,因此您有 2 个SessionRegistry 实例,一个实际正在使用,一个无用,正在控制器中使用。您的ContextLoaderListenerDispatcjerServlet 都加载了spring-servlet.xml,导致两次加载相同的bean(只会占用更多内存和可能的奇怪事务问题)。您的COntextLoaderLIstener 应该加载共享/通用 bean,例如服务、存储库、数据源和安全性。您的 DispatcherServlet 仅与 Web 相关的东西(控制器、视图解析器等)。

标签: spring security session model-view-controller


【解决方案1】:

感谢@M。 Denium 对于他的回答,我将 spring-servlet.xml 分成两个文件:spring-context.xmlspring-servlet.xml,如下所示:

Web.xml:

<?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>loyfeey</display-name>
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/spring-context.xml</param-value>
    </context-param>
    <!-- <context-param> <param-name>contextConfigLocation</param-name> <param-value>com.mkyong.web.config</param-value> 
        </context-param> -->
    <listener>
        <listener-class>
            org.springframework.security.web.session.HttpSessionEventPublisher</listener-class>
    </listener>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <servlet>
        <servlet-name>spring</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/spring-servlet.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>spring</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
    <filter>
        <filter-name>encodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
        <init-param>
            <param-name>forceEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>

    <filter-mapping>
        <filter-name>encodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    <error-page>
        <location>/errors</location>
    </error-page>

    <session-config>
        <session-timeout>30</session-timeout>
        <cookie-config>
            <!-- if true then browser script won't be able to access the cookie -->
            <http-only>false</http-only>
            <!--!if true then the cookie will be sent only over HTTPS connection -->
            <secure>false</secure>
        </cookie-config>
        <tracking-mode>COOKIE</tracking-mode>
    </session-config>
</web-app>


【讨论】:

    猜你喜欢
    • 2018-01-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-07
    • 1970-01-01
    相关资源
    最近更新 更多