|
2 | 2 |
|
3 | 3 | import com.example.config.OAuth2ClientDetailProperties.Registration; |
4 | 4 | import com.example.utils.CertificateUtils; |
5 | | -import com.example.utils.JWK2PEM; |
6 | | -import com.example.utils.PathResolver; |
7 | | -import com.example.utils.XMLSec2PEM; |
8 | 5 | import com.nimbusds.jose.JOSEException; |
9 | | -import com.nimbusds.jose.JOSEObjectType; |
10 | | -import com.nimbusds.jose.JWSAlgorithm; |
11 | | -import com.nimbusds.jose.JWSHeader; |
12 | | -import com.nimbusds.jose.JWSSigner; |
13 | | -import com.nimbusds.jose.crypto.RSASSASigner; |
14 | | -import com.nimbusds.jose.jwk.JWK; |
15 | | -import com.nimbusds.jose.jwk.KeyType; |
| 6 | +import com.nimbusds.jose.jwk.JWKSet; |
16 | 7 | import com.nimbusds.jose.jwk.RSAKey; |
17 | | -import com.nimbusds.jwt.JWTClaimsSet; |
18 | | -import com.nimbusds.jwt.JWTClaimsSet.Builder; |
19 | | -import com.nimbusds.jwt.SignedJWT; |
| 8 | +import com.nimbusds.jose.jwk.source.ImmutableJWKSet; |
| 9 | +import com.nimbusds.jose.jwk.source.JWKSource; |
| 10 | +import com.nimbusds.jose.proc.SecurityContext; |
20 | 11 | import java.io.IOException; |
21 | | -import java.nio.file.Files; |
22 | | -import java.nio.file.Path; |
23 | 12 | import java.security.NoSuchAlgorithmException; |
24 | 13 | import java.security.interfaces.RSAPrivateKey; |
25 | | -import java.security.interfaces.RSAPublicKey; |
26 | 14 | import java.security.spec.InvalidKeySpecException; |
27 | | -import java.util.Date; |
| 15 | +import java.time.Instant; |
28 | 16 | import java.util.Map; |
29 | 17 | import java.util.UUID; |
30 | 18 | import lombok.extern.slf4j.Slf4j; |
31 | 19 | import org.springframework.security.oauth2.client.registration.ClientRegistration; |
| 20 | +import org.springframework.security.oauth2.jwt.JwsHeader; |
| 21 | +import org.springframework.security.oauth2.jwt.Jwt; |
| 22 | +import org.springframework.security.oauth2.jwt.JwtClaimsSet; |
| 23 | +import org.springframework.security.oauth2.jwt.JwtClaimsSet.Builder; |
| 24 | +import org.springframework.security.oauth2.jwt.JwtEncoderParameters; |
| 25 | +import org.springframework.security.oauth2.jwt.NimbusJwtEncoder; |
32 | 26 |
|
33 | 27 | @Slf4j |
34 | 28 | public class DPoPProofBuilder { |
@@ -56,72 +50,40 @@ public String createDPoPProof( |
56 | 50 | try { |
57 | 51 |
|
58 | 52 | RSAPrivateKey privateKey = getRsaPrivateKey(registration); |
59 | | - RSAPublicKey publicKey = (RSAPublicKey) CertificateUtils.getPublicKey(privateKey); |
60 | | - JWK jwk = new RSAKey.Builder(publicKey).build(); |
| 53 | + RSAKey rsaKey = CertificateUtils.getRsaKey(privateKey, null); |
61 | 54 |
|
62 | | - JWSHeader header = |
63 | | - new JWSHeader.Builder(resolveAlgorithm(jwk)) |
64 | | - .type(new JOSEObjectType("dpop+jwt")) |
65 | | - .jwk(jwk) |
| 55 | + JWKSource<SecurityContext> jwkSource = new ImmutableJWKSet<>(new JWKSet(rsaKey)); |
| 56 | + NimbusJwtEncoder jwtEncoder = new NimbusJwtEncoder(jwkSource); |
| 57 | + |
| 58 | + JwsHeader jwsHeader = |
| 59 | + JwsHeader.with(CertificateUtils.resolveAlgorithm(rsaKey)) |
| 60 | + .jwk(rsaKey.toPublicJWK().toJSONObject()) |
| 61 | + .header("typ", "dpop+jwt") |
66 | 62 | .build(); |
67 | | - JWSSigner signer = new RSASSASigner(privateKey); |
68 | 63 |
|
69 | 64 | Builder builder = |
70 | | - new Builder() |
71 | | - .jwtID(UUID.randomUUID().toString()) |
72 | | - .issueTime(new Date()) |
73 | | - .claim("htm", httpMethod) |
74 | | - .claim("htu", url); |
| 65 | + JwtClaimsSet.builder().issuedAt(Instant.now()).claim("htm", httpMethod).claim("htu", url); |
| 66 | + |
75 | 67 | if (ath != null) { |
76 | 68 | builder.claim("ath", ath); |
77 | 69 | } |
78 | 70 | if (nonce != null) { |
79 | 71 | builder.claim("nonce", nonce); |
80 | 72 | } |
81 | | - JWTClaimsSet claimsSet = builder.build(); |
| 73 | + JwtClaimsSet claims = builder.id(UUID.randomUUID().toString()).build(); |
82 | 74 |
|
83 | | - SignedJWT signedJWT = new SignedJWT(header, claimsSet); |
84 | | - signedJWT.sign(signer); |
85 | | - |
86 | | - return signedJWT.serialize(); |
| 75 | + Jwt jws = jwtEncoder.encode(JwtEncoderParameters.from(jwsHeader, claims)); |
| 76 | + return jws.getTokenValue(); |
87 | 77 | } catch (Exception e) { |
88 | 78 | log.error(e.getMessage(), e); |
89 | 79 | } |
90 | 80 |
|
91 | 81 | return null; |
92 | 82 | } |
93 | 83 |
|
94 | | - private static JWSAlgorithm resolveAlgorithm(JWK jwk) { |
95 | | - JWSAlgorithm jwsAlgorithm = null; |
96 | | - |
97 | | - if (KeyType.RSA.equals(jwk.getKeyType())) { |
98 | | - jwsAlgorithm = JWSAlgorithm.RS256; |
99 | | - } else if (KeyType.EC.equals(jwk.getKeyType())) { |
100 | | - jwsAlgorithm = JWSAlgorithm.ES256; |
101 | | - } else if (KeyType.OCT.equals(jwk.getKeyType())) { |
102 | | - jwsAlgorithm = JWSAlgorithm.HS256; |
103 | | - } |
104 | | - return jwsAlgorithm; |
105 | | - } |
106 | | - |
107 | 84 | private RSAPrivateKey getRsaPrivateKey(Registration registration) |
108 | 85 | throws IOException, NoSuchAlgorithmException, InvalidKeySpecException { |
109 | | - RSAPrivateKey privateKey; |
110 | | - if (registration.getPrivateKey().endsWith(".pem")) { |
111 | | - final String pem = Files.readString( |
112 | | - Path.of(PathResolver.getURI(registration.getPrivateKey()))); |
113 | | - privateKey = (RSAPrivateKey) CertificateUtils.getPrivateKey(pem); |
114 | | - } else if (registration.getPrivateKey().endsWith(".xml")) { |
115 | | - final String pem = XMLSec2PEM.getPem( |
116 | | - PathResolver.getInputStream(registration.getPrivateKey())); |
117 | | - privateKey = (RSAPrivateKey) CertificateUtils.getPrivateKey(pem); |
118 | | - } else if (registration.getPrivateKey().endsWith(".json")) { |
119 | | - final String pem = JWK2PEM.getPem(PathResolver.getInputStream(registration.getPrivateKey())); |
120 | | - privateKey = (RSAPrivateKey) CertificateUtils.getPrivateKey(pem); |
121 | | - } else { |
122 | | - final String pem = registration.getPrivateKey(); |
123 | | - privateKey = (RSAPrivateKey) CertificateUtils.getPrivateKey(pem); |
124 | | - } |
125 | | - return privateKey; |
| 86 | + String privateKeyValue = registration.getPrivateKey(); |
| 87 | + return CertificateUtils.getRsaPrivateKey(privateKeyValue); |
126 | 88 | } |
127 | 89 | } |
0 commit comments