我正在关注Jérôme Jaglale
的{{1}}。在春季安全性部分中,我创建了一个小的登录示例,以根据数据库对用户进行身份验证。
login.jsp
Spring Cookbook
LoginController.java
<%@ 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>
SecurityConfig.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";
}
}
数据库登录身份验证部分运行正常很好。
问题在于表单的发布请求不会返回到@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;
}
}
。同样,注销操作不会返回到LoginController
中的/logout
映射方法。
请帮助我找出此示例出了什么问题?
谢谢。
答案 0 :(得分:1)
一切都与Spring Security兼容。您不需要执行log in
或log out
操作,Spring Security不用您执行(您只需通过http.formLogin()
,http.httpBasic()
,{{ 1}},默认情况下http.logout()
操作处于打开状态。
Spring Security的过滤器可以在命中控制器之前/之后根据请求进行/检查某些操作。根据{{3}},每个此类过滤器都可以检查,阻止,处理...您的请求。通过log out
或http.formLogin()
,您说的是弹簧安全性来打开负责http.logout()
或log in
用户的过滤器-这样,弹簧安全性将打开适当的过滤器并如果有人点击了log out
弹簧,则安全过滤器将拦截该请求,登录用户并将其重定向到主页(或受保护的请求页面),并且该过滤器不会将您的请求父亲传递给链(向您的控制器) )与POST /login
操作相同。
Spring Security为您提供了配置ex过滤器行为的选项。 log out
。当然,您可以关闭此类过滤器,并且请求http.formLogin().loginPage("/logpage").usernameParameter("custom-username-parameter-name")
POST /login
将命中您的控制器,但这不是一个好方法,因为它实现了与Spring安全性相同的逻辑,当然还有新的错误。 。要禁用过滤器,只需执行POST /logout