首页 技术 正文
技术 2022年11月6日
0 收藏 563 点赞 498 浏览 6183 个字

最近在开发一个项目 前后台分离的 使用 spring boot + spring security + jwt 实现用户登录权限控制等操作。但是 在用户登录的时候,怎么处理spring  security  抛出的异常呢?使用了@RestControllerAdvice 和@ExceptionHandler 不能处理Spring Security抛出的异常,如 UsernameNotFoundException等,我想要友好的给前端返回提示信息  如,用户名不存在之类的。 贴上我的代码:

JWT 验证类 : 重写了spring security UsernamaPasswordAuthenticationFilter

public class JWTAuthenticationFilter extends UsernamePasswordAuthenticationFilter {    private AuthenticationManager authenticationManager;    private RedisServiceImpl redisService;    private AppConfig appConfig;    public JWTAuthenticationFilter(AuthenticationManager authenticationManager, RedisServiceImpl redisService, AppConfig appConfig) {
this.authenticationManager = authenticationManager;
this.redisService = redisService;
this.appConfig = appConfig;
} /**
* @param req
* @param res
* @return
* @throws AuthenticationException
* @// TODO: 2018/4/12 接受并解析用户凭证
*/
@Override
public Authentication attemptAuthentication(HttpServletRequest req, HttpServletResponse res) throws AuthenticationException {
try {
AuthEntity creds = new ObjectMapper()
.readValue(req.getInputStream(), AuthEntity.class); //验证码校验
if (appConfig.getCaptchaEnabled()) { //如果开启了验证码登录校验功能
if (StringUtils.isBlank(creds.getCaptcha())) {
logger.error("验证码为空");
throw new WelendException(StatusCode.CAPTCHA_EMPTY);
}
if (!redisService.exists(appConfig.getCaptchaKey())) {
logger.error("验证码已失效");
throw new WelendException(StatusCode.CAPTCHA_OVERDUE);
}
String captcha = (String) redisService.get(appConfig.getCaptchaKey());
if (!creds.getCaptcha().equals(captcha)) {
logger.error("验证码不正确");
throw new WelendException(StatusCode.CAPTCHA_ERROR);
}
}
return authenticationManager.authenticate(
new UsernamePasswordAuthenticationToken(
creds.getUsername(),
creds.getPassword(),
new ArrayList<>())
);
} catch (IOException e) {
logger.error("Client's variables can't be parsed by com.fasterxml.jackson.core.JsonParse");
throw new WelendException(StatusCode.SERVER_ERROR);
} }
}

验证用户名 密码:

public class CustomAuthenticationProvider implements AuthenticationProvider {    private UserDetailsServiceImpl userDetailsService;    private BCryptPasswordEncoder bCryptPasswordEncoder;    public CustomAuthenticationProvider(UserDetailsServiceImpl userDetailsService, BCryptPasswordEncoder bCryptPasswordEncoder) {
this.userDetailsService = userDetailsService;
this.bCryptPasswordEncoder = bCryptPasswordEncoder;
} @Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
// 获取认证的用户名 & 密码
String name = authentication.getName();
String password = authentication.getCredentials().toString();
// 认证逻辑
JWTUserDetails userDetails = userDetailsService.loadUserByUsername(name);
if (null != userDetails) {
Boolean verifyPwd = bCryptPasswordEncoder.matches(password,userDetails.getLoginPwd());
if (verifyPwd) {
// 生成令牌 这里令牌里面存入了:userDetails,password,authorities(权限列表)
Authentication auth = new UsernamePasswordAuthenticationToken(userDetails, password, userDetails.getAuthorities());
return auth;
} else {
throw new BadCredentialsException("username or password wrong!");
}
} else {
throw new UsernameNotFoundException("can not find this account");
}
} /**
* 是否可以提供输入类型的认证服务
* @param authentication
* @return
*/
@Override
public boolean supports(Class<?> authentication) {
return authentication.equals(UsernamePasswordAuthenticationToken.class);
}}

全局异常处理

