【问题标题】:How can I send my own response in spring?我如何在春季发送自己的回复?
【发布时间】:2020-02-12 13:28:04
【问题描述】:

我正在我的应用程序中使用 JWT 实现 Spring 安全性,并且每当进行未经授权的调用时,它都会返回以下响应

@Override
    public void commence(HttpServletRequest request,
                         HttpServletResponse response,
                         AuthenticationException authException) throws IOException {

        response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized");
    }

响应 json 如下所示

{
"timestamp": 1497832267379,
"status": 401,
"error": "Unauthorized",
"message": "Unauthorized",
"path": "/path"
}

我可以发送自己的自定义响应,例如:

{
 "code":401,
 "message":"The request is unauthorized"

}

感谢任何帮助

编辑

我将代码更新为以下格式:

 @Override
    public void commence(HttpServletRequest request,
                         HttpServletResponse response,
                         AuthenticationException authException) throws IOException {

                //response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized");

                Status unauthorizedEntry = new Status();
                unauthorizedEntry.setCode(401);
                unauthorizedEntry.setMessage("Unauthorized Entry");
                Map<String, Object> unauthorizedEntryResponse = new HashMap<>();
                unauthorizedEntryResponse.put("status", unauthorizedEntry);
                objectMapper.writeValue(response.getOutputStream(), unauthorizedEntry);
                response.flushBuffer();
    }

我的状态类如下:

public class Status {

    int code;
    String message;

    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        this.code = code;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}

现在我收到 200 响应,但屏幕上没有显示任何内容。它是完全空白的。任何帮助表示赞赏!

【问题讨论】:

  • 您应该能够使用自定义 AuthenticationFailureHandler 覆盖响应。
  • 目前我正在重写开始方法
  • 您的新代码实际上并未设置状态。你需要response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); 才能工作。您必须告诉 servlet 引擎状态发生了变化,否则它将默认为 200。

标签: java spring security jwt


【解决方案1】:

您可以尝试添加控制器建议

@RestController
@ControllerAdvice
public class ExceptionHandlerController {

    @ExceptionHandler(UsernameNotFoundException.class, DataAccessException.class)
    @ResponseStatus(HttpStatus.SC_UNAUTHORIZED)
    @ResponseBody ErrorInfo
    UnauthorizeExceptionInfo(HttpServletRequest req, Exception ex) {
        return new ErrorInfo(req.getRequestURL(), ex);
    } 
}

和ErrorInfo.class

@JsonIgnore
public final StringBuffer url;
public final String ex;

public ErrorInfo(StringBuffer stringBuffer, Exception ex) {
    this.url = stringBuffer;
    this.ex = ex.getLocalizedMessage();
}

当您抛出新的 UsernameNotFoundException 时,控制器将处理响应。

我想如果密码/电子邮件不匹配,则会在您的 @Override public loadUserByUsername 中从 CustomUserDetailsS​​ervice 抛出异常。

更多详情:https://spring.io/blog/2013/11/01/exception-handling-in-spring-mvc

【讨论】:

    【解决方案2】:

    这应该对你有用:

    @Autowired
    private ObjectMapper objectMapper;
    
    @Override
    public void commence(HttpServletRequest request,
                         HttpServletResponse response,
                         AuthenticationException authException) throws IOException {
        // notify client of response body content type
        response.addHeader("Content-Type", "application/json;charset=UTF-8");
        // set the response status code
        response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
        // set up the response body
        Status unauthorized = new Status(HttpServletResponse.SC_UNAUTHORIZED,
                                         "The request is unauthorized");
        // write the response body
        objectMapper.writeValue(response.getOutputStream(), unauthorized);
        // commit the response
        response.flushBuffer();
    }
    
    public class Status {
        private int code;
        private String message;
    
        public Status(int code, String message) {
            this.code = code;
            this.message = message;
        }
    
        public int getCode() {
            return code;
        }
    
        public String getMessage() {
            return message;
        }
    }
    

    请注意,您需要

    【讨论】:

    • 我在其他 REST 控制器中使用 jackson 作为 @RequestMapping(value="/path",produces={MediaType.APPLICATION_JSON_VALUE},method=RequestMethod.GET) 。但在这种情况下,它不是 REST 控制器,所以我如何使用 Jackson 发送 JSON 响应
    • 我添加了一个使用 Jackson 的示例。
    • 我尝试了示例,现在我得到了 200 响应,但没有显示任何内容。我更新了问题代码
    • 如果你得到一个 200 那么它没有达到这个代码。
    • 如果你不介意你能提供匹配的整个代码sn-p吗?因为当我尝试它时要么什么都不显示,要么显示相同的格式(默认401)
    猜你喜欢
    • 2019-03-31
    • 1970-01-01
    • 2015-05-23
    • 1970-01-01
    • 2018-01-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多