Skip to content

Commit 511644f

Browse files
committed
WIP - Adding DPoP Auth scheme
1 parent 87e46e5 commit 511644f

File tree

1 file changed

+161
-0
lines changed
  • services/signin/src/main/java/software/amazon/awssdk/services/signin/internal

1 file changed

+161
-0
lines changed
Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
/*
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License").
5+
* You may not use this file except in compliance with the License.
6+
* A copy of the License is located at
7+
*
8+
* http://aws.amazon.com/apache2.0
9+
*
10+
* or in the "license" file accompanying this file. This file is distributed
11+
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12+
* express or implied. See the License for the specific language governing
13+
* permissions and limitations under the License.
14+
*/
15+
16+
package software.amazon.awssdk.services.signin.internal;
17+
18+
import java.security.interfaces.ECPrivateKey;
19+
import java.security.interfaces.ECPublicKey;
20+
import java.util.Collections;
21+
import java.util.List;
22+
import java.util.concurrent.CompletableFuture;
23+
import software.amazon.awssdk.core.SdkPlugin;
24+
import software.amazon.awssdk.core.SdkServiceClientConfiguration;
25+
import software.amazon.awssdk.http.auth.spi.scheme.AuthScheme;
26+
import software.amazon.awssdk.http.auth.spi.scheme.AuthSchemeOption;
27+
import software.amazon.awssdk.http.auth.spi.signer.AsyncSignRequest;
28+
import software.amazon.awssdk.http.auth.spi.signer.AsyncSignedRequest;
29+
import software.amazon.awssdk.http.auth.spi.signer.HttpSigner;
30+
import software.amazon.awssdk.http.auth.spi.signer.SignRequest;
31+
import software.amazon.awssdk.http.auth.spi.signer.SignedRequest;
32+
import software.amazon.awssdk.identity.spi.Identity;
33+
import software.amazon.awssdk.identity.spi.IdentityProvider;
34+
import software.amazon.awssdk.identity.spi.IdentityProviders;
35+
import software.amazon.awssdk.identity.spi.ResolveIdentityRequest;
36+
import software.amazon.awssdk.services.signin.SigninServiceClientConfiguration;
37+
import software.amazon.awssdk.services.signin.auth.scheme.SigninAuthSchemeParams;
38+
import software.amazon.awssdk.services.signin.auth.scheme.SigninAuthSchemeProvider;
39+
import software.amazon.awssdk.utils.Pair;
40+
import software.amazon.awssdk.utils.Validate;
41+
42+
public class DpopAuthScheme implements AuthScheme<DpopAuthScheme.DpopIdentity> {
43+
public static final String SCHEME_NAME = "DPOP";
44+
45+
private final DpopIdentityProvider identityProvider;
46+
47+
private DpopAuthScheme(DpopIdentityProvider identityProvider) {
48+
this.identityProvider = Validate.paramNotNull(identityProvider, "identityProvider");
49+
}
50+
51+
public static DpopAuthScheme create(ECPublicKey ecPublicKey) {
52+
return new DpopAuthScheme(DpopIdentityProvider.create(ecPublicKey));
53+
}
54+
55+
@Override
56+
public String schemeId() {
57+
return SCHEME_NAME;
58+
}
59+
60+
@Override
61+
public IdentityProvider<DpopIdentity> identityProvider(IdentityProviders providers) {
62+
// we don't currently support adding an arbitrary identityProvider as a request level override
63+
// return the identity provider configured up front instead
64+
return identityProvider;
65+
}
66+
67+
@Override
68+
public HttpSigner<DpopIdentity> signer() {
69+
return new DpopSigner();
70+
}
71+
72+
public static class DpopIdentity implements Identity {
73+
private final ECPublicKey publicKey;
74+
private final ECPrivateKey privateKey;
75+
76+
private DpopIdentity(ECPublicKey publicKey, ECPrivateKey privateKey) {
77+
this.publicKey = publicKey;
78+
this.privateKey = privateKey;
79+
}
80+
81+
public static DpopIdentity create(ECPublicKey publicKey, ECPrivateKey privateKey) {
82+
return new DpopIdentity(publicKey, privateKey);
83+
}
84+
85+
public static DpopIdentity create(String dpopKeyPem) {
86+
Pair<ECPrivateKey, ECPublicKey> keys = EcKeyLoader.loadSec1Pem(dpopKeyPem);
87+
return new DpopIdentity(keys.right(), keys.left());
88+
}
89+
90+
public ECPublicKey getPublicKey() {
91+
return publicKey;
92+
}
93+
94+
public ECPrivateKey getPrivateKey() {
95+
return privateKey;
96+
}
97+
}
98+
99+
private static class DpopSigner implements HttpSigner<DpopIdentity> {
100+
101+
@Override
102+
public SignedRequest sign(SignRequest<? extends DpopIdentity> request) {
103+
return SignedRequest.builder()
104+
.request(request.request())
105+
.payload(request.payload().orElse(null))
106+
.build();
107+
}
108+
109+
@Override
110+
public CompletableFuture<AsyncSignedRequest> signAsync(AsyncSignRequest<? extends DpopIdentity> request) {
111+
return CompletableFuture.completedFuture(
112+
AsyncSignedRequest.builder()
113+
.request(request.request())
114+
.payload(request.payload().orElse(null))
115+
.build());
116+
}
117+
}
118+
119+
private static class DpopIdentityProvider implements IdentityProvider<DpopIdentity> {
120+
private final DpopIdentity identity;
121+
122+
private DpopIdentityProvider(DpopIdentity identity) {
123+
this.identity = Validate.paramNotNull(identity, "identity");
124+
}
125+
126+
public static DpopIdentityProvider create(ECPublicKey ecPublicKey) {
127+
return new DpopIdentityProvider(DpopIdentity.create(ecPublicKey));
128+
}
129+
130+
@Override
131+
public Class<DpopIdentity> identityType() {
132+
return DpopIdentity.class;
133+
}
134+
135+
@Override
136+
public CompletableFuture<? extends DpopIdentity> resolveIdentity(ResolveIdentityRequest request) {
137+
return CompletableFuture.completedFuture(identity);
138+
}
139+
}
140+
141+
public static class DpopAuthSchemeResolver implements SigninAuthSchemeProvider {
142+
143+
@Override
144+
public List<AuthSchemeOption> resolveAuthScheme(SigninAuthSchemeParams authSchemeParams) {
145+
return Collections.singletonList(AuthSchemeOption.builder().schemeId(SCHEME_NAME).build());
146+
}
147+
}
148+
149+
public static class DpopAuthPlugin implements SdkPlugin {
150+
private final ECPublicKey ecPublicKey;
151+
152+
153+
@Override
154+
public void configureClient(SdkServiceClientConfiguration.Builder config) {
155+
SigninServiceClientConfiguration.Builder scb =
156+
Validate.isInstanceOf(SigninServiceClientConfiguration.Builder.class, config, "bad");
157+
scb.authSchemeProvider(new DpopAuthSchemeResolver());
158+
scb.putAuthScheme(new DpopAuthScheme());
159+
}
160+
}
161+
}

0 commit comments

Comments
 (0)