spring-boot - 如何在 Spring Boot 休息过滤器方法中处理自定义异常?
问题描述
我想在 WebSecurityConfigurerAdapter 过滤器方法中添加一个自定义异常处理程序。
我正在使用自定义过滤器从当前请求中获取授权 API 密钥。然后将此 API 密钥与存储的 apikey 匹配,如果 API 密钥不匹配想要显示自定义异常说“无效的 API 密钥”或者如果未提供 API 密钥则“在授权标头中找不到 API 密钥”。
当 API 密钥不匹配时,如何将自定义通知作为 BadCredentialsException 抛出。
我的 SpringSecurityConfig 类
package com.nil.springjpa.security;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
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.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.access.ExceptionTranslationFilter;
import com.nil.springjpa.exceptions.BadCredentialsException;
@Configuration
@EnableWebSecurity
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private AuthenticationEntryPoint authEntryPoint;
@Override
protected void configure(HttpSecurity http) throws Exception {
System.out.println("1st");
/*
* http.csrf().disable().authorizeRequests() .anyRequest().authenticated()
* .and().httpBasic() .authenticationEntryPoint(authEntryPoint);
*/
PreAuthTokenHeaderFilter filter = new PreAuthTokenHeaderFilter("Authorization");
filter.setAuthenticationManager(new AuthenticationManager() {
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
String principal = (String) authentication.getPrincipal();
String authHeaderValue = "123xyz";
System.out.println("5th" + principal);
if (!authHeaderValue.equals(principal)) {
System.out.println("5th" + principal);
throw new BadCredentialsException("API Key not matched");
}
authentication.setAuthenticated(true);
return authentication;
}
});
http.csrf().disable().addFilter(filter)
.addFilterBefore(new ExceptionTranslationFilter(authEntryPoint), filter.getClass()).authorizeRequests()
.anyRequest().authenticated();
/*
* http.csrf().disable().authorizeRequests() .anyRequest().authenticated()
* .and().httpBasic() .authenticationEntryPoint(authEntryPoint);
*/
}
}
解决方案
使用ControllerAdvice
.
@ControllerAdvice
@RequestMapping(produces = "application/json")
public class CentralExceptionHandler {
@ExceptionHandler(CustomException.class)
@ResponseBody
protected void handleAccessDeniedException(CustomException ex, HttpServletResponse response) {
response.setHeader("Content-Type", "application/json");
response.setStatus(status);
response.getOutputStream().write("Something went wrong".getBytes());
}
}
CustomException
需要是运行时异常,并且可以从代码中的任何位置抛出。
推荐阅读
- python - 在 matplotlib 中对齐一行图
- php - 未登录php,请检查我的代码
- seaborn - 使用带有 kind="boxen" 的 seaborn catplot 时框的边缘颜色
- php - PHP:使用 count() 获取 1 而不是 0
- php - 用于检测单词出现异常的正则表达式
- openehr - OpenEHR 和血压
- angular - 在 Angular 中,这是在尝试关闭之前检查可观察订阅是否打开的有效方法吗?
- wordpress - Wordpress WebToffee 替代品
- php - 在 wordpress 中使用用户元和元值搜索所有用户
- sql - T-SQL:找出之前发生的序列值