http.formLogin()
DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>登录title>
head>
<body>
<form class="login-page" action="/login" method="post">
<div class="form">
<h3>账户登录h3>
<input type="text" placeholder="用户名" name="username" required="required" />
<input type="password" placeholder="密码" name="password" required="required" />
<button type="submit">登录button>
div>
form>
body>
html>
@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
/**
* fromLogin():表单认证
* httpBasic():弹出框认证
* authorizeRequests():身份认证请求
* anyRequest():所有请求
* authenticated():身份认证
* loginPage():登录页面地址
* loginProcessingUrl():登录表单提交地址
* csrf().disable():关闭Spring Security的跨站请求伪造的功能
*/
http.csrf().disable()
.formLogin()
.loginPage("/login.html")
.loginProcessingUrl("/login")
.and()
.authorizeRequests()
.antMatchers("/login.html").permitAll()
.anyRequest()
.authenticated();
}
}
注意:SpringBoot项目集成Spring Security 5.3.4RELEASE后,默认情况crsf是开启的。每次请求会校验请求头中 X-CSRF-TOKEN 的值与内存中保存的是否一致,如果一致框架则认为登录页面是安全的,如果不一致,会报403。
@Controller
public class LoginController {
@RequestMapping("/login.html")
public String login(){
return "login";
}
@RequestMapping("/test")
@ResponseBody
public String test(){
return "test";
}
}
http.formLogin()
.usernameParameter("name") // 设置请求参数中,用户名参数名称。 默认username
.passwordParameter("pswd") // 设置请求参数中,密码参数名称。 默认password
.loginPage("/toLogin") // 当用户未登录的时候,跳转的登录页面地址是什么? 默认 /login
.loginProcessingUrl("/login") // 用户登录逻辑请求地址是什么。 默认是 /login
.failureForwardUrl("/failure"); // 登录失败后,请求转发的位置。Security请求转发使用Post请求。默认转发到:loginPage?error
.successForwardUrl("/toMain"); // 用户登录成功后,请求转发到的位置。Security请求转发使用POST请求。
http.formLogin()
.usernameParameter("name") // 设置请求参数中,用户名参数名称。 默认username
.passwordParameter("pswd") // 设置请求参数中,密码参数名称。 默认password
.loginPage("/toLogin") // 当用户未登录的时候,跳转的登录页面地址是什么? 默认 /login
.loginProcessingUrl("/login") // 用户登录逻辑请求地址是什么。 默认是 /login
.defaultSuccessUrl("/toMain",true); //用户登录成功后,响应重定向到的位置。GET请求。必须配置绝对地址。
.failureUrl("/failure"); // 登录失败后,重定向的位置。
@Slf4j
@Component
public class AuthenticationSuccessHandlerImpl implements AuthenticationSuccessHandler {
@Autowired
private ObjectMapper objectMapper;
@Override
public void onAuthenticationSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException {
log.info("登录成功");
httpServletResponse.setContentType("application/json;charset=utf-8");
httpServletResponse.getWriter().write(objectMapper.writeValueAsString(authentication));
}
}
@Slf4j
@Component
public class AuthenticationFailureHandlerImpl implements AuthenticationFailureHandler {
@Autowired
private ObjectMapper objectMapper;
@Override
public void onAuthenticationFailure(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException {
log.info("登录失败");
httpServletResponse.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
httpServletResponse.setContentType("application/json;charset=utf-8");
httpServletResponse.getWriter().write(objectMapper.writeValueAsString(e));
}
}
@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
/*@Resource
private PasswordEncoder passwordEncoder;
@Resource
private UserDetailsService userDetailsService;*/
@Autowired
private AuthenticationSuccessHandlerImpl authenticationSuccessHandler;
@Autowired
private AuthenticationFailureHandlerImpl authenticationFailureHandler;
@Override
protected void configure(HttpSecurity http) throws Exception {
/**
* fromLogin():表单认证
* httpBasic():弹出框认证
* authorizeRequests():身份认证请求
* anyRequest():所有请求
* authenticated():身份认证
* loginPage():登录页面地址
* loginProcessingUrl():登录表单提交地址
* csrf().disable():关闭Spring Security的跨站请求伪造的功能
*/
http.csrf().disable()
.formLogin()
.loginPage("/login")
.loginProcessingUrl("/auth/login")
.successHandler(authenticationSuccessHandler)
.failureHandler(authenticationFailureHandler)
.and()
.authorizeRequests()
.antMatchers("/login").permitAll()
.anyRequest()
.authenticated();
}
/**
* 认证管理器:
* 1、认证信息提供方式(用户名、密码、当前用户的资源权限)
* 2、可采用内存存储方式,也可能采用数据库方式等
*/
/*@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// 不再使用内存方式存储用户认证信息,而是动态从数据库中获取
auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder);
}*/
}
Spring Security默认的退出登录URL为/logout,退出登录后,Spring Security会做如下处理:
通过退出成功处理器来实现
@GetMapping("/signout/success")
public String signout() {
return "退出成功,请重新登录";
}
@Component
public class MyLogOutSuccessHandler implements LogoutSuccessHandler {
@Override
public void onLogoutSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException {
httpServletResponse.setStatus(HttpStatus.UNAUTHORIZED.value());
httpServletResponse.setContentType("application/json;charset=utf-8");
httpServletResponse.getWriter().write("退出成功,请重新登录");
}
}
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
/*@Resource
private PasswordEncoder passwordEncoder;
@Resource
private UserDetailsService userDetailsService;*/
@Autowired
private AuthenticationSuccessHandlerImpl authenticationSuccessHandler;
@Autowired
private AuthenticationFailureHandlerImpl authenticationFailureHandler;
@Resource
private MyLogOutSuccessHandler logOutSuccessHandler;
@Override
protected void configure(HttpSecurity http) throws Exception {
http.formLogin()
.successHandler(authenticationSuccessHandler)
.failureHandler(authenticationFailureHandler)
.and()
.logout()
//.logoutUrl("/signout")
.logoutSuccessUrl("/signout/success")
.deleteCookies("JSESSIONID")
.logoutSuccessHandler(logoutSuccessHandler)
.and()
.authorizeRequests()
.anyRequest()
.authenticated();
}
/**
* 认证管理器:
* 1、认证信息提供方式(用户名、密码、当前用户的资源权限)
* 2、可采用内存存储方式,也可能采用数据库方式等
*/
/*@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// 不再使用内存方式存储用户认证信息,而是动态从数据库中获取
auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder);
}*/
}