|
3 | 3 |
|
4 | 4 | package com.microsoft.aad.msal4j;
|
5 | 5 |
|
6 |
| -import com.nimbusds.oauth2.sdk.ParseException; |
7 |
| -import com.nimbusds.oauth2.sdk.auth.*; |
8 |
| -import com.nimbusds.oauth2.sdk.id.ClientID; |
9 | 6 | import org.slf4j.LoggerFactory;
|
10 | 7 |
|
11 |
| -import java.util.*; |
12 | 8 | import java.util.concurrent.CompletableFuture;
|
13 | 9 | import java.util.function.Function;
|
14 | 10 |
|
|
23 | 19 | */
|
24 | 20 | public class ConfidentialClientApplication extends AbstractClientApplicationBase implements IConfidentialClientApplication {
|
25 | 21 |
|
26 |
| - private ClientAuthentication clientAuthentication; |
27 |
| - |
28 |
| - private boolean clientCertAuthentication = false; |
29 | 22 | private ClientCertificate clientCertificate;
|
| 23 | + String assertion; |
| 24 | + String secret; |
30 | 25 |
|
31 | 26 | /** AppTokenProvider creates a Credential from a function that provides access tokens. The function
|
32 | 27 | must be concurrency safe. This is intended only to allow the Azure SDK to cache MSI tokens. It isn't
|
@@ -87,65 +82,31 @@ private void initClientAuthentication(IClientCredential clientCredential) {
|
87 | 82 | validateNotNull("clientCredential", clientCredential);
|
88 | 83 |
|
89 | 84 | if (clientCredential instanceof ClientSecret) {
|
90 |
| - clientAuthentication = new ClientSecretPost( |
91 |
| - new ClientID(clientId()), |
92 |
| - new Secret(((ClientSecret) clientCredential).clientSecret())); |
| 85 | + this.secret = ((ClientSecret) clientCredential).clientSecret(); |
93 | 86 | } else if (clientCredential instanceof ClientCertificate) {
|
94 |
| - this.clientCertAuthentication = true; |
95 | 87 | this.clientCertificate = (ClientCertificate) clientCredential;
|
96 |
| - clientAuthentication = buildValidClientCertificateAuthority(); |
| 88 | + this.assertion = getAssertionString(clientCredential); |
97 | 89 | } else if (clientCredential instanceof ClientAssertion) {
|
98 |
| - clientAuthentication = createClientAuthFromClientAssertion((ClientAssertion) clientCredential); |
| 90 | + this.assertion = getAssertionString(clientCredential); |
99 | 91 | } else {
|
100 | 92 | throw new IllegalArgumentException("Unsupported client credential");
|
101 | 93 | }
|
102 | 94 | }
|
103 | 95 |
|
104 |
| - @Override |
105 |
| - protected ClientAuthentication clientAuthentication() { |
106 |
| - if (clientCertAuthentication) { |
107 |
| - final Date currentDateTime = new Date(System.currentTimeMillis()); |
108 |
| - final Date expirationTime = ((PrivateKeyJWT) clientAuthentication).getJWTAuthenticationClaimsSet().getExpirationTime(); |
109 |
| - if (expirationTime.before(currentDateTime)) { |
110 |
| - clientAuthentication = buildValidClientCertificateAuthority(); |
111 |
| - } |
112 |
| - } |
113 |
| - return clientAuthentication; |
114 |
| - } |
| 96 | + String getAssertionString(IClientCredential clientCredential) { |
| 97 | + if (clientCredential instanceof ClientCertificate) { |
| 98 | + boolean useSha1 = Authority.detectAuthorityType(this.authenticationAuthority.canonicalAuthorityUrl()) == AuthorityType.ADFS; |
115 | 99 |
|
116 |
| - private ClientAuthentication buildValidClientCertificateAuthority() { |
117 |
| - //The library originally used SHA-1 for thumbprints as other algorithms were not supported server-side. |
118 |
| - //When this was written support for SHA-256 had been added, however ADFS scenarios still only allowed SHA-1. |
119 |
| - boolean useSha1 = Authority.detectAuthorityType(this.authenticationAuthority.canonicalAuthorityUrl()) == AuthorityType.ADFS; |
120 |
| - |
121 |
| - ClientAssertion clientAssertion = JwtHelper.buildJwt( |
122 |
| - clientId(), |
123 |
| - clientCertificate, |
124 |
| - this.authenticationAuthority.selfSignedJwtAudience(), |
125 |
| - sendX5c, |
126 |
| - useSha1); |
127 |
| - return createClientAuthFromClientAssertion(clientAssertion); |
128 |
| - } |
129 |
| - |
130 |
| - protected ClientAuthentication createClientAuthFromClientAssertion( |
131 |
| - final ClientAssertion clientAssertion) { |
132 |
| - final Map<String, List<String>> map = new HashMap<>(); |
133 |
| - try { |
134 |
| - |
135 |
| - map.put("client_assertion_type", Collections.singletonList(ClientAssertion.assertionType)); |
136 |
| - map.put("client_assertion", Collections.singletonList(clientAssertion.assertion())); |
137 |
| - return PrivateKeyJWT.parse(map); |
138 |
| - } catch (final ParseException e) { |
139 |
| - //This library is not supposed to validate Issuer and subject values. |
140 |
| - //The next lines of code ensures that exception is not thrown. |
141 |
| - if (e.getMessage().contains("Issuer and subject in client JWT assertion must designate the same client identifier")) { |
142 |
| - return new CustomJWTAuthentication( |
143 |
| - ClientAuthenticationMethod.PRIVATE_KEY_JWT, |
144 |
| - clientAssertion, |
145 |
| - new ClientID(clientId()) |
146 |
| - ); |
147 |
| - } |
148 |
| - throw new MsalClientException(e); |
| 100 | + return JwtHelper.buildJwt( |
| 101 | + clientId(), |
| 102 | + clientCertificate, |
| 103 | + this.authenticationAuthority.selfSignedJwtAudience(), |
| 104 | + sendX5c, |
| 105 | + useSha1).assertion(); |
| 106 | + } else if (clientCredential instanceof ClientAssertion) { |
| 107 | + return ((ClientAssertion) clientCredential).assertion(); |
| 108 | + } else { |
| 109 | + throw new IllegalArgumentException("Unsupported client credential"); |
149 | 110 | }
|
150 | 111 | }
|
151 | 112 |
|
|
0 commit comments