[tag] 解决了跨域问题

This commit is contained in:
LYC 2025-04-24 14:18:49 +08:00
parent f5188d8032
commit 1fae1e971e
7 changed files with 219 additions and 17 deletions

View File

@ -3,6 +3,7 @@ package com.waterquality.projectmanagement.config;
import com.waterquality.projectmanagement.repository.EmployeeRepository; import com.waterquality.projectmanagement.repository.EmployeeRepository;
import jakarta.servlet.Filter; import jakarta.servlet.Filter;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.apache.catalina.filters.CorsFilter;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.AuthenticationManager;
@ -20,6 +21,12 @@ import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import java.util.Arrays;
import java.util.Collections;
@Configuration @Configuration
@EnableWebSecurity @EnableWebSecurity
@ -35,6 +42,7 @@ public class SecurityConfig {
http http
.csrf(csrf -> csrf.disable()) .csrf(csrf -> csrf.disable())
.sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
.cors(cors -> cors.configurationSource(corsConfigurationSource())) // 配置 CORS
.authorizeHttpRequests(authz -> authz .authorizeHttpRequests(authz -> authz
.requestMatchers("/api/auth/**").permitAll() .requestMatchers("/api/auth/**").permitAll()
.anyRequest().authenticated()) .anyRequest().authenticated())
@ -44,6 +52,20 @@ public class SecurityConfig {
return http.build(); return http.build();
} }
@Bean
public CorsConfigurationSource corsConfigurationSource() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
Collections.singletonList("*");
config.setAllowedOrigins(Arrays.asList("http://localhost:8848")); // 替换为允许的源
config.setAllowedHeaders(Arrays.asList("*")); // 允许的头
config.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE", "OPTIONS")); // 允许的方法
source.registerCorsConfiguration("/**", config);
return source;
}
@Bean @Bean
public UserDetailsService userDetailsService() { public UserDetailsService userDetailsService() {
return username -> (UserDetails) employeeRepository.findByUsername(username) return username -> (UserDetails) employeeRepository.findByUsername(username)

View File

@ -15,10 +15,7 @@ import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException; import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.AuthenticationException; import org.springframework.security.core.AuthenticationException;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.validation.Valid; import javax.validation.Valid;
@ -32,6 +29,8 @@ public class AuthController {
private final JwtTokenProvider jwtTokenProvider; private final JwtTokenProvider jwtTokenProvider;
private final EmployeeRepository employeeRepository; private final EmployeeRepository employeeRepository;
@CrossOrigin
@PostMapping("/login") @PostMapping("/login")
public ResponseEntity<?> login(@Valid @RequestBody LoginDTO dto) { public ResponseEntity<?> login(@Valid @RequestBody LoginDTO dto) {
try { try {
@ -59,7 +58,7 @@ public class AuthController {
token, token,
employee.getEmployeeId(), employee.getEmployeeId(),
employee.getName(), employee.getName(),
employee.getPosition().name() employee.getPosition()
)); ));
} catch (Exception e) { } catch (Exception e) {

View File

@ -0,0 +1,75 @@
package com.waterquality.projectmanagement.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@RestController
public class RouteController {
@GetMapping("/get-async-routes")
public Map<String, Object> getAsyncRoutes() {
// 模拟后端动态生成路由
Map<String, Object> permissionRouter = new HashMap<>();
permissionRouter.put("path", "/permission");
permissionRouter.put("meta", createMeta("权限管理", "ep:lollipop", 10));
permissionRouter.put("children", createChildren());
return createResponse(Collections.singletonList(permissionRouter));
}
private Map<String, Object> createMeta(String title, String icon, int rank) {
Map<String, Object> meta = new HashMap<>();
meta.put("title", title);
meta.put("icon", icon);
meta.put("rank", rank);
return meta;
}
private List<Map<String, Object>> createChildren() {
Map<String, Object> pagePermission = new HashMap<>();
pagePermission.put("path", "/permission/page/index");
pagePermission.put("name", "PermissionPage");
pagePermission.put("meta", createMeta("页面权限", null, 0));
pagePermission.put("meta.roles", List.of("admin", "common"));
Map<String, Object> buttonPermission = new HashMap<>();
buttonPermission.put("path", "/permission/button");
buttonPermission.put("meta", createMeta("按钮权限", null, 0));
buttonPermission.put("children", createButtonChildren());
return List.of(pagePermission, buttonPermission);
}
private List<Map<String, Object>> createButtonChildren() {
Map<String, Object> buttonRouter = new HashMap<>();
buttonRouter.put("path", "/permission/button/router");
buttonRouter.put("component", "permission/button/index");
buttonRouter.put("name", "PermissionButtonRouter");
buttonRouter.put("meta", createButtonMeta("路由返回按钮权限", List.of("permission:btn:add", "permission:btn:edit", "permission:btn:delete")));
Map<String, Object> buttonLogin = new HashMap<>();
buttonLogin.put("path", "/permission/button/login");
buttonLogin.put("component", "permission/button/perms");
buttonLogin.put("name", "PermissionButtonLogin");
buttonLogin.put("meta", createMeta("登录接口返回按钮权限", null, 0));
return List.of(buttonRouter, buttonLogin);
}
private Map<String, Object> createButtonMeta(String title, List<String> auths) {
Map<String, Object> meta = createMeta(title, null, 0);
meta.put("auths", auths);
return meta;
}
private Map<String, Object> createResponse(List<Map<String, Object>> data) {
Map<String, Object> response = new HashMap<>();
response.put("success", true);
response.put("data", data);
return response;
}
}

View File

@ -29,13 +29,13 @@ public class WorkOrderController {
private final WorkOrderService workOrderService; private final WorkOrderService workOrderService;
@PostMapping @PostMapping
@PreAuthorize("hasRole('MAINTENANCE')") @PreAuthorize("hasAnyRole('MAINTENANCE', 'ADMIN')")
public ResponseEntity<Response<WorkOrderVO>> createOrder( public ResponseEntity<Response<WorkOrderVO>> createOrder(
@Valid @RequestBody WorkOrderCreateDTO dto, @Valid @RequestBody WorkOrderCreateDTO dto,
@AuthenticationPrincipal UserDetails user) { @AuthenticationPrincipal CustomUserDetails user) {
// 假设 UserDetails 实现了 getUsername() 方法返回用户 ID // 假设 UserDetails 实现了 getUsername() 方法返回用户 ID
return ResponseEntity.ok(Response.newSuccess( return ResponseEntity.ok(Response.newSuccess(
workOrderService.createOrder(dto, Integer.valueOf(user.getUsername())))); workOrderService.createOrder(dto, user.getUserID())));
} }
@PatchMapping("/{id}/status") @PatchMapping("/{id}/status")

View File

@ -1,9 +1,59 @@
package com.waterquality.projectmanagement.entity.employee; package com.waterquality.projectmanagement.entity.employee;
import lombok.Data;
import lombok.Getter;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetails;
public interface CustomUserDetails extends UserDetails { import java.util.Collection;
Integer getUserID(); import java.util.Collections;
String getUsername(); import java.util.List;
@Data
public class CustomUserDetails implements UserDetails {
private final String username;
private final String password;
private final Integer userid;
@Getter
private String position;
private final Collection<? extends GrantedAuthority> authorities;
// 默认构造函数
public CustomUserDetails() {
this.userid = null;
this.username = null;
this.password = null;
this.position = null;
this.authorities = Collections.emptyList();
}
public CustomUserDetails(String username, String password, Integer id, Integer userid, String position, Collection<? extends GrantedAuthority> authorities) {
this.username = username;
this.password = password;
this.userid = userid;
this.position = position;
this.authorities = authorities;
}
public CustomUserDetails(String username, String password, String position, List<GrantedAuthority> authorities,Integer id) {
this.username = username;
this.password = password;
this.position = position;
this.authorities = authorities;
this.userid = id;
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return List.of();
}
// 实现 getUserID 方法
public Integer getUserID(){
return userid;
};
} }

View File

@ -1,8 +1,8 @@
package com.waterquality.projectmanagement.entity.employee; package com.waterquality.projectmanagement.entity.employee;
import com.waterquality.projectmanagement.entity.department.Department;
import jakarta.persistence.*; import jakarta.persistence.*;
import lombok.Data; import lombok.Data;
import lombok.Getter;
import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority;
@ -12,7 +12,7 @@ import java.util.Collections;
@Entity @Entity
@Table(name = "employees") @Table(name = "employees")
@Data @Data
public class Employee implements CustomUserDetails { public class Employee extends CustomUserDetails {
@Id @Id
@GeneratedValue(strategy = GenerationType.IDENTITY) @GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "employee_id") @Column(name = "employee_id")
@ -41,9 +41,12 @@ public class Employee implements CustomUserDetails {
@Column(nullable = false, unique = true) @Column(nullable = false, unique = true)
private String username; private String username;
@Getter
@Column(nullable = false) @Column(nullable = false)
private String password; private String password;
// 实现 UserDetails 接口方法 // 实现 UserDetails 接口方法
@Override @Override
public Collection<? extends GrantedAuthority> getAuthorities() { public Collection<? extends GrantedAuthority> getAuthorities() {
@ -51,13 +54,19 @@ public class Employee implements CustomUserDetails {
} }
@Override @Override
public boolean isAccountNonExpired() { return true; } public boolean isAccountNonExpired() {
return super.isAccountNonExpired();
}
@Override @Override
public boolean isAccountNonLocked() { return true; } public boolean isAccountNonLocked() {
return super.isAccountNonLocked();
}
@Override @Override
public boolean isCredentialsNonExpired() { return true; } public boolean isCredentialsNonExpired() {
return super.isCredentialsNonExpired();
}
@Override @Override
public boolean isEnabled() { return status == Status.ACTIVE; } public boolean isEnabled() { return status == Status.ACTIVE; }
@ -70,6 +79,11 @@ public class Employee implements CustomUserDetails {
@Override @Override
public String getUsername() { public String getUsername() {
return name; // 返回用户名 return username; // 返回用户名
} }
public String getPosition(){
return position.name();
}
} }

View File

@ -0,0 +1,42 @@
package com.waterquality.projectmanagement.service;
import com.waterquality.projectmanagement.entity.employee.CustomUserDetails;
import com.waterquality.projectmanagement.entity.employee.Employee;
import com.waterquality.projectmanagement.repository.EmployeeRepository;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Optional;
@Service
public class CustomUserDetailsService implements UserDetailsService {
private final EmployeeRepository employeeRepository;
public CustomUserDetailsService(EmployeeRepository employeeRepository) {
this.employeeRepository = employeeRepository;
}
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
Optional<Object> optionalEmployee = employeeRepository.findByUsername(username);
if (optionalEmployee.isEmpty()) {
throw new UsernameNotFoundException("User not found");
}
Employee employee = (Employee) optionalEmployee.get(); // 获取 Employee 对象
// 根据 position 属性设置权限
List<GrantedAuthority> authorities = List.of(new SimpleGrantedAuthority("ROLE_" + employee.getPosition()));
System.out.println(employee.getEmployeeId());
return new CustomUserDetails(employee.getUsername(), employee.getPassword(), employee.getPosition(), authorities,employee.getEmployeeId());
}
}