weixin_33720452 2015-11-03 15:57 采纳率: 0%
浏览 54

会话到期时重定向

I have used one of the several approaches for solving issue with redirecting to login page when ajax or non-ajax event occurred and session was expired: https://gist.github.com/banterCZ/5160269

During testing ajax case in debug mode, I have performed following steps:

  1. Open two tabs in my browser.
  2. Perform login.
  3. The first page is displayed data table with several action buttons.
  4. The second page is displayed log out button.
  5. So, when I press log out button, I am going into the JsfRedirectStrategy class into else statement:

Bean:

@Component 
public class JsfRedirectStrategy implements InvalidSessionStrategy {

    final static Logger logger = LoggerFactory.getLogger(JsfRedirectStrategy.class);

    private static final String FACES_REQUEST_HEADER = "faces-request";

    private String invalidSessionUrl = "/login.xhtml";

    @Override
    public void onInvalidSessionDetected(HttpServletRequest request, HttpServletResponse response)
            throws IOException, ServletException {

        boolean ajaxRedirect = "partial/ajax".equals(request.getHeader(FACES_REQUEST_HEADER));
        if (ajaxRedirect) {
            String contextPath = request.getContextPath();
            String redirectUrl = contextPath + invalidSessionUrl;
            logger.debug("Session expired due to ajax request, redirecting to '{}'", redirectUrl);

            String ajaxRedirectXml = createAjaxRedirectXml(redirectUrl);
            logger.debug("Ajax partial response to redirect: {}", ajaxRedirectXml);

            response.setContentType("text/xml");
            response.getWriter().write(ajaxRedirectXml);
        } else { 
            String requestURI = getRequestUrl(request);
            logger.info(
                    "Session expired due to non-ajax request, starting a new session and redirect to requested url '{}'",
                    requestURI);
            request.getSession(true);
            response.sendRedirect(requestURI);
        }

    }

    private String getRequestUrl(HttpServletRequest request) {
        StringBuffer requestURL = request.getRequestURL();

        String queryString = request.getQueryString();
        if (StringUtils.hasText(queryString)) {
            requestURL.append("?").append(queryString);
        }

        return requestURL.toString();
    }

    private String createAjaxRedirectXml(String redirectUrl) {
        return new StringBuilder().append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>")
                .append("<partial-response><redirect url=\"")
                .append(redirectUrl)
                .append("\"></redirect></partial-response>").toString();
    }
}

and the following message is printed: Session expired due to non-ajax request, starting a new session and redirect to requested url

So, new session was opened, even user was logged out.

6. Then I am going to the first page and press one of the action button to trigger ajax event, but nothing happened (no action.)

the following message is printed: o.s.b.a.audit.listener.AuditListener - AuditEvent [timestamp=Tue Nov 03 17:44:39 EET 2015, principal=anonymousUser, type=AUTHORIZATION_FAILURE, data={type=org.springframework.security.access.AccessDeniedException, message=Access is denied}]

I suppose that reason of such behavior is executing this sample of code at step 5:

request.getSession(true);

From my point of view, the correct behavior would be if result of step 6 would be redirecting to the loging page.

So, please tell me how to achieve this?

My Spring Security config is:

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private UserDetailsServiceImpl userDetailsService;

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService);
    }

    @Override
    @Bean
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // @formatter:off   
        http
            .csrf().disable()
            .authorizeRequests()
            .antMatchers("/invite.xhtml").permitAll()
            .antMatchers("/login.xhtml").permitAll()
            .antMatchers("/forgotpassword.xhtml").permitAll()
            .antMatchers("/resetpwd.xhtml").permitAll()
            .antMatchers("/admin/*").hasRole(Roles.ROLE_ADMIN.getSpringSecName())
            .antMatchers("/**").authenticated()
            .antMatchers("/actuator/*").permitAll()
            .and()
                .formLogin()
                    .loginPage("/login.xhtml").permitAll()
                    //.failureUrl("/login?error").permitAll()
            .and()
            .logout()
            .logoutRequestMatcher( new AntPathRequestMatcher("/logout"))
            .logoutSuccessUrl("/login.xhtml")
            .permitAll()
            .and()
            .exceptionHandling().authenticationEntryPoint(new AjaxAwareAuthenticationEntryPoint("/login.xhtml"));

        http.headers().frameOptions().disable();

        http.addFilterBefore(sessionManagementFilter(), FilterSecurityInterceptor.class);
     // @formatter:on
    }

    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers("/javax.faces.resource/**");
    }

    @Bean
    public HttpSessionSecurityContextRepository httpSessionSecurityContextRepository() {
        return new HttpSessionSecurityContextRepository();
    }

    @Bean
    public JsfRedirectStrategy jsfRedirectStrategy() {
        return new JsfRedirectStrategy();
    }

    @Bean
    public SessionManagementFilter sessionManagementFilter() {
        SessionManagementFilter sessionManagementFilter = new SessionManagementFilter(
                httpSessionSecurityContextRepository());
        sessionManagementFilter.setInvalidSessionStrategy(jsfRedirectStrategy());
        return sessionManagementFilter;
    }

}
  • 写回答

0条回答 默认 最新

    报告相同问题?

    悬赏问题

    • ¥15 请问paddlehub能支持移动端开发吗?在Android studio上该如何部署?
    • ¥170 如图所示配置eNSP
    • ¥20 docker里部署springboot项目,访问不到扬声器
    • ¥15 netty整合springboot之后自动重连失效
    • ¥15 悬赏!微信开发者工具报错,求帮改
    • ¥20 wireshark抓不到vlan
    • ¥20 关于#stm32#的问题:需要指导自动酸碱滴定仪的原理图程序代码及仿真
    • ¥20 设计一款异域新娘的视频相亲软件需要哪些技术支持
    • ¥15 stata安慰剂检验作图但是真实值不出现在图上
    • ¥15 c程序不知道为什么得不到结果