Spring Boot Security – 不使用Bearer令牌时获取403而不是401

huangapple go评论62阅读模式
英文:

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

{
    &quot;time&quot;: &quot;2023-05-29T18:06:23.381897147&quot;,
    &quot;httpStatus&quot;: &quot;UNAUTHORIZED&quot;,
    &quot;header&quot;: &quot;AUTH ERROR&quot;,
    &quot;isSuccess&quot;: false
}

I want to get this message shown below as it is a user not admin

{
    &quot;time&quot;: &quot;2023-05-29T18:06:23.381897147&quot;,
    &quot;httpStatus&quot;: &quot;FORBIDDEN&quot;,
    &quot;header&quot;: &quot;AUTH ERROR&quot;,
    &quot;isSuccess&quot;: 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&lt;Object&gt; 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&lt;&gt;(error, HttpStatus.FORBIDDEN);
    }

Here is the sample code snippets

@GetMapping
@PreAuthorize(&quot;hasAnyAuthority(&#39;ADMIN&#39;)&quot;)
public Response&lt;?&gt; 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 &quot;Unauthorized&quot;
     * 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, &quot;Unauthorized&quot;);
    }

}

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);

} 

.....

}

huangapple
  • 本文由 发表于 2023年6月1日 04:43:12
  • 转载请务必保留本文链接:https://go.coder-hub.com/76377135.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定