英文:
Spring Boot Security - Get 403 instead of 401 without using bearer token
问题
I have translated the provided content:
处理异常处理以在未使用 Postman 的身份验证令牌时获取 401 未经授权的结果时,我遇到了一个问题。
当我使用用户身份验证令牌发送请求到这个方法时,我会得到下面显示的响应消息:
{
"time": "2023-05-29T18:06:23.381897147",
"httpStatus": "UNAUTHORIZED",
"header": "AUTH ERROR",
"isSuccess": false
}
我想得到下面显示的消息,因为这是一个用户而不是管理员:
{
"time": "2023-05-29T18:06:23.381897147",
"httpStatus": "FORBIDDEN",
"header": "AUTH ERROR",
"isSuccess": false
}
此外,我不使用任何身份验证令牌,它总是返回 403 禁止而不是 401 未经授权。我在 Postman 的 `Authorization` 的 `type` 部分中选择了 `No Auth`,然后向端点发送了一个请求,`handleAccessDeniedError` 无法被调用。我认为使用了不同的异常。应该使用哪个异常?
以下是 GlobalExceptionHandler 的相关部分:
@ExceptionHandler({AccessDeniedException.class})
protected ResponseEntity<Object> handleAccessDeniedError(final AccessDeniedException exception) {
log.error(exception.getMessage(), exception);
Error error = Error.builder()
.httpStatus(HttpStatus.FORBIDDEN)
.header(Error.Header.AUTH_ERROR.getName())
.build();
return new ResponseEntity<>(error, HttpStatus.FORBIDDEN);
}
以下是示例代码片段:
@GetMapping
@PreAuthorize("hasAnyAuthority('ADMIN')")
public Response<?> getUsers(@RequestBody @Valid UserListRequest listRequest) {
}
我该如何解决这个问题?
Please note that the translation is provided based on your instructions to only return the translated parts and exclude code sections. If you need any further assistance, feel free to ask.
英文:
I have a problem to handle with the exception handling to get 401 Unauthorized result when I don't use bearer token through Postman.
When I use a user bearer token and send a request to this method, I get this response message shown below
{
"time": "2023-05-29T18:06:23.381897147",
"httpStatus": "UNAUTHORIZED",
"header": "AUTH ERROR",
"isSuccess": false
}
I want to get this message shown below as it is a user not admin
{
"time": "2023-05-29T18:06:23.381897147",
"httpStatus": "FORBIDDEN",
"header": "AUTH ERROR",
"isSuccess": false
}
Moreover, I don't use any bearer token,
It always returns 403 Forbidden instead of 401 Unauthorized.
I selected No Auth
from type
part in Authorization
in Postman
and then send a request to the endpoint, handleAccessDeniedError
cannot be called. I think a different exception is used for that.
Which exception should be used?
Here is the relevant part of GlobalExceptionHandler.
@ExceptionHandler({AccessDeniedException.class})
protected ResponseEntity<Object> handleAccessDeniedError(final AccessDeniedException exception) {
log.error(exception.getMessage(), exception);
Error error = Error.builder()
.httpStatus(HttpStatus.FORBIDDEN)
.header(Error.Header.AUTH_ERROR.getName())
.build();
return new ResponseEntity<>(error, HttpStatus.FORBIDDEN);
}
Here is the sample code snippets
@GetMapping
@PreAuthorize("hasAnyAuthority('ADMIN')")
public Response<?> getUsers(@RequestBody @Valid UserListRequest listRequest) {
}
How can I fix the issue?
答案1
得分: 0
这是下面显示的解决方案:
1 ) 定义 CustomAuthenticationEntryPoint
@Component
public class CustomAuthenticationEntryPoint implements AuthenticationEntryPoint {
/**
* 处理未经授权的请求,通过发送带有HTTP状态码 401(SC_UNAUTHORIZED)的“未经授权”响应。
*
* @param request 表示传入请求的 {@link HttpServletRequest} 对象
* @param response 用于发送响应的 {@link HttpServletResponse} 对象
* @param authException 在身份验证期间发生的 {@link AuthenticationException}
* @throws IOException 如果在发送响应时发生I/O错误
*/
@Override
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException {
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "未经授权");
}
}
2 ) 将 CustomAuthenticationEntryPoint
类注入到 SecurityConfiguration
@Configuration
@EnableWebSecurity
@EnableGlobalAuthentication
@EnableMethodSecurity
@RequiredArgsConstructor
class SecurityConfiguration {
....
@Bean
public SecurityFilterChain filterChain(HttpSecurity httpSecurity,
AuthenticationFilter authenticationFilter, CustomAuthenticationEntryPoint customAuthenticationEntryPoint){
httpSecurity.exceptionHandling()
.authenticationEntryPoint(customAuthenticationEntryPoint);
}
....
}
英文:
Here is the solution shown below
1 ) Define CustomAuthenticationEntryPoint
@Component
public class CustomAuthenticationEntryPoint implements AuthenticationEntryPoint {
/**
* Handles the unauthorized request by sending an "Unauthorized"
* response with the HTTP status code 401 (SC_UNAUTHORIZED).
*
* @param request the {@link HttpServletRequest} object representing the incoming request
* @param response the {@link HttpServletResponse} object used to send the response
* @param authException the {@link AuthenticationException} that occurred during authentication
* @throws IOException if an I/O error occurs while sending the response
*/
@Override
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException {
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized");
}
}
2 ) Inject CustomAuthenticationEntryPoint
class to SecurityConfiguration
@Configuration
@EnableWebSecurity
@EnableGlobalAuthentication
@EnableMethodSecurity
@RequiredArgsConstructor
class SecurityConfiguration {
....
@Bean
public SecurityFilterChain filterChain(HttpSecurity httpSecurity,
AuthenticationFilter authenticationFilter, CustomAuthenticationEntryPoint customAuthenticationEntryPoint){
httpSecurity.exceptionHandling()
.authenticationEntryPoint(customAuthenticationEntryPoint);
}
.....
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论