pom文件
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.4.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 实现对 Spring Security 的自动化配置 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
前后端分离,后端不干涉前端的跳转,采用json格式传递数据
WebSecurityConfigurerAdapter 配置
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private MyUserDetailService myUserDetailService;
@Autowired
private PasswordEncoder passwordEncoder;
@Autowired
private MyAuthenticationEntryPoint myAuthenticationEntryPoint;
@Autowired
private MyAuthenticationSuccessHandler myAuthenticationSuccessHandler;
@Autowired
private MyAuthenticationFailureHandler myAuthenticationFailureHandler;
@Autowired
private MyLogoutSuccessHandler myLogoutSuccessHandler;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(myUserDetailService).passwordEncoder(passwordEncoder);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
//退出
http.logout()
.logoutUrl("/logout")
.logoutSuccessHandler(myLogoutSuccessHandler);
// 未登录&无权限返回
http.exceptionHandling()
.authenticationEntryPoint(myAuthenticationEntryPoint);
// 登录
http.formLogin().loginProcessingUrl("/login")
.successHandler(myAuthenticationSuccessHandler)
.failureHandler(myAuthenticationFailureHandler)
.and().authorizeRequests()
.antMatchers("/","/login.html").permitAll()
.anyRequest().authenticated()
.and().csrf().disable();//关闭csrf防护
}
}
AuthenticationSuccessHandler
- 登录成功
@Component
public class MyAuthenticationSuccessHandler implements AuthenticationSuccessHandler {
@Autowired
private ObjectMapper objectMapper;
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
response.setContentType("application/json;charset=utf-8");
PrintWriter out = response.getWriter();
Map<String, Object> map = new HashMap<>();
map.put("status", 200);
map.put("msg", authentication.getPrincipal()); // 登录成功的对象
out.write(objectMapper.writeValueAsString(map));
out.flush();
out.close();
}
}
AuthenticationFailureHandler
- 登录失败
@Component
public class MyAuthenticationFailureHandler implements AuthenticationFailureHandler {
@Autowired
private ObjectMapper objectMapper;
@Override
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {
response.setContentType("application/json;charset=utf-8");
PrintWriter out = response.getWriter();
Map<String, Object> map = new HashMap<>();
map.put("status", 401);
if (exception instanceof LockedException) {
map.put("msg", "账户被锁定,登录失败!");
} else if (exception instanceof BadCredentialsException) {
map.put("msg", "用户名或密码输入错误,登录失败!");
} else if (exception instanceof DisabledException) {
map.put("msg", "账户被禁用,登录失败!");
} else if (exception instanceof AccountExpiredException) {
map.put("msg", "账户过期,登录失败!");
} else if (exception instanceof CredentialsContainer) {
map.put("msg", "密码过期,登录失败");
} else {
map.put("msg", "登录失败!");
}
out.write(objectMapper.writeValueAsString(map));
out.flush();
out.close();
}
}
LogoutSuccessHandler
- 登出成功
@Component
public class MyLogoutSuccessHandler implements LogoutSuccessHandler {
@Autowired
private ObjectMapper objectMapper;
@Override
public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
response.setContentType("application/json;charset=utf-8");
PrintWriter out = response.getWriter();
Map<String, Object> map = new HashMap<>();
map.put("status", 200);
map.put("msg", "注销登录成功!");
out.write(objectMapper.writeValueAsString(map));
out.flush();
out.close();
}
}
AuthenticationEntryPoint
- 认证失败
@Component
public class MyAuthenticationEntryPoint implements AuthenticationEntryPoint {
@Autowired
private ObjectMapper objectMapper;
@Override
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {
// response.sendError(HttpServletResponse.SC_UNAUTHORIZED,authException.getMessage());
response.setContentType("application/json;charset=utf-8");
response.setStatus(HttpServletResponse.SC_FORBIDDEN);
PrintWriter out = response.getWriter();
Map<String,Object> map = new HashMap<String,Object>();
map.put("code",403);
map.put("message","未登录或无权限");
out.write(objectMapper.writeValueAsString(map));
out.flush();
out.close();
}
}
UserDetailsService
@Service
public class MyUserDetailService implements UserDetailsService {
@Autowired
private PasswordEncoder passwordEncoder;
@Override
public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
return new User("user",passwordEncoder.encode("123"),new ArrayList<>());
}
}
PasswordEncoder
@Component
public class MyPasswordEncoder implements PasswordEncoder {
@Override
public String encode(CharSequence charSequence) {
return charSequence.toString();
}
@Override
public boolean matches(CharSequence charSequence, String s) {
return encode(charSequence).equals(s);
}
}