Spring Cloud微服务架构中基于Spring AuditorAware结合KeyCloak实现用户姓名审计的部署位置及方案咨询
Spring Cloud微服务架构中基于Spring AuditorAware结合KeyCloak实现用户姓名审计的部署位置及方案咨询
嗨,针对你的Spring Cloud微服务审计问题,我来给你捋清楚部署位置和具体实现方案——毕竟很多旧例子确实容易误导人,咱们从实际业务场景出发:
部署位置明确:必须放在plant-ms业务服务中
首先直接给结论:AuditorAware的实现绝对要放在你的业务服务plant-ms里,而不是网关,原因很简单:
- 审计逻辑是和业务数据强绑定的——你要把用户姓名插入到
plant-ms的数据库条目里,属于业务层的责任; - 网关的核心职责是路由、认证校验、流量控制,不应该耦合业务层的审计细节,否则会让网关职责过重,后续维护成本极高;
- 网关只需要保证合法的JWT令牌能传递到
plant-ms即可,剩下的审计逻辑交给业务服务自己处理。
具体实现步骤(结合KeyCloak JWT)
1. 给plant-ms配置KeyCloak JWT资源支持
因为网关已经做了OAuth2校验,请求到达plant-ms时会携带有效的JWT令牌,你需要在plant-ms的配置里开启资源服务器支持,让它能解析KeyCloak的JWT:
# plant-ms/application.yml spring: security: oauth2: resourceserver: jwt: jwk-set-uri: "http://你的KeyCloak地址/auth/realms/你的realm名称/protocol/openid-connect/certs" config: import: "optional:configserver:http://localhost:8080/" eureka: instance: preferIpAddress: true client: serviceUrl: defaultZone: http://localhost:8070/eureka/
2. 实现AuditorAware接口,从JWT中提取用户姓名
这里用Spring Security提供的JwtAuthenticationToken来获取用户信息,比手动解析JWT更安全优雅:
@Component public class KeycloakAuditorAware implements AuditorAware<String> { @Override public Optional<String> getCurrentAuditor() { // 从Security上下文获取当前认证信息 Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); // 判断是否为合法的已认证用户 if (authentication == null || !authentication.isAuthenticated() || authentication instanceof AnonymousAuthenticationToken) { return Optional.empty(); } // 转换为JWT认证令牌,提取KeyCloak返回的用户姓名 JwtAuthenticationToken jwtToken = (JwtAuthenticationToken) authentication; String firstName = jwtToken.getToken().getClaimAsString("given_name"); String lastName = jwtToken.getToken().getClaimAsString("family_name"); // 返回组合后的用户姓名,也可以根据你的审计表结构返回单独的字段 return Optional.of(String.join(" ", firstName, lastName)); } }
3. 开启Spring Data JPA审计支持
在plant-ms的主启动类或者配置类上添加注解,同时给实体类加上审计字段:
// 主启动类 @SpringBootApplication @EnableJpaAuditing(auditorAwareRef = "keycloakAuditorAware") public class PlantMsApplication { public static void main(String[] args) { SpringApplication.run(PlantMsApplication.class, args); } } // 业务实体类示例 @Entity @EntityListeners(AuditingEntityListener.class) public class Plant { // 其他业务字段 @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @CreatedBy private String createdBy; // 存储创建人姓名 @LastModifiedBy private String lastModifiedBy; // 存储最后修改人姓名 @CreatedDate private LocalDateTime createdDate; @LastModifiedDate private LocalDateTime lastModifiedDate; // getter、setter方法 }
关键注意事项
- KeyCloak客户端配置:确保你的KeyCloak客户端已经勾选了
profile范围,这样JWT里才会包含given_name(名)和family_name(姓)字段; - 令牌传递:Spring Cloud Gateway默认会传递
Authorization请求头,但如果有自定义过滤器,不要把这个头过滤掉,否则plant-ms拿不到JWT; - 异常处理:可以在
AuditorAware实现中添加异常捕获,比如JWT解析失败时返回默认值(比如"system"),避免业务请求失败。
备注:内容来源于stack exchange,提问作者viespring
相关产品推荐
相关产品推荐