@RestControllerAdvice
public class GlobalExceptionHandler {
private Logger logger = LoggerFactory.getLogger(getClass()); /**
* @param request
* @param exception
* @return
* @throws Exception
* @// TODO: 2018/4/25 参数未通过验证异常
*/
@ExceptionHandler(value = MethodArgumentNotValidException.class)
public Object MethodArgumentNotValidHandler(HttpServletRequest request, MethodArgumentNotValidException exception) throws Exception {
//按需重新封装需要返回的错误信息
//List<StatusCode> invalidArguments = new ArrayList<>();
//解析原错误信息,封装后返回,此处返回非法的字段名称,原始值,错误信息
ResultObject resultMsg = ResultObject.dataMsg(exception.getBindingResult().getFieldError().getDefaultMessage(), StatusCode.VARIABLE_ERROR);
return resultMsg;
} /**
* @param request
* @param exception
* @return
* @throws Exception
* @// TODO: 2018/4/25 无法解析参数异常
*/
@ExceptionHandler(value = HttpMessageNotReadableException.class)
public Object HttpMessageNotReadableHandler(HttpServletRequest request, HttpMessageNotReadableException exception) throws Exception {
logger.info(exception.getMessage());
ResultObject resultMsg = ResultObject.dataMsg("参数无法正常解析", StatusCode.VARIABLE_ERROR);
return resultMsg;
} /**
* @param exception
* @return
* @throws Exception
* @// TODO: 2018/4/25 处理token 过期异常
*/
@ExceptionHandler(value = ExpiredJwtException.class)
public Object ExpiredJwtExceptionHandler(ExpiredJwtException exception) throws Exception {
logger.info(exception.getMessage());
ResultObject resultMsg = ResultObject.dataMsg("登录已过期!", StatusCode.FORBIDDEN);
return resultMsg;
} /**
* @param request
* @param exception
* @return
* @throws Exception
* @// TODO: 2018/4/25 方法访问权限不足异常
*/
@ExceptionHandler(value = AccessDeniedException.class)
public Object AccessDeniedExceptionHandler(AccessDeniedException exception) throws Exception {
logger.info(exception.getMessage());
ResultObject resultMsg = ResultObject.dataMsg("权限不足!", StatusCode.FORBIDDEN);
return resultMsg;
} @ExceptionHandler(value = NoHandlerFoundException.class)
public Object NoHandlerFoundExceptionHandler(NoHandlerFoundException exception) throws Exception {
logger.info(exception.getMessage());
return ResultObject.dataMsg("链接不存在", StatusCode.NOT_FOUND);
}
/**
* 处理自定义异常
*/
@ExceptionHandler(value = WelendException.class)
public Object WelendExceptionHandler(WelendException e) {
ResultObject r = new ResultObject();
r.setStatus(String.valueOf(e.getCode()));
r.setMessage(e.getMessage());
return r;
} @ExceptionHandler(value = AuthenticationException.class)
public Object AuthenticationExceptionHandler(AuthenticationException e) {
return ResultObject.dataMsg(e.getLocalizedMessage(),StatusCode.FORBIDDEN);
} @ExceptionHandler(value = DuplicateKeyException.class)
public Object DuplicateKeyExceptionHandler(DuplicateKeyException e) throws Exception {
logger.error(e.getMessage(), e);
return ResultObject.codeMsg(StatusCode.EXISTED);
} @ExceptionHandler(value = BadCredentialsException.class)
public Object BadCredentialsExceptionHandler(BadCredentialsException e) throws Exception {
logger.error(e.getMessage(), e);
return ResultObject.codeMsg(StatusCode.AUTH_ERROR);
} @ExceptionHandler(value = Exception.class)
public Object ExceptionHandler(Exception e) throws Exception {
logger.error(e.getMessage(), e);
return ResultObject.codeMsg(StatusCode.FAILED);
}
}

登录时输入错误的用户名

Spring boot 前后台分离项目 怎么处理spring security 抛出的异常

控制台直接打印信息了, 并没有经过ExceptionHandler 处理。

如上所示,我想在全局异常类中 处理spring security抛出异常, 以便返回友好的提示信息。有什么解决办法么?

相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,078
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,553
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,402
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,177
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:7,814
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:4,898