Skip to content
This repository was archived by the owner on Apr 10, 2025. It is now read-only.

Commit 46aedfd

Browse files
committed
fix: use new code exchange endpoint
1 parent 875f664 commit 46aedfd

File tree

13 files changed

+135
-30
lines changed

13 files changed

+135
-30
lines changed

src/main/java/be/nicholasmeyers/vwgroupconnector/resource/StartAuthorization.java

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,15 @@ public class StartAuthorization {
44
private final String cookie;
55
private final String relayState;
66
private final String loginUrl;
7+
private final String redirectUrl;
8+
private final String codeVerifier;
79

8-
public StartAuthorization(String cookie, String relayState, String loginUrl) {
10+
public StartAuthorization(String cookie, String relayState, String loginUrl, String redirectUrl, String codeVerifier) {
911
this.cookie = cookie;
1012
this.relayState = relayState;
1113
this.loginUrl = loginUrl;
14+
this.redirectUrl = redirectUrl;
15+
this.codeVerifier = codeVerifier;
1216
}
1317

1418
public String getCookie() {
@@ -22,4 +26,12 @@ public String getRelayState() {
2226
public String getLoginUrl() {
2327
return loginUrl;
2428
}
29+
30+
public String getRedirectUrl() {
31+
return redirectUrl;
32+
}
33+
34+
public String getCodeVerifier() {
35+
return codeVerifier;
36+
}
2537
}

src/main/java/be/nicholasmeyers/vwgroupconnector/resource/TokenInfo.java

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,24 @@
22

33
public class TokenInfo {
44
private final String authCode;
5-
private final String idToken;
5+
private final String redirectUri;
6+
private final String verifier;
67

7-
public TokenInfo(String authCode, String idToken) {
8+
public TokenInfo(String authCode, String redirectUri, String verifier) {
89
this.authCode = authCode;
9-
this.idToken = idToken;
10+
this.redirectUri = redirectUri;
11+
this.verifier = verifier;
1012
}
1113

1214
public String getAuthCode() {
1315
return authCode;
1416
}
1517

16-
public String getIdToken() {
17-
return idToken;
18+
public String getRedirectUri() {
19+
return redirectUri;
20+
}
21+
22+
public String getVerifier() {
23+
return verifier;
1824
}
1925
}

src/main/java/be/nicholasmeyers/vwgroupconnector/resource/Tokens.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,12 @@
33
public class Tokens {
44
private final String accessToken;
55
private final String idToken;
6+
private final String refreshToken;
67

7-
public Tokens(String accessToken, String idToken) {
8+
public Tokens(String accessToken, String idToken, String refreshToken) {
89
this.accessToken = accessToken;
910
this.idToken = idToken;
11+
this.refreshToken = refreshToken;
1012
}
1113

1214
public String getAccessToken() {
@@ -16,4 +18,8 @@ public String getAccessToken() {
1618
public String getIdToken() {
1719
return idToken;
1820
}
21+
22+
public String getRefreshToken() {
23+
return refreshToken;
24+
}
1925
}

src/main/java/be/nicholasmeyers/vwgroupconnector/service/ConnectorService.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ public Tokens getTokens(Client client, String email, String password) {
5656

5757
if (Client.VWG.equals(client)) {
5858
String idToken = tokenService.getTokens(tokenInfo).getIdToken();
59-
Tokens tokens = new Tokens(vwgService.getAccessToken(idToken), idToken);
59+
Tokens tokens = new Tokens(vwgService.getAccessToken(idToken), idToken, "");
6060
cache.put(client, tokens);
6161
return tokens;
6262
} else {

src/main/java/be/nicholasmeyers/vwgroupconnector/utils/ClientUtils.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,12 @@ public static Map<String, String> getClientConfig(String client) {
1717
private static Map<String, Map<String, String>> getClients() {
1818
Map<String, String> connect = new HashMap<>();
1919
connect.put("client_id", "7f045eee-7003-4379-9968-9355ed2adb06@apps_vw-dilab_com");
20-
connect.put("scope", "openid profile address cars email birthdate badge mbb phone driversLicense dealers profession vin");
20+
connect.put("scope", "openid profile address cars email birthdate badge mbb phone driversLicense nationalIdentifier dealers mileage profession vin");
2121
connect.put("token_types", "code id_token");
2222

2323
Map<String, String> vwg = new HashMap<>();
2424
vwg.put("client_id", "7f045eee-7003-4379-9968-9355ed2adb06@apps_vw-dilab_com");
25-
vwg.put("scope", "openid profile address cars email birthdate badge mbb phone driversLicense dealers profession vin");
25+
vwg.put("scope", "openid profile address cars email birthdate badge mbb phone driversLicense nationalIdentifier dealers mileage profession vin");
2626
vwg.put("token_types", "code id_token");
2727

2828
Map<String, String> skoda = new HashMap<>();

src/main/java/be/nicholasmeyers/vwgroupconnector/web/out/IdentityClientImpl.java

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@
1414
import org.apache.commons.codec.binary.Base64;
1515

1616
import java.io.IOException;
17+
import java.nio.charset.StandardCharsets;
18+
import java.security.MessageDigest;
19+
import java.security.NoSuchAlgorithmException;
20+
import java.security.SecureRandom;
1721
import java.util.Date;
1822
import java.util.HashMap;
1923
import java.util.Map;
@@ -49,19 +53,32 @@ public OpenidConfiguration getConfiguration() {
4953

5054
@Override
5155
public StartAuthorization getAuthorizationEndpoint(String redirectUri, String client, String scope, String responseType) {
56+
String codeVerifier = generateCodeVerifier();
57+
String codeChallenge = "";
58+
59+
try {
60+
codeChallenge = generateCodeChallenge(codeVerifier);
61+
} catch (NoSuchAlgorithmException e) {
62+
throw new RuntimeException(e);
63+
}
64+
5265
Map<String, String> query = new HashMap<>();
5366
query.put("redirect_uri", redirectUri);
5467
query.put("client_id", client);
5568
query.put("scope", scope);
5669
query.put("response_type", responseType);
5770
query.put("nonce", getNonce());
71+
query.put("code_challenge", codeChallenge);
72+
query.put("code_challenge_method", "s256");
73+
query.put("prompt", "login");
74+
5875
Response response = identityClient.getAuthorizationEndpoint(query);
5976
response.close();
6077
String location = getLocationHeader(response.headers());
6178
String cookie = getCookieHeader(response.headers());
6279
cookie = cookie.substring(0, cookie.indexOf(";"));
6380
String relayState = location.substring(location.indexOf("?relayState") + 12);
64-
return new StartAuthorization(cookie, relayState, location);
81+
return new StartAuthorization(cookie, relayState, location, redirectUri, codeVerifier);
6582
}
6683

6784
@Override
@@ -208,7 +225,7 @@ public TokenInfo handleSuccess(String client, StartAuthorization startAuthorizat
208225

209226
String idToken = location.substring(location.indexOf("id_token") + 9);
210227

211-
return new TokenInfo(authCode, idToken);
228+
return new TokenInfo(authCode, startAuthorization.getRedirectUrl(), startAuthorization.getCodeVerifier());
212229
}
213230

214231
private String getNonce() {
@@ -224,4 +241,21 @@ private String getResponseBody(Response.Body body) {
224241
throw new RuntimeException(e);
225242
}
226243
}
244+
245+
private static String generateCodeVerifier() {
246+
SecureRandom random = new SecureRandom();
247+
byte[] codeVerifier = new byte[32];
248+
random.nextBytes(codeVerifier);
249+
return base64UrlEncode(codeVerifier);
250+
}
251+
252+
private static String generateCodeChallenge(String codeVerifier) throws NoSuchAlgorithmException {
253+
MessageDigest digest = MessageDigest.getInstance("SHA-256");
254+
byte[] hash = digest.digest(codeVerifier.getBytes(StandardCharsets.UTF_8));
255+
return base64UrlEncode(hash);
256+
}
257+
258+
private static String base64UrlEncode(byte[] input) {
259+
return java.util.Base64.getUrlEncoder().withoutPadding().encodeToString(input);
260+
}
227261
}
Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
package be.nicholasmeyers.vwgroupconnector.web.out;
22

3+
import be.nicholasmeyers.vwgroupconnector.web.out.resource.CodeExchangeWebRequestResource;
34
import be.nicholasmeyers.vwgroupconnector.web.out.resource.TokenWebResponseResource;
4-
import feign.*;
5+
import feign.Headers;
6+
import feign.RequestLine;
57

68
public interface TokenClient {
7-
@RequestLine("POST /exchangeAuthCode")
8-
@Headers("Content-Type: application/x-www-form-urlencoded")
9-
TokenWebResponseResource getTokens(@Param("auth_code") String authCode, @Param("id_token") String idToken, @Param("brand") String brand);
9+
@RequestLine("POST /api/v1/authentication/exchange-authorization-code?tokenType=CONNECT")
10+
@Headers("Content-Type: application/json")
11+
TokenWebResponseResource getTokens(CodeExchangeWebRequestResource codeExchangeWebRequestResource);
1012
}

src/main/java/be/nicholasmeyers/vwgroupconnector/web/out/TokenClientImpl.java

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@
33
import be.nicholasmeyers.vwgroupconnector.resource.TokenInfo;
44
import be.nicholasmeyers.vwgroupconnector.resource.Tokens;
55
import be.nicholasmeyers.vwgroupconnector.service.TokenService;
6+
import be.nicholasmeyers.vwgroupconnector.web.out.resource.CodeExchangeWebRequestResource;
67
import be.nicholasmeyers.vwgroupconnector.web.out.resource.TokenWebResponseResource;
78
import feign.Feign;
8-
import feign.form.FormEncoder;
99
import feign.jackson.JacksonDecoder;
1010
import feign.jackson.JacksonEncoder;
1111

@@ -14,14 +14,18 @@ public class TokenClientImpl implements TokenService {
1414

1515
public TokenClientImpl() {
1616
this.tokenClient = Feign.builder()
17-
.encoder(new FormEncoder(new JacksonEncoder()))
17+
.encoder(new JacksonEncoder())
1818
.decoder(new JacksonDecoder())
19-
.target(TokenClient.class, "https://tokenrefreshservice.apps.emea.vwapps.io");
19+
.target(TokenClient.class, "https://mysmob.api.connect.skoda-auto.cz");
2020
}
2121

2222
@Override
2323
public Tokens getTokens(TokenInfo tokenInfo) {
24-
TokenWebResponseResource webResponseResource = tokenClient.getTokens(tokenInfo.getAuthCode(), tokenInfo.getIdToken(), "skoda");
25-
return new Tokens(webResponseResource.getAccessToken(), webResponseResource.getIdToken());
24+
CodeExchangeWebRequestResource codeExchangeWebRequestResource = new CodeExchangeWebRequestResource();
25+
codeExchangeWebRequestResource.setCode(tokenInfo.getAuthCode());
26+
codeExchangeWebRequestResource.setRedirectUri(tokenInfo.getRedirectUri());
27+
codeExchangeWebRequestResource.setVerifier(tokenInfo.getVerifier());
28+
TokenWebResponseResource webResponseResource = tokenClient.getTokens(codeExchangeWebRequestResource);
29+
return new Tokens(webResponseResource.getAccessToken(), webResponseResource.getIdToken(), webResponseResource.getRefreshToken());
2630
}
2731
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package be.nicholasmeyers.vwgroupconnector.web.out.resource;
2+
3+
public class CodeExchangeWebRequestResource {
4+
private String code;
5+
private String redirectUri;
6+
private String verifier;
7+
8+
public String getCode() {
9+
return code;
10+
}
11+
12+
public void setCode(String code) {
13+
this.code = code;
14+
}
15+
16+
public String getRedirectUri() {
17+
return redirectUri;
18+
}
19+
20+
public void setRedirectUri(String redirectUri) {
21+
this.redirectUri = redirectUri;
22+
}
23+
24+
public String getVerifier() {
25+
return verifier;
26+
}
27+
28+
public void setVerifier(String verifier) {
29+
this.verifier = verifier;
30+
}
31+
}

src/main/java/be/nicholasmeyers/vwgroupconnector/web/out/resource/TokenWebResponseResource.java

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,9 @@
11
package be.nicholasmeyers.vwgroupconnector.web.out.resource;
22

3-
import com.fasterxml.jackson.annotation.JsonProperty;
4-
53
public class TokenWebResponseResource {
6-
@JsonProperty("access_token")
74
private String accessToken;
8-
@JsonProperty("id_token")
95
private String idToken;
6+
private String refreshToken;
107

118
public String getAccessToken() {
129
return accessToken;
@@ -23,4 +20,12 @@ public String getIdToken() {
2320
public void setIdToken(String idToken) {
2421
this.idToken = idToken;
2522
}
23+
24+
public String getRefreshToken() {
25+
return refreshToken;
26+
}
27+
28+
public void setRefreshToken(String refreshToken) {
29+
this.refreshToken = refreshToken;
30+
}
2631
}

0 commit comments

Comments
 (0)