[英]Does I need a spring boot oauth2 authorization server to generate a custom JWT and a JWKS endpoint?
[英]Creating jwks endpoint spring boot
我正在 Java Spring Boot 中构建两个服务应用程序,其中一个服务是生成 jwt 的身份验证服务,另一个是资源服务,它解码 jwt 并根据 jwt 主题返回帖子列表。
我当前的身份验证服务设置有一个存储在资源中的 .jks 密钥对和一个登录端点:
我的资源服务器有一个在 preHandle() 阶段解码 jwt 的方法,如下所示:
@Value("${jwt.key}")
private String publicKey;
public Claims decodeJWT(String jwt) {
KeyFactory kf;
PublicKey key;
publicKey = publicKey
.replace("-----BEGIN PUBLIC KEY-----", "")
.replace("-----END PUBLIC KEY-----", "")
.replace("\n", "")
.trim();
try{
kf = KeyFactory.getInstance("RSA");
X509EncodedKeySpec pubKeySpecX509EncodedKeySpec = new X509EncodedKeySpec(Base64.getDecoder().decode(publicKey));
key = kf.generatePublic(pubKeySpecX509EncodedKeySpec);
} catch (Exception e) {
throw new RuntimeException("Failed to generate Public Key", e);
}
//This line will throw an exception if it is not a signed JWS (as expected)
return Jwts.parser()
.requireIssuer("auth-service")
.requireAudience("posts-service")
.setSigningKey(key)
.parseClaimsJws(jwt).getBody();
}
我唯一的问题是我需要从身份验证服务 .jks 文件中手动导出公钥并将其存储在资源服务 application.yml 文件中。
因此,我的问题是:在身份验证服务中创建 jwks 端点的最佳方法是什么,该端点从 .jks 文件返回公钥? 以及如何最好地从资源服务中添加对它的调用?
干杯克里斯
弄清楚了。
在 auth 服务中创建 JWKS:
public Map<String, List<Map<String, Object>>> getPublicKeys(){
RSAPublicKey rsa;
try{
is = JwtBuilder.class.getResourceAsStream(("/" + signingKeyStore));
keyStore = KeyStore.getInstance("JKS");
keyStore.load(is, signingKeyStorePassword.toCharArray());
rsa = (RSAPublicKey) keyStore.getCertificate(signingKeyId).getPublicKey();
} catch (Exception e) {
throw new RuntimeException("Failed to retrieve public key", e);
}
Map<String, Object> values = new HashMap<>();
values.put("kty", rsa.getAlgorithm()); // getAlgorithm() returns kty not algorithm
values.put("kid", signingKeyId);
values.put("n", Base64.getUrlEncoder().encodeToString(rsa.getModulus().toByteArray()));
values.put("e", Base64.getUrlEncoder().encodeToString(rsa.getPublicExponent().toByteArray()));
values.put("alg", "RS256");
values.put("use", "sig");
List<Map<String, Object>> keyList = new ArrayList<>();
keyList.add(values);
Map<String, List<Map<String, Object>>> keys = new HashMap<>();
keys.put("keys", keyList);
return keys;
}
在资源服务中解码和验证 JWT:
public DecodedJWT decodeAndVerifyJWT(String token){
DecodedJWT jwt;
try{
jwt = JWT.decode(token);
JwkProvider provider = new UrlJwkProvider("http://localhost:8090");
Jwk jwk = provider.get(jwt.getKeyId());
Algorithm algorithm = Algorithm.RSA256((RSAPublicKey) jwk.getPublicKey(), null);
algorithm.verify(jwt);
} catch (InvalidPublicKeyException e) {
throw new RuntimeException("Invalid Public key", e);
} catch (JwkException e) {
throw new RuntimeException("Couldn't verify JWT", e);
}
return jwt;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.