有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java表单的post方法不会在Spring安全登录验证中返回到控制器


我正在跟踪Jérôme JaglaleSpring Cookbook。在spring安全部分中,我创建了一个小的登录示例,以根据数据库对用户进行身份验证


登录。jsp

<%@ page language="java" contentType="text/html;  charset=UTF-8" pageEncoding="UTF-8"%>

    <body>
        <c:url var="loginUrl" value="/login" />
        <form action="${loginUrl}" method="post" >
            <input type="hidden" name="${_csrf.parameterName}"
                   value="${_csrf.token}"/>
            <c:if test="${param.error != null}">
                <p>
                    Invalid username and password.
                </p>
            </c:if>
            <p>
                <label for="username">Username</label>
                <input type="text" id="username" name="username"/>
            </p>
            <p>
                <label for="password">Password</label>
                <input type="password" id="password"
                       name="password"/>
            </p>
            <button type="submit">Log in</button>

        </form>
        <c:url var="logout" value="/logout" /> 
        <a href="${logout}">logout</a>
    </body>

登录控制器。java

@Controller
public class LoginController {

    @RequestMapping(value = "/login", method = RequestMethod.GET)
    public void login() {
    }

    @RequestMapping(value = "/login", method = RequestMethod.POST)
    public String processLogin() {
        return "homepage";
    }

    @RequestMapping(value = "/logout")
    public String logout() {
        return "out"; 
    }
}

SecurityConfig。java

@Configuration
@EnableWebMvcSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    public void configureUser(AuthenticationManagerBuilder auth) throws Exception {
      auth.jdbcAuthentication()
                .dataSource(dataSource())
                .usersByUsernameQuery("select username,password,enabled from users where username =  ?")
                .authoritiesByUsernameQuery("select username,authority from authorities where username =  ? ");
    }

    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests().anyRequest().authenticated();
        http.formLogin().loginPage("/login").permitAll();
        AntPathRequestMatcher pathRequestMatcher = new AntPathRequestMatcher("/logout");
        http.logout().logoutRequestMatcher(pathRequestMatcher);
    }

    @Bean
    public DataSource dataSource() {
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql://localhost:3306/customer");
        dataSource.setUsername("root");
        dataSource.setPassword("123");
        return dataSource;
    }

    @Bean
    public DataSourceTransactionManager transactionManager() {
        DataSourceTransactionManager transactionManager = new DataSourceTransactionManager();
        transactionManager.setDataSource(dataSource());
        return transactionManager;
    }
}

最后是我的项目的文件夹结构。 project folder sturcture

数据库登录验证部分工作正常。
问题是表单的post请求没有返回到LoginController。此外,注销操作不会返回到LoginConroller中的/logout映射方法


请帮助我找出这个例子中的错误所在?
谢谢


共 (1) 个答案

  1. # 1 楼答案

    一切都符合Spring Security的要求。您不需要实现log inlog out操作,Spring Security正在代替您执行这些操作(您只需要通过http.formLogin()http.httpBasic()http.logout()打开它们,默认情况下log out操作已打开)

    Spring Security有一些过滤器,它们在点击控制器之前/之后根据请求执行/检查一些操作。根据filter pattern,每个这样的过滤器可以检查、阻塞、处理。。。你的要求。通过http.formLogin()http.logout()您是说spring security打开负责log inlog out用户的筛选器-因此spring security将打开相应的筛选器,如果有人点击POST /loginspring的安全筛选器,spring将拦截此类请求,登录用户并将其重定向到主页(或受保护的请求页面),这样的筛选器将不会通过log out操作将请求传递给链中的父节点(到控制器)

    Spring Security为您提供了配置过滤器行为的选项,例如http.formLogin().loginPage("/logpage").usernameParameter("custom-username-parameter-name")。当然,您可以关闭这样的过滤器,请求POST /login{}将击中您的控制器,但这不是一个好方法,因为它实现了与spring security中相同的逻辑,当然还有新的bug。要禁用过滤器,只需执行http.formLogin().disable(); http.logout().disable();