|
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