I have created this api for streaming an mp3 audio file as response.
@GetMapping (value = "/api/user/stream/{songId}", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
public ResponseEntity<StreamingResponseBody> playSong(@PathVariable Long songId) throws IOException {
File file = new File(projectPath + "\\assets\\audio\\DummySong" + ".mp3");
FileInputStream in = new FileInputStream(file);
StreamingResponseBody songStream = out -> {
try {
Thread.sleep(10);
IOUtils.copy(in, out);
}
catch (InterruptedException e) {
LOGGER.error("Streaming Thread Interrupted - {}", e.getMessage());
}
};
return ResponseEntity.ok()
.header(HttpHeaders.ACCEPT_RANGES, "128")
.header(HttpHeaders.CONTENT_TYPE, "audio/mpeg")
.contentLength(file.length())
.body(songStream);
}
Spring Security Config
@Bean
public SecurityFilterChain configure(HttpSecurity http) throws Exception {
http.csrf(csrf -> csrf.disable());
http.sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS));
http.authorizeHttpRequests((authorizeHttpRequests) ->
authorizeHttpRequests
.requestMatchers("/auth/signin", "/auth/signup", "/docs/**").permitAll()
.requestMatchers("/api/admin/**").hasRole("ADMIN")
.requestMatchers("/api/artist/**").hasAnyRole("ARTIST", "ADMIN")
.requestMatchers("/api/user/**").hasAnyRole("USER", "ADMIN")
.anyRequest().authenticated()
);
http.exceptionHandling((exceptionHandling) ->
exceptionHandling.authenticationEntryPoint((req, resp, e) -> {
LOGGER.error("Error during auth: {}", e.getMessage());
resp.sendError(HttpServletResponse.SC_UNAUTHORIZED, e.getMessage());
}));
http.addFilterBefore(jwtTokenFilter, UsernamePasswordAuthenticationFilter.class);
return http.build();
}
Once I hit this api using Postman the response comes correctly and also the song plays as expected, but in the server terminal I am getting the following errors.
org.springframework.security.access.AccessDeniedException: Access Denied
at org.springframework.security.web.access.intercept.AuthorizationFilter.doFilter(AuthorizationFilter.java:98) ~[spring-security-web-6.1.2.jar:6.1.2]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) ~[spring-security-web-6.1.2.jar:6.1.2]
at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:126) ~[spring-security-web-6.1.2.jar:6.1.2]
at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:120) ~[spring-security-web-6.1.2.jar:6.1.2]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) ~[spring-security-web-6.1.2.jar:6.1.2]
at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:91) ~[spring-security-web-6.1.2.jar:6.1.2]
at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:85) ~[spring-security-web-6.1.2.jar:6.1.2]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) ~[spring-security-web-6.1.2.jar:6.1.2]
at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:100) ~[spring-security-web-6.1.2.jar:6.1.2]
And as root cause
2023-08-17T18:35:48.233+05:30 ERROR 10528 --- [0.0-8080-exec-8] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with pat
h [] threw exception [Unable to handle the Spring Security Exception because the response is already committed.] with root cause.
Please help me figure out what is going wrong and how I fix this issue.