简体   繁体   English

Spring Boot和Jersey,无法使ExceptionMapper工作

[英]Spring boot and Jersey, can't make ExceptionMapper work

I am using Spring boot + Spring Security + Jersey. 我正在使用Spring Boot + Spring Security + Jersey。

I am trying to do something always that an Unathorized error happens with an ExceptionMapper, but it doesn't seem to work. 我一直在尝试做一些事情,使ExceptionMapper发生Unathorized错误,但似乎不起作用。 However, other Mappers that I've done work perfectly. 但是,我做过的其他Mapper都能完美地工作。

This is my code: 这是我的代码:

Unauthorized Excepcion: 未经授权的例外:

package com.ulises.usersserver.rest.exceptionsmappers;

import com.ulises.usersserver.rest.dto.ErrorDTO;
import com.ulises.usersserver.rest.dto.ErrorDTOBuilder;

import javax.ws.rs.NotAuthorizedException;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.ext.ExceptionMapper;

import static com.ulises.usersserver.constants.Constants.REQUEST_ERROR_UNATHORIZED;

public class NotAuthorizedMapper implements ExceptionMapper<NotAuthorizedException> {
    @Override
    public Response toResponse(NotAuthorizedException e) {
        final ErrorDTO errorDTO = ErrorDTOBuilder.builder()
                .message(REQUEST_ERROR_UNATHORIZED)
                .build();
        return Response.status(Response.Status.UNAUTHORIZED)
                .type(MediaType.APPLICATION_JSON_TYPE)
                .entity(errorDTO)
                .build();
    }
}

Other custom mapper that works perfectly: 完美运行的其他自定义映射器:

package com.ulises.usersserver.rest.exceptionsmappers;

import com.ulises.usersserver.rest.dto.ErrorDTO;
import com.ulises.usersserver.rest.dto.ErrorDTOBuilder;
import com.ulises.usersserver.services.exceptions.UserNotFoundException;

import javax.ws.rs.core.Response;
import javax.ws.rs.ext.ExceptionMapper;

import static com.ulises.usersserver.constants.Constants.REQUEST_ERROR_USER_DOESNT_EXIST;

public class UserNotFoundExceptionMapper implements ExceptionMapper<UserNotFoundException> {
    @Override
    public Response toResponse(UserNotFoundException e) {
        final ErrorDTO errorDTO = ErrorDTOBuilder.builder()
                .message(REQUEST_ERROR_USER_DOESNT_EXIST)
                .build();
        return Response.status(Response.Status.NOT_FOUND).entity(errorDTO).build();
    }
}

They are of course registered in Jersey's config : 他们当然是在Jersey的配置中注册

@Bean
public ResourceConfig jerseyConfig() {
    final ResourceConfig resourceConfig = new ResourceConfig();
                      ...
    resourceConfig.register(NotFoundMapper.class);
    resourceConfig.register(NotAuthorizedMapper.class);
                      ...

    return resourceConfig;
}

I don't seem to be able to map other exceptions such as InternalServerErrorException (I managed to map this one by doing ExceptionMapper<Exception> , which doesn't look very correct to me. 我似乎无法映射其他异常,例如InternalServerErrorException (我通过做ExceptionMapper<Exception>设法映射了这个ExceptionMapper<Exception> ,这对我来说似乎不太正确。

Anyone knows why is this happening? 有人知道为什么会这样吗? I've checked all possible questions here and none of them solved this. 我在这里检查了所有可能的问题,但没有一个解决了这个问题。

Thanks in advance. 提前致谢。

Okay, it seems Jersey has no control over Spring Security's exceptions. 好的,泽西岛似乎无法控制Spring Security的异常。

The way to solve this (had to dig alot) is to override the method from AuthenticationEntryPoint that S-Security uses to return the 401 response if an user isn't authorized. 解决此问题的方法(必须进行大量挖掘)是覆盖AuthenticationEntryPoint中的方法,如果未授权用户,则S-Security会使用该方法返回401响应。

So I created the following class implementing that interface: 因此,我创建了以下实现该接口的类:

public class CustomEntryPoint implements AuthenticationEntryPoint {

    @Override
    public void commence(HttpServletRequest request,
                         HttpServletResponse response, AuthenticationException authException) throws IOException {
        JSONObject json = new JSONObject();
        json.put("Message", "You don't have access to view this section. Please, log in with an authorized account.");
        response.addHeader("Content-Type", "application/json");
        response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
        response.getWriter().println(json);
    }
}

And then just add this configuration to S-Security to use this class as entry point : 然后只需将此配置添加到S-Security即可使用此类作为entry point

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.httpBasic().authenticationEntryPoint(new CustomEntryPoint());
         ..... any other config you had .....
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM