-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathOidcService.java
More file actions
76 lines (63 loc) · 3.15 KB
/
Copy pathOidcService.java
File metadata and controls
76 lines (63 loc) · 3.15 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
package fr.insee.genesis.infrastructure.utils.http;
import fr.insee.genesis.configuration.Config;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.HttpStatusCodeException;
import org.springframework.web.client.RestTemplate;
import java.io.IOException;
import java.util.Map;
@Service
@Slf4j
public class OidcService {
public static final String ACCESS_TOKEN = "access_token";
@Getter
private final Config config;
private String serviceAccountToken;
private long tokenExpirationTime = 0;
private final RestTemplate restTemplate;
public OidcService(Config config) {
this.restTemplate = new RestTemplate();
this.config = config;
}
protected void retrieveServiceAccountToken() throws IOException {
String tokenUrl = String.format("%s/realms/%s/protocol/openid-connect/token",
config.getAuthServerUrl(),
config.getRealm());
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
String body = String.format("grant_type=client_credentials&client_id=%s&client_secret=%s&scope=openid profile roles",
config.getServiceClientId(),
config.getServiceClientSecret());
HttpEntity<String> request = new HttpEntity<>(body, headers);
try {
ResponseEntity<Map> response = restTemplate.postForEntity(tokenUrl, request, Map.class);
if (response.getStatusCode().is2xxSuccessful() && response.hasBody() && response.getBody() != null) {
Map<String, Object> responseBody = response.getBody();
if (responseBody == null || !responseBody.containsKey(ACCESS_TOKEN) || !(responseBody.get(ACCESS_TOKEN) instanceof String)) {
throw new IOException("Invalid response: Missing or incorrect 'access_token'");
}
serviceAccountToken = (String) responseBody.get(ACCESS_TOKEN);
Integer expiresIn = (Integer) responseBody.get("expires_in");
tokenExpirationTime = System.currentTimeMillis() + (expiresIn.longValue() * 1000L);
} else {
throw new IOException("Failed to retrieve service account token, status: " + response.getStatusCode());
}
} catch (HttpStatusCodeException e) {
throw new IOException("HTTP error: " + e.getStatusCode() + " - " + e.getResponseBodyAsString(), e);
} catch (Exception e) {
throw new IOException("Unexpected error while fetching token: " + e.getMessage(), e);
}
}
public synchronized String getServiceAccountToken() throws IOException {
//We had a margin of 5 seconds for the expiration time
if (serviceAccountToken == null || System.currentTimeMillis() >= tokenExpirationTime - 5000L) {
retrieveServiceAccountToken();
}
return serviceAccountToken;
}
}