Sample Java source code
The Java source code below shows how to obtain an access token from Social Security OAuth server.
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.util.Base64;
import java.util.Properties;
import java.util.UUID;
import java.util.logging.Level;
import java.util.logging.Logger;
public class GetAccessToken {
private static final Logger logger = Logger.getLogger(GetAccessToken.class.getName());
/**
* Main method to generate an OAuth 2.0 token using client credentials grant.
* To run this program, provide the path to a properties file as a command line argument.
* The properties file should contain the following keys (and be adjusted accordingly to your environment)
* audience=https://services.socialsecurity.be/REST/oauth/v5/token
* authUrl=https://services.socialsecurity.be/REST/oauth/v5/token
* clientId=self_service_chaman_xxxxxxxxxxxxxxxx // replace with your client ID
* scope=scope:rsz-onss:socialdebt:retention:billretainment-rest:post-billretainment
* password=your-key-store-password // replace with your keystore password
* certificate=path-to-your-PKCS12-file // replace with the path to your PKCS12 file
* keyAlias=your key alias // replace with your key alias
*
* @param args Command line arguments should include the path to the properties file.
*/
public static void main(String[] args) {
Properties prop = new Properties();
try (FileInputStream fis = new FileInputStream(args[0])) {
prop.load(fis);
} catch (IOException e) {
logger.log(Level.SEVERE, e.getMessage(), e);
return;
}
// Extract necessary properties for OAuth token request
String audience = prop.getProperty("audience");
String authUrl = prop.getProperty("authUrl");
String clientId = prop.getProperty("clientId");
String scope = prop.getProperty("scope");
String password = prop.getProperty("password");
String certificate = prop.getProperty("certificate");
String keyAlias = prop.getProperty("keyAlias");
try {
// Generate and print the access token
String accessTokenResponse = getAccessToken(certificate, password, keyAlias, audience, clientId, authUrl, scope);
logger.log(Level.INFO, accessTokenResponse);
} catch (Exception ex) {
logger.log(Level.SEVERE,ex.getMessage(), ex);
}
}
/**
* Retrieves the access token using the provided parameters.
*
* @param certificate Path to the certificate file.
* @param password Certificate's password.
* @param keyAlias Alias of the private key within the certificate.
* @param audience Token endpoint audience.
* @param clientId Client ID for OAuth.
* @param authUrl Authorization server URL.
* @param scope OAuth scopes requested.
* @return A string containing the access token.
* @throws IOException If an I/O error occurs during communication with the OAuth server.
* @throws GeneralSecurityException If there is an issue with the private key or signature.
* @throws URISyntaxException If the URI is invalid.
*/
private static String getAccessToken(String certificate, String password, String keyAlias, String audience, String clientId, String authUrl, String scope)
throws IOException, GeneralSecurityException, URISyntaxException {
KeyStore keyStore = KeyStore.getInstance("PKCS12");
PrivateKey privateKey;
// Load the keystore and extract the private key
try (FileInputStream fis = new FileInputStream(certificate)) {
keyStore.load(fis, password.toCharArray());
privateKey = (PrivateKey) keyStore.getKey(keyAlias, password.toCharArray());
}
// Create a signed JWT for the OAuth authentication request
String jwt = createJWT(privateKey, clientId, audience);
// Send the JWT to the OAuth server and retrieve the access token
return doPostToAuthServer(jwt, new URI(authUrl), scope);
}
/**
* Creates a signed JWT for the OAuth authentication request.
*
* @param privateKey The private key used to sign the JWT.
* @param clientId The OAuth client ID.
* @param audience The audience for the token, usually the token URL.
* @return A signed JWT string.
* @throws NoSuchAlgorithmException If the RSA algorithm is not supported.
* @throws InvalidKeyException If the private key is invalid.
* @throws SignatureException If there is an issue with the signature.
* @throws InvalidKeyException If the private key is invalid.
*/
private static String createJWT(PrivateKey privateKey, String clientId, String audience) throws NoSuchAlgorithmException, InvalidKeyException, SignatureException {
long nowMillis = System.currentTimeMillis(); // Current time in milliseconds
long expMillis = nowMillis + 3600000; // JWT validity for 1 hour
String jti = UUID.randomUUID().toString(); // Unique identifier for each JWT
// Create the JWT header and payload
String header = "{\"alg\":\"RS256\",\"typ\":\"JWT\"}"; // JWT header
String payload = String.format(
"{\"iss\":\"%s\",\"sub\":\"%s\",\"aud\":\"%s\",\"exp\":%d,\"iat\":%d,\"jti\":\"%s\"}",
clientId, clientId, audience, expMillis / 1000, nowMillis / 1000, jti);
// Encode the header and payload
String encodedHeader = Base64.getUrlEncoder().withoutPadding().encodeToString(header.getBytes(StandardCharsets.UTF_8));
String encodedPayload = Base64.getUrlEncoder().withoutPadding().encodeToString(payload.getBytes(StandardCharsets.UTF_8));
// Concatenate the encoded header and payload
String assertion = encodedHeader + "." + encodedPayload;
// Sign the JWT using the RS256 algorithm
Signature signature = Signature.getInstance("SHA256withRSA");
signature.initSign(privateKey);
signature.update(assertion.getBytes(StandardCharsets.UTF_8));
byte[] signedAssertion = signature.sign();
// Encode the signature and append it to the assertion to create the final JWT
String encodedSignature = Base64.getUrlEncoder().withoutPadding().encodeToString(signedAssertion);
return assertion + "." + encodedSignature;
}
/**
* Sends a POST request to the OAuth server and retrieves the access token.
*
* @param jwt The JWT used for client assertion.
* @param authUri The URI of the OAuth server.
* @param scope The requested scope(s).
* @return The access token as a String.
* @throws IOException If an I/O error occurs during communication with the OAuth server.
*/
private static String doPostToAuthServer(String jwt, URI authUri, String scope) throws IOException {
// Create a connection to the OAuth server
URL url = new URL(authUri.toString());
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
connection.setDoOutput(true);
// Construct the request parameters
String params = String.format("grant_type=%s&client_assertion_type=%s&client_assertion=%s&scope=%s",
"client_credentials", "urn:ietf:params:oauth:client-assertion-type:jwt-bearer", jwt, scope);
// Send the request and read the response
try (DataOutputStream wr = new DataOutputStream(connection.getOutputStream())) {
wr.writeBytes(params);
wr.flush();
}
// Read the response from the server
StringBuilder response = new StringBuilder();
if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
try (BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()))) {
reader.lines().forEach(response::append);
}
} else {
// Read the error stream to capture any error messages from the server
try (BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getErrorStream()))) {
reader.lines().forEach(response::append);
}
}
return response.toString();
}
}