我想提供一個有 Spring Boot 的 Web 服務,它能夠從 MySQL 資料庫下載轉儲。
但下載不應該適合所有人。所以我需要一種登入。不太確定憑證將儲存在哪裡,有可能它們只是硬編碼在應用程式本身。
我有點迷失,不知道該如何實現。
這是我到目前為止得到的:
@Controller public class EBMysqldumpController { private EBMysqldumpService mysqldumpService; @Autowired public EBMysqldumpController(EBMysqldumpService mysqldumpService) { this.mysqldumpService = mysqldumpService; } @GetMapping("/login") public String showLoginForm(Model model) { model.addAttribute("userDto", new UserDto()); return "mysqldump-login"; } @PostMapping(path = "/login") public String validateLoginForm(@Valid UserDto userDto, BindingResult result, HttpServletRequest request) { if (result.hasErrors()) { return "mysqldump-login"; } if (!this.mysqldumpService.checkLogin(userDto)) { result.addError(new ObjectError("", "Wrong username and/or password")); return "mysqldump-login"; } return "redirect:/file"; } @PostMapping(path = "/file") public ResponseEntity<Resource> startMysqlDump(@Valid UserDto userDto, Model model) throws IOException, InterruptedException, MysqldumpException { if (!this.mysqldumpService.checkLogin(userDto)) { return new ResponseEntity<>(HttpStatus.UNAUTHORIZED); } File mysqlDump = this.mysqldumpService.getMysqlDumpFile(); ByteArrayResource byteArrayResource = this.mysqldumpService.getByteArrayResourceFromFile(mysqlDump); HttpHeaders headers = getMysqldumpHeaders(mysqlDump.getName()); ResponseEntity<Resource> body = ResponseEntity.ok() .headers(headers) .contentLength(mysqlDump.length()) .contentType(MediaType.APPLICATION_OCTET_STREAM) .body(byteArrayResource); this.mysqldumpService.deleteFile(mysqlDump); return body; } private HttpHeaders getMysqldumpHeaders(String filename) { ContentDisposition contentDisposition = ContentDisposition.inline().filename(filename).build(); HttpHeaders headers = new HttpHeaders(); headers.setContentDisposition(contentDisposition); return headers; } }
目前控制器在「/login」處顯示登入頁面。提交表單後,控制器會檢查憑證是否正確,如果不正確,則會再次顯示帶有錯誤訊息的登入頁面。
但我的問題是,登入成功後我不知道該做什麼。當我直接呼叫它時,下載工作正常,但使用重定向時它不起作用,因為我發出了發布請求以確保剛剛登入的使用者可以下載該檔案。如果我發出獲取請求,每個人都可以使用該連結。
我有種感覺,我處理問題的方式是錯的。你會推薦什麼?登入成功後如何開始下載?
P粉5746952152024-03-29 00:48:53
我建議將 Spring Security 添加到您的專案中,並在其中有一個硬編碼的用戶:
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.crypto.password.NoOpPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; @Configuration public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter { @Autowired private PasswordEncoder passwordEncoder; @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.inMemoryAuthentication() .passwordEncoder(passwordEncoder) .withUser("user1").password("my-secret-pwd").roles("USER"); } @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests( registry -> registry.mvcMatchers("/**").authenticated() ) .formLogin(); } @Bean public PasswordEncoder passwordEncoder() { return NoOpPasswordEncoder.getInstance(); } }