form表单提交和成功页面跳转必须是post请求
自定义的login.html中,form表单的method必须是post
<form action="/login" method="post">
用户名:<input type="text" name="username"/></br>
密码:<input type="password" name="password"/>
<input type="submit" value="登录"/>
</form>
跳转的成功页面可以写为一个controller
@RequestMapping("toMain")
public String tomain(){
return "redirect:main.html";
}
但是在Secrity的配置类中不能出现如下代码
//表单提交
http.formLogin()
//当发现是/login时认为是登录,必须和前端表单提交的地址一样
.loginProcessingUrl("/login")
//自定义的登录页面
.loginPage("/login.html")
//登录成功后跳转到static静态资源中的main.html
.successForwardUrl("Main.html");
这样也会出现302,我们只要将代码中最后一个定义改为successForwardUrl("/toMain"),post方式请求controller再重定向到main.html中即可
关闭csrf
在配置类中,最后一句代码必须关闭csrf,否则也无法实现功能
http.csrf().disable();
最后放上我自己成功实现自定义认证的代码,写了大量注释给大家参考
Controller
@Controller
public class LoginController {
@RequestMapping("toMain")
public String tomain(){
return "redirect:main.html";
}
}
SecurityConfig
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
//注册组件,UserDetailsServiceImpl需要用到BCryptPasswordEncoder
@Bean
public PasswordEncoder getPw(){
return new BCryptPasswordEncoder();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
//表单提交
http.formLogin()
//当发现是/login时认为是登录,必须和前端表单提交的地址一样,这样前端的/login请求就可以被SpringSecurity拦截,并且进UserDetailsServiceImpl中去认证
.loginProcessingUrl("/login")
//自定义的登录页面
.loginPage("/login.html")
//登录成功后跳转的url
.successForwardUrl("/toMain");
http.authorizeRequests().
//login。html不需要被认证,permitAll表示放行/login.html的请求,很像拦截器
antMatchers("/login.html").permitAll()
//任何请求都需要被认证,必须要登录后被访问
.anyRequest().authenticated();
//关闭csrf,否则页面无法访问
http.csrf().disable();
}
}
UserDetailsServiceImpl
@Service
public class UserDetailsServiceImpl implements UserDetailsService {
@Autowired
private PasswordEncoder pw;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
System.out.println("走登录逻辑了");
//模拟查询数据库,如果不存在,就抛出用户不存在的异常
if(!"admin".equals(username))
{
throw new UsernameNotFoundException("用户名不存在");
}
//把查询出来的密码(注册时已经加密过的密码)进行解析,或者直接把密码放入构造方法
String password=pw.encode("123");
return new User(username,password, AuthorityUtils.commaSeparatedStringToAuthorityList(
("admin,normal")
));
}
}
login.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>登录</title>
</head>
<body>
<form action="/login" method="post">
用户名:<input type="text" name="username"/></br>
密码:<input type="password" name="password"/>
<input type="submit" value="登录"/>
</form>
</body>
</html>
main.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
登录成功
</body>
</html>
代码目录