java - Spring REST API,拦截 401 需要完全身份验证

标签 java spring spring-mvc

我有一个 Spring REST API,它提供了许多端点;它们需要使用基本 http 或 JWT token 进行身份验证。我还使用 @ControllerAdvice,如下所示:

@ControllerAdvice
public class CustomResponseEntityExceptionHandler extends ResponseEntityExceptionHandler {
    private Logger log = LogManager.getLogger();

    @Inject
    private MessageSource messageSource;


    @ExceptionHandler(value = { RuntimeException.class, Exception.class })
    public ResponseEntity<ErrorMessage> exceptionHandler(RuntimeException ex, Locale locale) {          
        ErrorMessage error = new ErrorMessage(ApiExceptionCodes.GENERIC_INTERNAL_SERVER_ERROR, messageSource.getMessage(
                ApiExceptionCodes.GENERIC_INTERNAL_SERVER_ERROR + "", null, locale));           
        return new ResponseEntity<ErrorMessage>(error, HttpStatus.INTERNAL_SERVER_ERROR);
    }

    @ExceptionHandler(value = { ApiException.class })
    public ResponseEntity<ErrorMessage> handlerApiException(ApiException ex, Locale locale) {           
        ErrorMessage error = new ErrorMessage(ex.getCode(), ex.getMessage());
        return new ResponseEntity<ErrorMessage>(error, HttpStatus.INTERNAL_SERVER_ERROR);
    }

    @ExceptionHandler(value = { ApiRuntimeException.class })
    public ResponseEntity<ErrorMessage> handlerApiRuntimeException(ApiRuntimeException ex, Locale locale) {
        ErrorMessage error = new ErrorMessage(ex.getCode(), messageSource.getMessage(ex.getCode() + "", null, locale));
        return new ResponseEntity<ErrorMessage>(error, HttpStatus.INTERNAL_SERVER_ERROR);
    }

我的端点之一是:

@ApiOperation(value = "Return Spring Principal object.", notes = "Return Spring Principal object. It contains several details of the logged-in user.")
@RequestMapping(method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
@PreAuthorize("hasAnyRole('B2B','API')")
public ResponseEntity<?> user(Principal user) {
    return ResponseEntity.ok(user);
}

简而言之,我在我的应用程序中捕获了全局异常。除了当我尝试调用端点而不进行身份验证时,一切都工作正常。在这种情况下,异常不会被我的 @ControllerAdvice 拦截,并且用户会在响应中看到此正文:

  <html>
    <head>
        <meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
        <title>Error 401 Full authentication is required to access this resource</title>
    </head>
    <body>
        <h2>HTTP ERROR 401</h2>
        <p>Problem accessing /aci/api/v1/tickets/chart. Reason:

            <pre>    Full authentication is required to access this resource</pre>
        </p>
        <hr>
        <a href="http://eclipse.org/jetty">Powered by Jetty:// 9.3.9.v20160517</a>
        <hr/>
    </body>
</html>

我如何在全局范围内拦截此异常?请建议我这样做的最佳实践。

最佳答案

对于基本安全性,您可以扩展 org.springframework.security.web.authentication.www.BasicAuthenticationEntryPoint 并覆盖开始方法以返回自定义响应,例如:

 @Override
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {
    response.addHeader("your_custom_header", "some_value");
    response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
    PrintWriter writer = response.getWriter();
    writer.println("HTTP Status 401 - " + authException.getMessage());
}

关于java - Spring REST API,拦截 401 需要完全身份验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43398792/

相关文章:

java - Tomcat 在 INFOS : Initializing Spring root WebApplicationContext after migration to Spring 3. 2.3.RELEASE 之后不继续

java - SpringBatch - javaconfig 与 xml

java - Java 中扩展名为 .00x 的文件合并

Java Spring 散列和验证密码

java - 是否有使用带注释的方法参数启用 JSR 303 Bean 验证的标准方法

spring-mvc - 在 SpringBootTest 中测试 COR

java - SecurityContextLogoutHandler 的 clearAuthentication 如何不是线程安全的?

Java Applet 图形大小调整

java - JAVA和PYTHON中的SHA256加密产生不同的结果

java - 移动<mvc :annotation-driven/>: no declaration can be found for element 'mvc:annotation-driven' 后出错