1515
1616package software .amazon .awssdk .services .signin .internal ;
1717
18- import java .security .interfaces .ECPrivateKey ;
19- import java .security .interfaces .ECPublicKey ;
20- import java .time .Instant ;
21- import java .util .Collections ;
22- import java .util .List ;
23- import java .util .UUID ;
24- import java .util .concurrent .CompletableFuture ;
25- import software .amazon .awssdk .core .SdkPlugin ;
26- import software .amazon .awssdk .core .SdkRequest ;
27- import software .amazon .awssdk .core .SdkServiceClientConfiguration ;
28- import software .amazon .awssdk .http .SdkHttpRequest ;
18+ import software .amazon .awssdk .annotations .SdkInternalApi ;
2919import software .amazon .awssdk .http .auth .spi .scheme .AuthScheme ;
30- import software .amazon .awssdk .http .auth .spi .scheme .AuthSchemeOption ;
31- import software .amazon .awssdk .http .auth .spi .signer .AsyncSignRequest ;
32- import software .amazon .awssdk .http .auth .spi .signer .AsyncSignedRequest ;
33- import software .amazon .awssdk .http .auth .spi .signer .BaseSignRequest ;
3420import software .amazon .awssdk .http .auth .spi .signer .HttpSigner ;
35- import software .amazon .awssdk .http .auth .spi .signer .SignRequest ;
36- import software .amazon .awssdk .http .auth .spi .signer .SignedRequest ;
37- import software .amazon .awssdk .identity .spi .Identity ;
3821import software .amazon .awssdk .identity .spi .IdentityProvider ;
3922import software .amazon .awssdk .identity .spi .IdentityProviders ;
40- import software .amazon .awssdk .identity .spi .ResolveIdentityRequest ;
41- import software .amazon .awssdk .services .signin .SigninServiceClientConfiguration ;
42- import software .amazon .awssdk .services .signin .auth .scheme .SigninAuthSchemeParams ;
43- import software .amazon .awssdk .services .signin .auth .scheme .SigninAuthSchemeProvider ;
44- import software .amazon .awssdk .utils .Pair ;
4523import software .amazon .awssdk .utils .Validate ;
46- import software .amazon .awssdk .utils .http .SdkHttpUtils ;
4724
48- public class DpopAuthScheme implements AuthScheme <DpopAuthScheme .DpopIdentity > {
25+ /**
26+ * An AuthScheme representing authentication withOAuth 2.0 Demonstrating Proof of Possession (DPoP) header.
27+ */
28+ @ SdkInternalApi
29+ public class DpopAuthScheme implements AuthScheme <DpopIdentity > {
4930 public static final String SCHEME_NAME = "DPOP" ;
5031
51- private final DpopIdentityProvider identityProvider ;
32+ private final IdentityProvider < DpopIdentity > identityProvider ;
5233
53- private DpopAuthScheme (DpopIdentityProvider identityProvider ) {
34+ private DpopAuthScheme (IdentityProvider < DpopIdentity > identityProvider ) {
5435 this .identityProvider = Validate .paramNotNull (identityProvider , "identityProvider" );
5536 }
5637
57- public static DpopAuthScheme create (DpopIdentityProvider identityProvider ) {
38+ public static DpopAuthScheme create (IdentityProvider < DpopIdentity > identityProvider ) {
5839 return new DpopAuthScheme (identityProvider );
5940 }
6041
@@ -74,129 +55,4 @@ public IdentityProvider<DpopIdentity> identityProvider(IdentityProviders provide
7455 public HttpSigner <DpopIdentity > signer () {
7556 return new DpopSigner ();
7657 }
77-
78- public static class DpopIdentity implements Identity {
79- private final ECPublicKey publicKey ;
80- private final ECPrivateKey privateKey ;
81-
82- private DpopIdentity (ECPublicKey publicKey , ECPrivateKey privateKey ) {
83- this .publicKey = publicKey ;
84- this .privateKey = privateKey ;
85- }
86-
87- public static DpopIdentity create (ECPublicKey publicKey , ECPrivateKey privateKey ) {
88- return new DpopIdentity (publicKey , privateKey );
89- }
90-
91- public static DpopIdentity create (String dpopKeyPem ) {
92- Pair <ECPrivateKey , ECPublicKey > keys = EcKeyLoader .loadSec1Pem (dpopKeyPem );
93- return new DpopIdentity (keys .right (), keys .left ());
94- }
95-
96- public ECPublicKey getPublicKey () {
97- return publicKey ;
98- }
99-
100- public ECPrivateKey getPrivateKey () {
101- return privateKey ;
102- }
103- }
104-
105- private static class DpopSigner implements HttpSigner <DpopIdentity > {
106-
107- @ Override
108- public SignedRequest sign (SignRequest <? extends DpopIdentity > request ) {
109- return SignedRequest .builder ()
110- .request (doSign (request ))
111- .payload (request .payload ().orElse (null ))
112- .build ();
113- }
114-
115- @ Override
116- public CompletableFuture <AsyncSignedRequest > signAsync (AsyncSignRequest <? extends DpopIdentity > request ) {
117- return CompletableFuture .completedFuture (
118- AsyncSignedRequest .builder ()
119- .request (doSign (request ))
120- .payload (request .payload ().orElse (null ))
121- .build ());
122- }
123-
124- /**
125- * Using {@link BaseSignRequest}, sign the request with a {@link BaseSignRequest} and re-build it.
126- */
127- private SdkHttpRequest doSign (BaseSignRequest <?, ? extends DpopIdentity > request ) {
128- return request .request ().toBuilder ()
129- .putHeader (
130- "DPoP" ,
131- buildDpopHeader (request ))
132- .build ();
133- }
134-
135- private String buildDpopHeader (BaseSignRequest <?, ? extends DpopIdentity > request ) {
136- SdkHttpRequest httpRequest = request .request ();
137- String endpoint = extractRequestEndpoint (httpRequest );
138- return DpopHeaderGenerator .generateDPoPProofHeader (
139- request .identity (), endpoint , httpRequest .method ().name (),
140- Instant .now ().getEpochSecond (), UUID .randomUUID ().toString ());
141- }
142-
143- private static String extractRequestEndpoint (SdkHttpRequest httpRequest ) {
144- // using SdkHttpRequest.getUri() results in creating a URI which is slow and we don't need the query components
145- // construct only the endpoint that we require for DPoP.
146- String portString =
147- SdkHttpUtils .isUsingStandardPort (httpRequest .protocol (), httpRequest .port ()) ? "" : ":" + httpRequest .port ();
148- return httpRequest .protocol () + "://" + httpRequest .host () + portString + httpRequest .encodedPath ();
149- }
150- }
151-
152- private static class DpopIdentityProvider implements IdentityProvider <DpopIdentity > {
153- private final DpopIdentity identity ;
154-
155- private DpopIdentityProvider (DpopIdentity identity ) {
156- this .identity = Validate .paramNotNull (identity , "identity" );
157- }
158-
159- public static DpopIdentityProvider create (String dpopKeyPem ) {
160- return new DpopIdentityProvider (DpopIdentity .create (dpopKeyPem ));
161- }
162-
163- @ Override
164- public Class <DpopIdentity > identityType () {
165- return DpopIdentity .class ;
166- }
167-
168- @ Override
169- public CompletableFuture <? extends DpopIdentity > resolveIdentity (ResolveIdentityRequest request ) {
170- return CompletableFuture .completedFuture (identity );
171- }
172- }
173-
174- public static class DpopAuthSchemeResolver implements SigninAuthSchemeProvider {
175-
176- @ Override
177- public List <AuthSchemeOption > resolveAuthScheme (SigninAuthSchemeParams authSchemeParams ) {
178- return Collections .singletonList (AuthSchemeOption .builder ().schemeId (SCHEME_NAME ).build ());
179- }
180- }
181-
182- public static class DpopAuthPlugin implements SdkPlugin {
183- private final String dpopKeyPem ;
184-
185- private DpopAuthPlugin (String dpopKeyPem ) {
186- this .dpopKeyPem = Validate .paramNotNull (dpopKeyPem , "dpopKeyPem" );
187- }
188-
189- public static DpopAuthPlugin create (String dpopKeyPem ) {
190- return new DpopAuthPlugin (dpopKeyPem );
191- }
192-
193- @ Override
194- public void configureClient (SdkServiceClientConfiguration .Builder config ) {
195- SigninServiceClientConfiguration .Builder scb =
196- Validate .isInstanceOf (SigninServiceClientConfiguration .Builder .class , config ,
197- "DpopAuthPlugin must be applied to a SigninServiceClient" );
198- scb .authSchemeProvider (new DpopAuthSchemeResolver ());
199- scb .putAuthScheme (DpopAuthScheme .create (DpopIdentityProvider .create (dpopKeyPem )));
200- }
201- }
20258}
0 commit comments