Spring Boot OAuth:JdbcTokenStore未校验Client ID的查询问题求助
解决JdbcTokenStore跨客户端校验令牌的问题
嘿,这个问题我之前帮不少开发者解决过,你观察得非常仔细——JdbcTokenStore的默认查询逻辑确实存在这个“宽松”的问题,咱们一步步拆解来看:
问题根源
你已经注意到了,JdbcTokenStore的默认访问令牌查询语句DEFAULT_ACCESS_TOKEN_SELECT_STATEMENT只通过token_id过滤:
select token_id, token from oauth_access_token where token_id =?
而oauth_access_token表中其实是存储了client_id字段的(记录生成该令牌的客户端ID),但默认查询并没有把这个字段加入校验逻辑。这就导致只要令牌本身存在且未过期,不管是哪个客户端发起校验请求,都会返回成功,完全不符合你预期的“令牌与客户端绑定”的安全约束。
解决方案:自定义令牌查询语句
要实现“令牌只能由生成它的客户端校验”的逻辑,我们需要修改查询语句,同时匹配token_id和当前请求的client_id:
1. 编写自定义SQL语句
把查询语句调整为:
select token_id, token from oauth_access_token where token_id =? and client_id =?
2. 配置JdbcTokenStore使用自定义SQL
在你的Spring配置类中,创建TokenStore Bean时,通过setAccessTokenSql()方法替换默认语句:
@Bean public TokenStore tokenStore(DataSource dataSource) { JdbcTokenStore tokenStore = new JdbcTokenStore(dataSource); // 替换为带client_id校验的自定义查询 String customAccessTokenQuery = "select token_id, token from oauth_access_token where token_id =? and client_id =?"; tokenStore.setAccessTokenSql(customAccessTokenQuery); return tokenStore; }
3. 额外优化(可选)
如果你的业务场景还需要校验令牌所属的用户(比如密码模式下生成的令牌),还可以在查询中加入username字段的匹配:
select token_id, token from oauth_access_token where token_id =? and client_id =? and username =?
不过这一步需要结合你实际的校验逻辑来调整。
效果验证
修改完成后,当你用client_id2去校验client_id1生成的令牌时,自定义查询会因为client_id不匹配返回空结果,Spring Security OAuth会自动抛出InvalidTokenException,也就是你预期的“令牌未找到”类的错误提示了。
内容的提问来源于stack exchange,提问作者Tulio Adorno
相关产品推荐
相关产品推荐

