Spring MVC / Security - 用户在成功登录后仍然可以访问登录页面

问题描述 投票:0回答:2

我对Spring很新。

我正在使用Spring MVC的4.3.9.RELEASE版本,4.2.3.RELEASE的Spring Security。

我使用spring的内置登录和一点定制,这是我的配置

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    private UserDetailsService myUserService;

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {       
        auth
            .userDetailsService(myUserService);
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .antMatchers("/resources/**").permitAll()
                .anyRequest().authenticated()
                .and()
            .formLogin()
                .loginPage("/login")
                .permitAll()
                .and()
            .rememberMe()
                .alwaysRemember(true)
                .and()
            .logout()
                .permitAll();

    }
}

为什么用户登录成功后可以访问登录页面?我试着从与我相同的问题中学习,但没有一个与我合作。

此解决方案不适用于我:

<sec:authorize access="isAuthenticated()">
  <% response.sendRedirect(request.getContextPath()); %>
</sec:authorize>

我正在使用Apache Tiles,我有is_authenticated.jsp与该部分。这是tiles.xml:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE tiles-definitions PUBLIC
        "-//Apache Software Foundation//DTD Tiles Configuration 3.0//EN"
        "http://tiles.apache.org/dtds/tiles-config_3_0.dtd">

<tiles-definitions>
  <definition name="base" template="/WEB-INF/layouts/page.jsp">
    <put-attribute name="pageHeader" value="/WEB-INF/layouts/page_header.jsp"></put-attribute>
    <put-attribute name="pageFooter" value="/WEB-INF/layouts/page_footer.jsp"></put-attribute>
  </definition>

  <definition name="login" extends="base">
    <put-attribute name="isAuthenticated" value="/WEB-INF/views/is_authenticated.jsp"></put-attribute>
    <put-attribute name="pageBody" value="/WEB-INF/views/login.jsp"></put-attribute>
  </definition>

  <definition name="home" extends="base">
    <put-attribute name="isAuthenticated" value=""></put-attribute>
    <put-attribute name="pageBody" value="/WEB-INF/views/home.jsp"></put-attribute>
  ...
</tiles-definitions>

这是page.jsp

<!DOCTYPE>
<html>
<head>
    <t:insertAttribute name="isAuthenticated"></t:insertAttribute>  
    ...
</head>

<body>
    <!-- Page Layout HTML -->
    <header id="pageHeader">
    <t:insertAttribute name="pageHeader"></t:insertAttribute>
    </header>

    <main id="pageBody">
    <t:insertAttribute name="pageBody"></t:insertAttribute>
    </main>
    ...
</body>
</html>

is_authenticated.jsp包含并呈现但它不起作用,只有当我将块放在page.jsp本身内时才会起作用,如你所见,它看起来不对,但是当它包含在另一个jsp文件中时它不起作用。

另一个解决方案,从登录控制器处理此问题,但这在我的情况下不可用,因为我没有使用任何控制器来处理登录过程。我该怎么办?自定义登录控制器比Spring中的默认登录控制器更安全吗?

UPDATE1

我试图使用spring的默认登录功能:

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    private UserDetailsService myUserService;

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {       
        auth
            .userDetailsService(myUserService);
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .antMatchers("/resources/**").permitAll()
                .anyRequest().authenticated()
                .and()
            .formLogin();

    }
}

但我发现登录成功后,用户仍然可以访问登录页面。所以我猜我需要在LoginController中有一个方法来完成这个。

spring spring-mvc spring-security
2个回答
0
投票

我想我找到了答案。

由于我将configure方法配置为:

@Override
protected void configure(HttpSecurity http) throws Exception {
    http
        .authorizeRequests()
            .antMatchers("/resources/**").permitAll()
            .anyRequest().authenticated()
            .and()
        .formLogin()
            .loginPage("/login")
            .permitAll()
            .and()
        .rememberMe()
            .alwaysRemember(true)
            .and()
        .logout()
            .permitAll();
}

我应该在我的addViewControllers实施中有WebMvcConfigurerAdapter。所以我试图删除这个方法,而是创建一个LoginController,它只有login()方法,用于处理重定向的GET请求,如果用户通过身份验证。

@Controller
public class LoginController {

    @RequestMapping(value="/login", method=GET)
    public String login(Principal principal) {
        return principal == null ?  "login" : "redirect:/"; 
    }
}

0
投票

我有同样的问题,我通过使用access()方法解决了它:

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


    http
            .authorizeRequests().antMatchers("/login", "/signup", "/")
            .access("hasRole('ANONYMOUS')")
            .antMatchers("/test").access("permitAll()")
            .antMatchers("/user/**").access("hasRole('ADMIN')")
            .anyRequest().authenticated()
            .antMatchers()
            .access("hasRole('USER')").anyRequest().fullyAuthenticated()
            .and()
            .formLogin()
            .loginPage("/login")
            .permitAll()
            .successHandler(loginSuccessHandler()).permitAll()
            .failureHandler(loginFailureHandler())
            .and()
            .logout()
            .permitAll()
            .logoutSuccessUrl("/");
}

private AuthenticationSuccessHandler loginSuccessHandler() {
    return (request, response, authentication) ->{
        response.sendRedirect("/home");
    };
}

private AuthenticationFailureHandler loginFailureHandler() {
    return (request, response, exception) -> {
        response.sendRedirect("/");
    };
}
© www.soinside.com 2019 - 2024. All rights reserved.