我是Angular和Spring Security的新手,我遵循this tutorial来使用Springboot和Angular上传/下载文件。在本教程中,他们没有使用Spring Security(只是Angular + Springboot)。但是,我无法同时使用这三种技术上传文件。
问题: 我不能像教程中那样下载带有链接的文件
我得到的错误消息是:
401 unathorized http error
说我需要完整的身份验证才能访问localhost:8080/api/manage/download
资源,该资源指向本教程中介绍的用于下载文件的get方法:
@GetMapping("/download")
@ResponseBody
public ResponseEntity<?> getFile() throws IOException, URISyntaxException{
// just an example of an image resource to test
Resource file = storageService.loadAsResource("d.jpg");
// the resource is not null
// I can see it when debugging
// which mean i should receive it as a response body
return ResponseEntity.ok()
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + file.getFilename() + "\"")
.body(file);
}
网络安全配置:
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(
prePostEnabled = true
)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
UserDetailsServiceImpl userDetailsService;
@Autowired
private JwtAuthEntryPoint unauthorizedHandler;
@Bean
public JwtAuthTokenFilter authenticationJwtTokenFilter() {
return new JwtAuthTokenFilter();
}
@Override
public void configure(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception {
authenticationManagerBuilder
.userDetailsService(userDetailsService)
.passwordEncoder(passwordEncoder());
}
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.cors().and().csrf().disable().
authorizeRequests()
.antMatchers("/api/auth/**").permitAll()
.and()
.authorizeRequests()
.antMatchers("/api/manage/**").authenticated()
.and()
.exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
http.addFilterBefore(authenticationJwtTokenFilter(), UsernamePasswordAuthenticationFilter.class);
}
}
如您所见,经过身份验证后,我应该访问资源。
附加说明: 即使成功通过身份验证,我也无法直接从浏览器或通过链接访问提到的资源。但是我可以通过服务从此Angular get请求访问它:
showFile(): any {
return this.http.get<any>("http://localhost:8080/api/manage/download");
}
但是我不知道如何在Angular中将结果作为文件使用(即使我不喜欢这种方法,我也喜欢像教程中那样通过链接获取它),因为我看不到任何可转换为Blob的东西或文件中的结果,如下所示,正文为null:
Response : {"_isScalar":false,"source":{"_isScalar":false,"source":{"_isScalar":false,"source":{"_isScalar":true,"value":{"url":"http://localhost:8080/api/manage/download","body":null,"reportProgress":false,"withCredentials":false,"responseType":"json","method":"GET","headers":{"normalizedNames":{},"lazyUpdate":null,"headers":{}},"params":{"updates":null,"cloneFrom":null,"encoder":{},"map":null},"urlWithParams":"http://localhost:8080/api/manage/download"}},"operator":{"concurrent":1}},"operator":{}},"operator":{}}
为什么我认为该问题可能与Spring Security有关:
因为它无需使用就可以工作
我已经尝试过的内容:
我发现了一些类似的问题,但是所有这些都是关于使用Spring Security从自定义位置访问文件的,而解决方案是在WebSecurity配置中启用此访问。我认为这对我来说没有问题,因为正如我所说,我能够从upload-dir
自定义位置加载资源。