【问题标题】:How to enable session and set session timeout in Spring Security如何在 Spring Security 中启用会话并设置会话超时
【发布时间】:2016-08-16 04:39:26
【问题描述】:

我是 Spring Security 的新手,我正在研究登录、注销和会话超时功能。我已经通过参考this 文档配置了我的代码。我的代码如下所示:

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

    http.authorizeRequests().antMatchers("/admin/**")
        .access("hasRole('ROLE_USER')").and().formLogin()
        .loginPage("/login").failureUrl("/login?error")
            .usernameParameter("username")
            .passwordParameter("password")
            .and().logout().logoutSuccessUrl("/login?logout").and().csrf();
    http.sessionManagement().maximumSessions(1).expiredUrl("/login?expired");
}

重写类 AbstractSecurityWebApplicationInitializer

import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer;

public class SpringSecurityInitializer extends AbstractSecurityWebApplicationInitializer {

    @Override
    public boolean enableHttpSessionEventPublisher() {
        return true;
    }

}

我需要澄清我是否做得对,如果看起来不错,那么我需要在哪里设置会话超时。我完全是根据注释来做的。

【问题讨论】:

    标签: java spring spring-mvc session spring-security


    【解决方案1】:

    如果你使用JavaConfig并且不想使用XML,你可以创建一个HttpSessionListener并使用getSession().setMaxInactiveInterval(),然后在Initializer中添加监听器onStartup()

    public class SessionListener implements HttpSessionListener {
    
        @Override
        public void sessionCreated(HttpSessionEvent event) {
            System.out.println("session created");
            event.getSession().setMaxInactiveInterval(15);
        }
    
        @Override
        public void sessionDestroyed(HttpSessionEvent event) {
           System.out.println("session destroyed");
        }
    }
    

    然后在初始化器中:

    @Override
    public void onStartup(ServletContext servletContext) throws ServletException {
        super.onStartup(servletContext);
        servletContext.addListener(new SessionListener());
    }
    

    【讨论】:

    • 您还可以将侦听器添加为 bean,以防您以不同的方式启动应用程序。
    • super.onStartup(servletContext);它没有在初始化程序中显示错误
    • 嗨@munilvc session is create onStartup 很好.. 尝试跟踪用户会话时,会话时间应该在正确登录后开始
    • 我应该在哪个类中使用 void onStartup 函数
    【解决方案2】:

    我只能通过在 web.xml 中添加以下配置来解决上述问题。任何更好的方法都会被接受。

     <session-config>
        <session-timeout>20</session-timeout>
    </session-config>
    

    【讨论】:

      【解决方案3】:

      使用 application.properties 时设置属性server.session.timeout= 的值以秒为单位。

      【讨论】:

      【解决方案4】:

      spring security中配置会话超时时间(maxInactiveInterval)的不同方式。

      1. 通过在 web.xml 中添加会话配置(来自 raju vaishnav 的回答)

      2. 通过创建 HttpSessionListener 的实现并将其添加到 servlet 上下文中。(来自 munilvc 的回答)

      3。通过在 spring 安全配置中注册您的自定义 AuthenticationSuccessHandler,并在 onAuthenticationSuccess 方法中设置会话最大不活动间隔。

      这种实现有优势

      1. 登录成功后,可以为不同的角色/用户设置不同的maxInactiveInterval值。

      2. 登录成功后,您可以在会话中设置用户对象,因此可以从会话中的任何控制器中访问用户对象。

      缺点:您不能为匿名用户(未经身份验证的用户)设置会话超时

      创建 AuthenticationSuccessHandler 处理程序

      public class MyAuthenticationSuccessHandler implements AuthenticationSuccessHandler
      {
      
          public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication)
                  throws IOException 
          {
              Set<String> roles = AuthorityUtils.authorityListToSet(authentication.getAuthorities());
              if (roles.contains("ROLE_ADMIN"))
              {
                  request.getSession(false).setMaxInactiveInterval(60);
              }
              else
              {
                  request.getSession(false).setMaxInactiveInterval(120);
              }
              //Your login success url goes here, currently login success url="/"
              response.sendRedirect(request.getContextPath());
          }
      }
      

      注册成功处理程序

      Java 配置方式

      @Override
      protected void configure(final HttpSecurity http) throws Exception
      {
          http
              .authorizeRequests()
                  .antMatchers("/resources/**", "/login"").permitAll()
                  .antMatchers("/app/admin/*").hasRole("ADMIN")
                  .antMatchers("/app/user/*", "/").hasAnyRole("ADMIN", "USER")
              .and().exceptionHandling().accessDeniedPage("/403")
              .and().formLogin()
                  .loginPage("/login").usernameParameter("userName")
                  .passwordParameter("password")
                  .successHandler(new MyAuthenticationSuccessHandler())
                  .failureUrl("/login?error=true")
              .and().logout()
                  .logoutSuccessHandler(new CustomLogoutSuccessHandler())
                  .invalidateHttpSession(true)
              .and().csrf().disable();
      
          http.sessionManagement().maximumSessions(1).expiredUrl("/login?expired=true");
      }
      

      xml配置方式

      <http auto-config="true" use-expressions="true" create-session="ifRequired">
          <csrf disabled="true"/>
      
          <intercept-url pattern="/resources/**" access="permitAll" />
          <intercept-url pattern="/login" access="permitAll" />
      
          <intercept-url pattern="/app/admin/*" access="hasRole('ROLE_ADMIN')" />
          <intercept-url pattern="/" access="hasAnyRole('ROLE_USER', 'ROLE_ADMIN')" />
          <intercept-url pattern="/app/user/*" access="hasAnyRole('ROLE_USER', 'ROLE_ADMIN')" />
      
          <access-denied-handler error-page="/403" />
      
          <form-login 
              login-page="/login"
              authentication-success-handler-ref="authenticationSuccessHandler"
              authentication-failure-url="/login?error=true" 
              username-parameter="userName"
              password-parameter="password" />
      
          <logout invalidate-session="false" success-handler-ref="customLogoutSuccessHandler"/>
      
          <session-management invalid-session-url="/login?expired=true">
              <concurrency-control max-sessions="1" />
          </session-management>
       </http>
      
       <beans:bean id="authenticationSuccessHandler" class="com.pvn.mvctiles.configuration.MyAuthenticationSuccessHandler" />
      
      

      工作代码在my github repository 中可用 工作代码有两种形式

      1. XML config way of implementation

      2. JAVA config way of implementation

      如果您想要在会话即将到期时显示自动注销功能和计时器,如果用户正在填写表单但未提交,则用户可以通过单击保持会话活动按钮来延长会话。 如果你想实现自动注销,请参考stack overflow answer on auto logout on session timeout。希望这会有所帮助。

      【讨论】:

        【解决方案5】:

        在您的应用程序属性中使用 server.servlet.session.timeout=1m(如果没有指定时长后缀,将使用秒。)

        默认为 30 分钟。

        【讨论】:

          【解决方案6】:

          我在 UsernamePasswordAuthenticationFilter 的子类中处理它 您可以通过 -

          获取用户名
          obtainUsername(request);
          

          并应用用户检查并相应地设置超时,例如-

          if(username.equalsIgnoreCase("komal-singh-sisodiya@xyz.com")) 
                  {
                  logger.debug("setting timeout 15 min");
                  request.getSession(false).setMaxInactiveInterval(15*60);
                  }
          

          【讨论】:

            猜你喜欢
            • 2012-07-26
            • 2011-07-20
            • 2018-09-27
            • 2016-08-03
            • 2014-10-18
            • 2012-08-18
            • 2014-10-20
            • 1970-01-01
            相关资源
            最近更新 更多