无法在 spring 启动安全性中登录我的自定义登录页面
Can't login to my custom login page in spring boot security
我的问题是:当我尝试在我的自定义登录页面上登录时,它再次将我重定向到登录页面(不管我输入的凭据是对还是错都没有关系)。我在调试中没有到达我的自定义 UserDetailService 也很奇怪,我认为这意味着 spring 甚至不检查用户的凭据。
我有自定义登录表单 /WEB-INF/jsp/login.jsp
:
...
<form name='loginForm' action="<c:url value='j_spring_security_check' />" method='POST'>
<table>
<tr>
<td>User:</td>
<td><input type='text' name='j_username' value=''></td>
</tr>
<tr>
<td>Password:</td>
<td><input type='password' name='j_password' /></td>
</tr>
<tr>
<td colspan='2'><input name="submit" type="submit"
value="submit" /></td>
</tr>
</table>
<input type="hidden" name="${_csrf.parameterName}"
value="${_csrf.token}" />
</form>
...
这是配置:
@Configuration
@EnableWebMvcSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UserDetailsService userDetailsService;
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests().antMatchers("/", "/welcome", "/resources/**").permitAll()
.anyRequest().authenticated().and()
.formLogin().loginPage("/login").failureUrl("/login?error").permitAll().and()
.logout().logoutUrl("/login?logout").permitAll();
}
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
这是在控制器内部:
@RequestMapping(value = "/login", method = RequestMethod.GET)
public ModelAndView login(
@RequestParam(value = "error", required = false) String error,
@RequestParam(value = "logout", required = false) String logout) {
ModelAndView model = new ModelAndView();
if (error != null) {
model.addObject("error", "Invalid username and password!");
}
if (logout != null) {
model.addObject("msg", "You've been logged out successfully.");
}
model.setViewName("login");
return model;
}
在src/main/resources/application.properties
我有:
spring.view.prefix: /WEB-INF/jsp/
spring.view.suffix: .jsp
那些 j_spring_security_check
、j_username
、j_password
名称都是旧的默认值(pre Spring Security 3.2)。
现在的默认值是:login
、username
和 password
。
我通过在 HttpSecurity 配置中禁用 CSRF 解决了类似的问题:
.csrf().disable()
如果您想启用 CSRF,则必须在所有形式中包含令牌
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/>
我的问题是:当我尝试在我的自定义登录页面上登录时,它再次将我重定向到登录页面(不管我输入的凭据是对还是错都没有关系)。我在调试中没有到达我的自定义 UserDetailService 也很奇怪,我认为这意味着 spring 甚至不检查用户的凭据。
我有自定义登录表单 /WEB-INF/jsp/login.jsp
:
...
<form name='loginForm' action="<c:url value='j_spring_security_check' />" method='POST'>
<table>
<tr>
<td>User:</td>
<td><input type='text' name='j_username' value=''></td>
</tr>
<tr>
<td>Password:</td>
<td><input type='password' name='j_password' /></td>
</tr>
<tr>
<td colspan='2'><input name="submit" type="submit"
value="submit" /></td>
</tr>
</table>
<input type="hidden" name="${_csrf.parameterName}"
value="${_csrf.token}" />
</form>
...
这是配置:
@Configuration
@EnableWebMvcSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UserDetailsService userDetailsService;
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests().antMatchers("/", "/welcome", "/resources/**").permitAll()
.anyRequest().authenticated().and()
.formLogin().loginPage("/login").failureUrl("/login?error").permitAll().and()
.logout().logoutUrl("/login?logout").permitAll();
}
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
这是在控制器内部:
@RequestMapping(value = "/login", method = RequestMethod.GET)
public ModelAndView login(
@RequestParam(value = "error", required = false) String error,
@RequestParam(value = "logout", required = false) String logout) {
ModelAndView model = new ModelAndView();
if (error != null) {
model.addObject("error", "Invalid username and password!");
}
if (logout != null) {
model.addObject("msg", "You've been logged out successfully.");
}
model.setViewName("login");
return model;
}
在src/main/resources/application.properties
我有:
spring.view.prefix: /WEB-INF/jsp/
spring.view.suffix: .jsp
那些 j_spring_security_check
、j_username
、j_password
名称都是旧的默认值(pre Spring Security 3.2)。
现在的默认值是:login
、username
和 password
。
我通过在 HttpSecurity 配置中禁用 CSRF 解决了类似的问题:
.csrf().disable()
如果您想启用 CSRF,则必须在所有形式中包含令牌
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/>