Spring OAuth2类型转换异常:LinkedHashMap无法转为WebAuthenticationDetails
看起来你在无状态OAuth2 JWT的场景下用Actuator做登录审计踩坑了,我来帮你理理问题所在:
问题根源分析
你提到移除details相关代码就正常,而且返回的details和WebAuthenticationDetails属性不同,还带gr...前缀——这大概率是因为在OAuth2 JWT的认证流程里,Authentication对象的details并不是WebAuthenticationDetails,而是Spring Security OAuth2提供的OAuth2AuthenticationDetails(或者对应JWT场景下的特定实现),它的属性和Web版的完全不一样,直接照搬常规Web登录审计的代码去处理自然会报错。
解决步骤建议
先确认details的实际类型
可以在代码里加个日志打印,输出authentication.getDetails().getClass().getName(),看看它到底是哪个类,比如可能是org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationDetails。针对性处理details属性
如果是OAuth2AuthenticationDetails,它的核心属性是tokenValue(JWT令牌本身)、remoteAddress(客户端IP)这些,而不是WebAuthenticationDetails里的sessionId之类的。你可以根据实际需求提取这些字段用于审计,比如:OAuth2AuthenticationDetails details = (OAuth2AuthenticationDetails) authentication.getDetails(); String clientIp = details.getRemoteAddress(); String jwtToken = details.getTokenValue(); // 把这些信息传入Actuator的审计记录中适配无状态场景的审计逻辑
因为是无状态OAuth2,本身没有session,所以常规审计代码里依赖session的部分肯定要去掉,只保留和JWT、客户端信息相关的内容。检查Actuator审计的配置
确保你已经正确配置了AuditEventRepository,比如用InMemoryAuditEventRepository或者自定义的持久化实现,同时在Security配置里开启审计:@Override protected void configure(HttpSecurity http) throws Exception { http // ...其他配置 .oauth2Login() .and() .audit(audit -> audit.enabled(true)); }
额外提示
如果你的details里的gr...是grantType相关的内容,那可能是认证过程中携带的授权类型信息,你可以通过OAuth2Authentication(注意不是普通的Authentication)来获取更多OAuth2相关的上下文信息,比如客户端ID、授权范围等。
内容的提问来源于stack exchange,提问作者secondbreakfast

