web-dev-qa-db-ja.com

SpringInterceptorは@RestControllerサービスにヘッダーを追加しません

私は次のインターセプターを持っています:

public class SecurityInterceptor extends HandlerInterceptorAdapter {

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        response.addHeader("X-Frame-Options", "DENY");
    }
}

私はチェックしました-春は各http要求でそれを呼び出します。

奇妙なことに気づきました。これは、次のようなコントローラーでは正常に機能します。

@Controller
public class AdminViewController {
    @GetMapping ("data")
    public String dataTemplate() {
        return "data";
    }
}

enter image description here

ただし、次のようにコントローラーに応答ヘッダーは追加されません。

@RestController
@RequestMapping(Constants.MY_API_URL)
public class DataServiceController {
     @PostMapping(value = "/mapping", consumes = "application/json")
     public ResponseEntity<Void> saveMapping(@RequestBody MappingDTO mapping, HttpServletRequest request) {
        ...
        return new ResponseEntity<>(CREATED);
    }
}

enter image description here

しかし、インターセプターが呼び出しているため、説明できません。

すべてのリクエスト応答にヘッダーを追加するにはどうすればよいですか?

7
gstackoverflow

私が作成したフィルターは機能しています:

public class SecurityFilter extends OncePerRequestFilter {
    @Override
    protected void doFilterInternal(HttpServletRequest httpRequest,
                                    HttpServletResponse httpResponse,
                                    FilterChain filterChain) throws ServletException, IOException {
        httpResponse.setHeader("X-FRAME-OPTIONS", "DENY");
        filterChain.doFilter(httpRequest, httpResponse);
    }
}    

および登録済み:

@Configuration
public class SecurityConfiguration {
    @Bean
    public FilterRegistrationBean dawsonApiFilter() {
        FilterRegistrationBean registration = new FilterRegistrationBean();
        registration.setFilter(new SecurityFilter());
        return registration;
    }
}
4
gstackoverflow

HandlerInterceptorAdaptersは@ResponseBodyメソッドとResponseEntityメソッドを使用できません。これは、HttpMessageConverterが呼び出される前に応答に書き込むpostHandleによって処理されるためです。応答を変更するのは難しい。

代わりに、ResponseBodyAdviceを記述し、それを@ControllerAdviceとしてマークして、必要なヘッダーを追加できます。

@ControllerAdvice
public class ResponseDTOFilterAdvice implements ResponseBodyAdvice<Object> {
    @Override
    public boolean supports(final MethodParameter returnType, final Class<? extends HttpMessageConverter<?>> converterType) {
        return true;
    }

    @Override
    public Object beforeBodyWrite(final Object body, final MethodParameter returnType, final MediaType selectedContentType,
        final Class<? extends HttpMessageConverter<?>> selectedConverterType, final ServerHttpRequest request,
        final ServerHttpResponse response) {
        if (body instanceof ResponseEntity) {
            ResponseEntity responseEntity = (ResponseEntity) body;
            responseEntity.getHeaders().add("X-Frame-Options", "DENY");
        }
        return body;
    }
}
7
shazin

サー、特定のコントローラーについては、この手順を試すことができます

    @RestController
    @RequestMapping(Constants.MY_API_URL)
     public class DataServiceController {
    @PostMapping(value = "/mapping", consumes = 
     "application/json")
     public ResponseEntity<Boolean> 
     saveMapping(@RequestBody MappingDTO mapping) {
     .........
     ...........
     ......
      HttpHeaders headers = new HttpHeaders();
      headers.addHeader("X-Frame-Options", "DENY");
       return new ResponseEntity<Boolean>(true, headers, 
        HttpStatus.OK);
     }
      }

または

アプリケーションにSpringセキュリティがある場合は、これをセキュリティ構成ファイル内に追加します。これにより、リクエストの応答ごとにxframeオプションをグローバルに無効にできます。

    http.headers().frameOptions().disable();

または

HandlerInterceptorのPostHandleメソッドは、@ ResponseBodyメソッドおよびResponseEntityメソッドでの使用に必ずしも理想的に適しているとは限りません。このような場合、HttpMessageConverterは、postHandleが呼び出される前に応答を書き込んでコミットするため、ヘッダーの追加など、応答を変更できなくなります。代わりに、アプリケーションはResponseBodyAdviceを実装し、それを@ControllerAdvice Beanとして宣言するか、RequestMappingHandlerAdapterで直接構成できます。

https://mtyurt.net/post/spring-modify-response-headers-after-processing.html

または

@gstackoverflow投稿の所有者はすでに解決策を見つけています。彼の解決策を参照できます。

2
Sibin