Создание фасада с помощью spring, который вызывает другой сервер и возвращает его ответ

Для приложения мне нужно создать фасад безопасности в Spring 4.x.

Этот тонкий слой должен принимать любой запрос от нашего мобильного приложения и выполнять проверку безопасности предоставленного токена (с помощью openId и Oauth).

После успешной проверки запрос необходимо перенаправить серверному приложению, которому не нужно знать о механизме токена безопасности.

Таким образом, поток будет примерно таким: security_facade_url/path/of/the/request

С заголовком, который указывает серверную часть для вызова после успешной проверки токена.

После успешной проверки фасад безопасности отправляет запрос на серверный URL-адрес backend_application_url/path/of/the/request.

Фасад не должен иметь контроллера, который сопоставляется с любым возможным путем запроса, но должен вызывать запрос на правильном внутреннем сервере на основе значения в заголовке запроса. Затем верните этот ответ пользователю.

Пока у меня есть реализация HandlerInterceptor. Этот перехватчик работает, однако я не очень доволен тем, как мне нужно избежать afterCompletion, выбрасывая исключение в методе postHandle. Если я не выдаю ошибку, страница ошибки по умолчанию добавляется к правильному ответу на этапе afterCompletion.

Это мой код до сих пор:

public class RequestProcessingInterceptor implements HandlerInterceptor {    
private final Logger log = LoggerFactory.getLogger(RequestProcessingInterceptor.class);

public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
    log.info("Doing some security stuff now ...");

    log.warn("... security ok ... since I am not really checking stuff");
    return true;
}

public void postHandle(HttpServletRequest request,
                       HttpServletResponse response, Object handler,
                       ModelAndView modelAndView) throws Exception {
    log.info("Forwarding request and sending that info back ...");

    ClientConfig config = new DefaultClientConfig();
    Client client = Client.create(config);
    WebResource service = client.resource(UriBuilder.fromUri("http://localhost:8080").build());

    response.setContentType("application/json");
    response.getWriter().write(service.path(modelAndView.getModel().get("path").toString()).accept("application/json").get(String.class));
    response.setStatus(200);

    throw new Exception("Need to avoid the execution of the afterCompletion. Only way to do so is by throwing an exception...");
}

public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {

}

}

Есть ли более правильный способ вмешаться в жизненный цикл Spring или получить поведение, как описано выше?


person zip4ever    schedule 11.06.2015    source источник
comment
Я не использовал его лично раньше, но я уверен, что Spring Security — это то, что вам нужно: projects .spring.io/spring-security   -  person nicholas.hauschild    schedule 11.06.2015


Ответы (2)


Нашел лучшее решение. Для того, что мне нужно, мне не нужно манипулировать результатами в перехватчике.

Гораздо проще определить контроллер, который сопоставляется с методами запроса.

@RequestMapping(method = {RequestMethod.GET, RequestMethod.PUT, RequestMethod.POST})
public void handleRequest(HttpServletRequest request, HttpServletResponse response) { // code omitted }
person zip4ever    schedule 12.06.2015

Вы не должны пытаться избежать вызова afterCompletion. Просто реализуйте пустой метод и позвольте SpringFramework вызвать его.

Если ваш контроллер возвращает значение null, указывающее, что представление не нужно вызывать, он должен работать с более плавной интеграцией Spring.

Но я не могу понять, почему вы используете здесь Spring MVC. Поскольку вы взаимодействуете только с низкоуровневыми HttpServletRequest и HttpServletResponse, вы также можете использовать:

  • выделенный сервлет, ответственный за передачу запроса и ответа на серверную часть и запись возвращаемого значения в ответ
  • фильтр, который будет выполнять функции безопасности перед передачей запроса в цепочку фильтров
person Serge Ballesta    schedule 11.06.2015