java表单的post方法不会在Spring安全登录验证中返回到控制器
我正在跟踪Jérôme Jaglale
的Spring 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;
}
}
数据库登录验证部分工作正常。
问题是表单的post请求没有返回到LoginController
。此外,注销操作不会返回到LoginConroller
中的/logout
映射方法
请帮助我找出这个例子中的错误所在?
谢谢
# 1 楼答案
一切都符合Spring Security的要求。您不需要实现
log in
或log out
操作,Spring Security正在代替您执行这些操作(您只需要通过http.formLogin()
、http.httpBasic()
、http.logout()
打开它们,默认情况下log out
操作已打开)Spring Security有一些过滤器,它们在点击控制器之前/之后根据请求执行/检查一些操作。根据filter pattern,每个这样的过滤器可以检查、阻塞、处理。。。你的要求。通过
http.formLogin()
或http.logout()
您是说spring security打开负责log in
或log out
用户的筛选器-因此spring security将打开相应的筛选器,如果有人点击POST /login
spring的安全筛选器,spring将拦截此类请求,登录用户并将其重定向到主页(或受保护的请求页面),这样的筛选器将不会通过log out
操作将请求传递给链中的父节点(到控制器)Spring Security为您提供了配置过滤器行为的选项,例如}将击中您的控制器,但这不是一个好方法,因为它实现了与spring security中相同的逻辑,当然还有新的bug。要禁用过滤器,只需执行
http.formLogin().loginPage("/logpage").usernameParameter("custom-username-parameter-name")
。当然,您可以关闭这样的过滤器,请求POST /login
{http.formLogin().disable(); http.logout().disable();