I’ve tried changing target to /connect/api/upload
still no luck.
Since its returning 403 i thought it might be related to my security config. So i provided my spring security config class below.
I generated my hilla app yesterday using start.vaadin.com.
Cant upload file with backend response:
{
"timestamp": "2025-01-02T07:51:30.179+00:00",
"status": 403,
"error": "Forbidden",
"message": "Forbidden",
"path": "/api/upload"
}
My upload component:
<Upload
accept='application/pdf,.pdf'
maxFiles={1}
maxFileSize={10485760}
target='/api/upload'
className='w-full'
/>
Backend Controller
package com.mitpc.hr.services.file;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
@RestController
@RequestMapping("/api")
@Log4j2
public class FileEndpoint {
@Autowired
private FileService fileService;
@CrossOrigin
@PostMapping("/upload")
public String uploadFile(@RequestParam("file") MultipartFile uploadedFile) {
log.info(uploadedFile.getOriginalFilename());
return "works";
}
}
Spring security config:
package com.mitpc.hr.security;
import com.nimbusds.jose.JWSAlgorithm;
import com.vaadin.flow.spring.security.VaadinWebSecurity;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;
@EnableWebSecurity
@Configuration
public class SecurityConfiguration extends VaadinWebSecurity {
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.sessionManagement(sess -> sess.sessionCreationPolicy(SessionCreationPolicy.STATELESS));
http.authorizeHttpRequests(authorize -> authorize
.requestMatchers(new AntPathRequestMatcher("/images/*.png")).permitAll()
.requestMatchers(new AntPathRequestMatcher("/line-awesome/**/*.svg")).permitAll()
.requestMatchers(new AntPathRequestMatcher("/api/upload")).anonymous());
super.configure(http);
setLoginView(http, "/login");
setStatelessAuthentication(http, new SecretKeySpec(Base64.getDecoder().decode("CHANGED"), JWSAlgorithm.HS256.getName()), "CHANGED");
}
}
Component on the web: