客户订单管理的微服务例子

下述代码实现了一个客户基本信息管理的微服务,包含以下功能:

1、用户认证

  • 使用 Spring Security 和 OAuth2 进行认证。
  • 配置了角色和权限控制。

2、角色授权

  • 通过 @PreAuthorize 注解实现角色授权,只有管理员可以执行某些操作。

3、调用其他微服务

  • 使用 FeignClient 调用用户管理微服务,从中获取用户数据。

此示例具备扩展性,可以轻松增加其他功能,例如更多的 REST API 或与其他微服务的集成。

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.web.bind.annotation.*;

import java.util.Map;

@SpringBootApplication
@EnableFeignClients
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class CustomerServiceApplication {

    public static void main(String[] args) {
        SpringApplication.run(CustomerServiceApplication.class, args);
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        // 配置加密强度参数,允许通过配置文件动态调整
        int strength = Integer.parseInt(System.getProperty("bcrypt.strength", "12"));
        return new BCryptPasswordEncoder(strength);
    }

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            .authorizeRequests(registry -> configureAuthorizationRules(registry)) // 集中管理路径和角色规则
            .anyRequest().permitAll(); // 其他接口允许所有人访问
        return http.build();
    }

    private void configureAuthorizationRules(HttpSecurity.AuthorizeRequestsConfigurer registry) {
        registry
            .antMatchers("/admin/**").hasRole("ADMIN") // 仅允许管理员访问
            .antMatchers("/user/**").authenticated(); // 需要身份认证的接口
    }
}

@FeignClient(name = "user-management-service", url = "${user.management.service.url}")
interface UserManagementClient {
    @GetMapping("/users/{id}")
    Map getUserById(@PathVariable("id") String userId); // 调用用户管理微服务获取用户信息
}

class UserDetailsDTO {
    private String username; // 用户名字段

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }
}

class AuthenticationDetailsDTO {
    private String username;

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public static AuthenticationDetailsDTO fromMap(Map detailsMap) {
        AuthenticationDetailsDTO dto = new AuthenticationDetailsDTO();
        dto.setUsername((String) detailsMap.get("username"));
        return dto;
    }
}

class CustomerDetailsDTO {
    private String name;
    private String email;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }
}

@RestController
@RequestMapping("/customer")
class CustomerController {

    private final UserManagementClient userManagementClient;

    // 使用构造器注入依赖,提升可测试性
    public CustomerController(UserManagementClient userManagementClient) {
        this.userManagementClient = userManagementClient;
    }

    @GetMapping("/info/{id}")
    public Map getCustomerInfo(@PathVariable String id, OAuth2Authentication authentication) {
        // 从认证对象中提取用户详细信息
        Object details = authentication.getUserAuthentication().getDetails();
        if (!(details instanceof Map)) {
            throw new IllegalArgumentException("Unexpected authentication details structure");
        }
        AuthenticationDetailsDTO userDetails = AuthenticationDetailsDTO.fromMap((Map) details);
        String username = userDetails.getUsername();

        // 调用用户管理微服务获取客户信息
        Map userInfo = userManagementClient.getUserById(id);
        userInfo.put("requestedBy", username); // 添加请求者信息

        return userInfo;
    }

    @PostMapping("/create")
    @PreAuthorize("hasRole('ADMIN')")
    public String createCustomer(@RequestBody CustomerDetailsDTO customerDetails) {
        // 创建新客户记录的逻辑
        return "Customer created: " + customerDetails.getName() + " (" + customerDetails.getEmail() + ")";
    }

    @DeleteMapping("/delete/{id}")
    @PreAuthorize("hasRole('ADMIN')")
    public String deleteCustomer(@PathVariable String id) {
        // 删除客户记录的逻辑
        return "Customer deleted: " + id;
    }
}

你可能感兴趣的:(Java程序,微服务,架构,云原生)