我正在关注 Jérôme Jaglale
的 Spring Cookbook
。在 Spring Security 部分中,我创建了一个小型登录示例来根据数据库对用户进行身份验证。
登录.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>
LoginController.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
映射方法。
请帮我找出这个例子中出了什么问题?
谢谢。
最佳答案
一切都按照 Spring Security 进行。您不需要实现log in
或log out
actions Spring Security 正在代替您执行此操作(您只需通过 http.formLogin()
、 http.httpBasic()
、 http.logout()
来打开它们,默认情况下 log out
操作已打开)。
Spring Security 具有过滤器,可以在点击 Controller 之前/之后根据请求执行/检查一些操作。根据filter pattern ,每个这样的过滤器都可以检查、阻止、处理……您的请求。通过http.formLogin()
或http.logout()
你是说 spring security 打开负责 log in
的过滤器或log out
用户 - 所以 spring security 将打开适当的过滤器,如果有人点击 POST /login
spring的安全过滤器将拦截此类请求,登录用户并将其重定向到主页(或 protected 请求页面),并且此类过滤器不会将您的请求父亲传递到链中(到您的 Controller ),与 log out
相同行动。
Spring Security 为您提供配置过滤器行为的选项。 http.formLogin().loginPage("/logpage").usernameParameter("custom-username-parameter-name")
。当然你可以关闭这样的过滤器和请求POST /login
POST /logout
会击中你的 Controller ,但这不是一个好方法,因为它实现的逻辑与 Spring Security 中已经存在的逻辑相同,当然还有新的错误。要禁用过滤器,只需执行 http.formLogin().disable(); http.logout().disable();
关于java - Spring Security 登录身份验证中表单 post 方法不会返回到 Controller ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54141184/