Spring Security Authorization Server令牌校验原理与正确实现咨询
JWT令牌校验原理与Spring Security资源服务正确配置流程
一、资源服务校验JWT令牌的核心原理
资源服务校验令牌分为公钥获取和令牌验证两个核心阶段:
- 公钥拉取与缓存:资源服务启动时或首次校验令牌时,会通过配置的
jwkSetUri请求认证服务的JWKS(JSON Web Key Set)端点,获取认证服务暴露的所有公钥集合,之后会缓存这些公钥(默认缓存时长为5分钟),避免重复请求。 - 令牌解析与验证:
- 先从JWT的**头部(Header)**中提取
kid(密钥ID),用这个kid匹配缓存中的公钥; - 使用匹配到的公钥验证JWT的签名,确保令牌没有被篡改;
- 自动校验令牌的标准属性:
exp(过期时间)、iat(签发时间)、iss(签发者,即认证服务地址)、aud(受众,即资源服务的标识),只要其中一项不合法,就会拒绝请求。
- 先从JWT的**头部(Header)**中提取
二、正确实现流程(基于Spring Security)
1. 认证服务端:配置密钥与JWKS端点
确保认证服务生成的RSA密钥对被正确配置,并且JWKS端点能正常对外暴露:
- 生成RSA密钥对(可以用代码生成或KeyStore):
@Bean public KeyPair keyPair() { try { KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA"); keyPairGenerator.initialize(2048); return keyPairGenerator.generateKeyPair(); } catch (NoSuchAlgorithmException e) { throw new RuntimeException(e); } } @Bean public JWKSource<SecurityContext> jwkSource(KeyPair keyPair) { RSAKey rsaKey = new RSAKey.Builder((RSAPublicKey) keyPair.getPublic()) .privateKey(keyPair.getPrivate()) .keyID(UUID.randomUUID().toString()) .build(); JWKSet jwkSet = new JWKSet(rsaKey); return (jwkSelector, securityContext) -> jwkSelector.select(jwkSet); } - 确保Authorization Server的配置中开放JWKS端点(默认路径是
/oauth2/jwks),这个端点不需要认证就能访问。
2. 资源服务端:配置JWT校验参数
在资源服务的配置文件(如application.yml)中添加以下配置:
spring: security: oauth2: resourceserver: jwt: jwk-set-uri: http://你的认证服务地址/oauth2/jwks issuer-uri: http://你的认证服务地址 # 必须和认证服务签发令牌时的iss一致
或者用Java代码配置JwtDecoder:
@Bean public JwtDecoder jwtDecoder() { return NimbusJwtDecoder.withJwkSetUri("http://你的认证服务地址/oauth2/jwks") .build(); }
3. 关键校验细节
- 受众(aud)匹配:认证服务在颁发令牌时,要把资源服务的
client-id加入aud字段;如果资源服务需要自定义受众校验,可以通过配置jwt.audiences指定:spring: security: oauth2: resourceserver: jwt: audiences: your-resource-client-id - 公钥缓存更新:如果认证服务更新了密钥对,资源服务会在缓存过期后自动拉取新的JWKS,无需重启;如果需要立即更新,可以调用
JwtDecoder的clearCache()方法。
三、部署注意事项
- 网络可达性:资源服务必须能访问认证服务的JWKS端点,生产环境建议配置内部域名或VPN,避免公网暴露不必要的端点。
- 密钥管理:生产环境不要用代码生成的临时密钥,使用KeyStore存储密钥对,并且定期轮换;禁止把私钥暴露给任何外部服务。
- 时钟同步:认证服务和资源服务的系统时钟必须保持一致(误差不超过1分钟),否则会出现令牌过期校验错误。
- HTTPS传输:生产环境必须使用HTTPS,避免令牌和公钥在传输过程中被窃取或篡改。
内容的提问来源于stack exchange,提问作者Xan
相关产品推荐
相关产品推荐

