Return 来自 Rest API 的自定义 Spring 安全消息
Return custom Spring security message from Rest API
我想为禁止错误创建自定义错误消息。我试过这个:
Spring 安全配置:
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private JwtTokenProvider jwtTokenProvider;
@Override
protected void configure(HttpSecurity http) throws Exception {
// Disable CSRF (cross site request forgery)
http.csrf().disable();
// No session will be created or used by spring security
http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
// Entry points
http.authorizeRequests()//
.antMatchers("/users/signin").permitAll()//
.antMatchers("/users/signup").permitAll()//
.antMatchers("/h2-console/**/**").permitAll()
// Disallow everything else..
.anyRequest().authenticated();
// If a user try to access a resource without having enough permissions
http.exceptionHandling().accessDeniedHandler(accessDeniedHandler());
// Apply JWT
http.apply(new JwtTokenFilterConfigurer(jwtTokenProvider));
// Optional, if you want to test the API from a browser
// http.httpBasic();
}
@Override
public void configure(WebSecurity web) throws Exception {
// Allow swagger to be accessed without authentication
web.ignoring().antMatchers("/v2/api-docs")//
.antMatchers("/swagger-resources/**")//
.antMatchers("/swagger-ui.html")//
.antMatchers("/configuration/**")//
.antMatchers("/webjars/**")//
.antMatchers("/public")
// Un-secure H2 Database (for testing purposes, H2 console shouldn't be unprotected in production)
.and()
.ignoring()
.antMatchers("/h2-console/**/**");
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder(12);
}
// @Override
// @Bean
// public AuthenticationManager authenticationManagerBean() throws Exception {
// return super.authenticationManagerBean();
// }
@Bean
public AccessDeniedHandler accessDeniedHandler() {
return new CustomAccessDeniedHandler();
}
}
自定义处理程序:
public class CustomAccessDeniedHandler implements AccessDeniedHandler {
public static final Logger LOG = LoggerFactory.getLogger(CustomAccessDeniedHandler.class);
@Override
public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException exc) throws IOException, ServletException {
response.setStatus(HttpStatus.UNAUTHORIZED.value());
String jsonPayload = "{\"messffffffage\" : \"%s\", \"timestamp\" : \"%s\" }";
response.getOutputStream().println(String.format(jsonPayload, exc.getMessage(), Calendar.getInstance().getTime()));
}
}
但我收到默认错误消息:
{
"timestamp": "2020-06-09T21:23:32.528+00:00",
"status": 403,
"error": "Forbidden",
"message": "",
"path": "/engine/users/request"
}
你知道我如何正确实现处理程序吗?
我最近遇到了类似的问题,我认为你可以像这样实现你想要的:
在您的安全配置中添加:
@Override
protected void configure(HttpSecurity http) throws Exception
{
...
http.exceptionHandling().accessDeniedHandler(accessDeniedHandler())
.authenticationEntryPoint(authenticationEntryPoint())
...
}
/**
* @return Custom {@link AuthenticationEntryPoint} to send suitable response in the event of a
* failed authentication attempt.
*/
@Bean
public AuthenticationEntryPoint authenticationEntryPoint()
{
return new CustomAuthenticationEntryPoint();
}
创建您的 CustomAuthenticationEntryPoint class 并写出任何自定义消息:
public class CustomAuthenticationEntryPoint implements AuthenticationEntryPoint {
@Override
public void commence(HttpServletRequest request, HttpServletResponse response,
AuthenticationException authException) throws IOException {
response.setStatus(HttpStatus.UNAUTHORIZED.value());
Map<String, Object> data = new HashMap<>();
data.put("message", "Your message");
data.put("timestamp",LocalDateTime.now());
OutputStream out = response.getOutputStream();
ObjectMapper mapper = new ObjectMapper();
mapper.writeValue(out, data);
out.flush();
}
}
希望对您有所帮助!
只需添加AuthenticationEntryPoint
@Component
public class JwtAuthenticationEntryPoint implements AuthenticationEntryPoint {
@Override
public void commence(HttpServletRequest request, HttpServletResponse response,
AuthenticationException authException) throws IOException {
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized");
}
}
并在配置class
中进行配置
@Autowired
private JwtAuthenticationEntryPoint jwtAuthenticationEntryPoint;
@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity.csrf().disable()
.authorizeRequests().antMatchers("/authenticate").permitAll()
.anyRequest().authenticated()
.and().
exceptionHandling().authenticationEntryPoint(jwtAuthenticationEntryPoint)
.and().sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
httpSecurity.addFilterBefore(requestFilter, UsernamePasswordAuthenticationFilter.class);
}
您可以在 JwtAuthenticationEntryPoint
中编写自定义消息(名称由用户定义)class 实现 AuthenticationEntryPoint
只需在 response.sendError(...)
方法中添加您的自定义消息。
我想为禁止错误创建自定义错误消息。我试过这个:
Spring 安全配置:
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private JwtTokenProvider jwtTokenProvider;
@Override
protected void configure(HttpSecurity http) throws Exception {
// Disable CSRF (cross site request forgery)
http.csrf().disable();
// No session will be created or used by spring security
http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
// Entry points
http.authorizeRequests()//
.antMatchers("/users/signin").permitAll()//
.antMatchers("/users/signup").permitAll()//
.antMatchers("/h2-console/**/**").permitAll()
// Disallow everything else..
.anyRequest().authenticated();
// If a user try to access a resource without having enough permissions
http.exceptionHandling().accessDeniedHandler(accessDeniedHandler());
// Apply JWT
http.apply(new JwtTokenFilterConfigurer(jwtTokenProvider));
// Optional, if you want to test the API from a browser
// http.httpBasic();
}
@Override
public void configure(WebSecurity web) throws Exception {
// Allow swagger to be accessed without authentication
web.ignoring().antMatchers("/v2/api-docs")//
.antMatchers("/swagger-resources/**")//
.antMatchers("/swagger-ui.html")//
.antMatchers("/configuration/**")//
.antMatchers("/webjars/**")//
.antMatchers("/public")
// Un-secure H2 Database (for testing purposes, H2 console shouldn't be unprotected in production)
.and()
.ignoring()
.antMatchers("/h2-console/**/**");
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder(12);
}
// @Override
// @Bean
// public AuthenticationManager authenticationManagerBean() throws Exception {
// return super.authenticationManagerBean();
// }
@Bean
public AccessDeniedHandler accessDeniedHandler() {
return new CustomAccessDeniedHandler();
}
}
自定义处理程序:
public class CustomAccessDeniedHandler implements AccessDeniedHandler {
public static final Logger LOG = LoggerFactory.getLogger(CustomAccessDeniedHandler.class);
@Override
public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException exc) throws IOException, ServletException {
response.setStatus(HttpStatus.UNAUTHORIZED.value());
String jsonPayload = "{\"messffffffage\" : \"%s\", \"timestamp\" : \"%s\" }";
response.getOutputStream().println(String.format(jsonPayload, exc.getMessage(), Calendar.getInstance().getTime()));
}
}
但我收到默认错误消息:
{
"timestamp": "2020-06-09T21:23:32.528+00:00",
"status": 403,
"error": "Forbidden",
"message": "",
"path": "/engine/users/request"
}
你知道我如何正确实现处理程序吗?
我最近遇到了类似的问题,我认为你可以像这样实现你想要的:
在您的安全配置中添加:
@Override
protected void configure(HttpSecurity http) throws Exception
{
...
http.exceptionHandling().accessDeniedHandler(accessDeniedHandler())
.authenticationEntryPoint(authenticationEntryPoint())
...
}
/**
* @return Custom {@link AuthenticationEntryPoint} to send suitable response in the event of a
* failed authentication attempt.
*/
@Bean
public AuthenticationEntryPoint authenticationEntryPoint()
{
return new CustomAuthenticationEntryPoint();
}
创建您的 CustomAuthenticationEntryPoint class 并写出任何自定义消息:
public class CustomAuthenticationEntryPoint implements AuthenticationEntryPoint {
@Override
public void commence(HttpServletRequest request, HttpServletResponse response,
AuthenticationException authException) throws IOException {
response.setStatus(HttpStatus.UNAUTHORIZED.value());
Map<String, Object> data = new HashMap<>();
data.put("message", "Your message");
data.put("timestamp",LocalDateTime.now());
OutputStream out = response.getOutputStream();
ObjectMapper mapper = new ObjectMapper();
mapper.writeValue(out, data);
out.flush();
}
}
希望对您有所帮助!
只需添加AuthenticationEntryPoint
@Component
public class JwtAuthenticationEntryPoint implements AuthenticationEntryPoint {
@Override
public void commence(HttpServletRequest request, HttpServletResponse response,
AuthenticationException authException) throws IOException {
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized");
}
}
并在配置class
中进行配置@Autowired
private JwtAuthenticationEntryPoint jwtAuthenticationEntryPoint;
@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity.csrf().disable()
.authorizeRequests().antMatchers("/authenticate").permitAll()
.anyRequest().authenticated()
.and().
exceptionHandling().authenticationEntryPoint(jwtAuthenticationEntryPoint)
.and().sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
httpSecurity.addFilterBefore(requestFilter, UsernamePasswordAuthenticationFilter.class);
}
您可以在 JwtAuthenticationEntryPoint
中编写自定义消息(名称由用户定义)class 实现 AuthenticationEntryPoint
只需在 response.sendError(...)
方法中添加您的自定义消息。