自定义的JWT认证异常处理器类。实现了AuthenticationEntryPoint接口,用于处理认证失败的情况。
/**
* 自定义JWT认证异常处理器
*/
public class JwtAuthenticationEntryPoint implements AuthenticationEntryPoint {
//这是 commence方法的重写。当发生认证失败时,该方法会被调用。
@Override
public void commence(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException {
//设置响应的内容类型为JSON,并指定字符编码为UTF-8。
httpServletResponse.setContentType("application/json;charset=UTF-8");
//获取响应的输出流。
ServletOutputStream outputStream = httpServletResponse.getOutputStream();
//将认证失败的错误信息转换为JSON字符串,并通过输出流写入响应。
outputStream.write(JSONUtil.toJsonStr(R.error(HttpServletResponse.SC_UNAUTHORIZED,"认证失败,请登录!")).getBytes());
outputStream.flush();
//刷新输出流并关闭。
outputStream.close();
}
}
2.注入进配置文件
@Autowired
private JwtAuthenticationEntryPoint jwtAuthenticationEntryPoint;
3.添加异常处理器
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.cors() // 开启CORS功能(跨域)
.and()
.csrf().disable() // 关闭CSRF攻击防护
.formLogin() // 配置登录相关设置
.successHandler(loginSuccessHandler) // 自定义登录成功处理器
.failureHandler(loginFailureHandler) // 自定义登录失败处理器
// .and()
// .logout() // 配置注销设置(如果需要)
// .logoutSuccessHandler() // 自定义注销成功处理器(如果需要)
.and()
//session禁用配置
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS) // 禁用会话的创建(无状态)
.and()
.authorizeRequests()
.antMatchers(URL_WHITELIST).permitAll() // 白名单中的URL路径允许无需身份验证/permitAll放行所有
.anyRequest().authenticated() // 其他所有请求需要身份验证
//异常处理配置
.and()
.exceptionHandling()
.authenticationEntryPoint(jwtAuthenticationEntryPoint)
//自定义过滤器配置
.and()
.addFilter(jwtAuthenticationFilter());//添加filter
}
完整源码
JwtAuthenticationEntryPoint
package com.javaandvue.common.security;
import cn.hutool.json.JSONUtil;
import com.javaandvue.entity.R;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* 自定义JWT认证异常处理器
*/
public class JwtAuthenticationEntryPoint implements AuthenticationEntryPoint {
//这是 commence方法的重写。当发生认证失败时,该方法会被调用。
@Override
public void commence(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException {
//设置响应的内容类型为JSON,并指定字符编码为UTF-8。
httpServletResponse.setContentType("application/json;charset=UTF-8");
//获取响应的输出流。
ServletOutputStream outputStream = httpServletResponse.getOutputStream();
//将认证失败的错误信息转换为JSON字符串,并通过输出流写入响应。
outputStream.write(JSONUtil.toJsonStr(R.error(HttpServletResponse.SC_UNAUTHORIZED,"认证失败,请登录!")).getBytes());
outputStream.flush();
//刷新输出流并关闭。
outputStream.close();
}
}
SecurityConfig
package com.javaandvue.config;
import com.javaandvue.common.security.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private LoginSuccessHandler loginSuccessHandler;
@Autowired
private LoginFailureHandler loginFailureHandler;
@Autowired
private MyUserDetailServiceImpl myUserDetailService;
@Autowired
private JwtAuthenticationEntryPoint jwtAuthenticationEntryPoint;
// 定义白名单URL路径数组
private static final String URL_WHITELIST[] = {
"/login",
"/logout",
"/captcha",
"/password",
"/image/**"
};
@Bean
JwtAuthenticationFilter jwtAuthenticationFilter() throws Exception {
JwtAuthenticationFilter jwtAuthenticationFilter=new JwtAuthenticationFilter(authenticationManager());
return jwtAuthenticationFilter;
}
//默认密码加密配置
@Bean
BCryptPasswordEncoder bCryptPasswordEncoder(){
return new BCryptPasswordEncoder();
}
/**
* 配置应用程序的安全规则
* 开启跨域资源共享(CORS)功能,并关闭跨站请求伪造(CSRF)攻击防护
* 配置登录相关设置
* 禁用会话(session)的创建
* 配置拦截规则
* @param http HttpSecurity对象,用于配置应用程序的安全规则
* @throws Exception 配置过程中可能抛出的异常
*/
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.cors() // 开启CORS功能(跨域)
.and()
.csrf().disable() // 关闭CSRF攻击防护
.formLogin() // 配置登录相关设置
.successHandler(loginSuccessHandler) // 自定义登录成功处理器
.failureHandler(loginFailureHandler) // 自定义登录失败处理器
// .and()
// .logout() // 配置注销设置(如果需要)
// .logoutSuccessHandler() // 自定义注销成功处理器(如果需要)
.and()
//session禁用配置
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS) // 禁用会话的创建(无状态)
.and()
.authorizeRequests()
.antMatchers(URL_WHITELIST).permitAll() // 白名单中的URL路径允许无需身份验证/permitAll放行所有
.anyRequest().authenticated() // 其他所有请求需要身份验证
//异常处理配置
.and()
.exceptionHandling()
.authenticationEntryPoint(jwtAuthenticationEntryPoint)
//自定义过滤器配置
.and()
.addFilter(jwtAuthenticationFilter());//添加filter
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(myUserDetailService);
}
}