Code voorbeelden
Genereer 'authorize' urls en ontvang de code
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Base64;
import java.util.List;
import java.util.UUID;
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpServer;
public class AuthorizeUrlGenerator {
private static final String CODE_CHALLENGE_METHOD = "S256";
private static final String AUTHORIZATION_SERVER = "https://www.acc.mijnenergiedata.nl/autorisatieregister/oauth2/authorize";
private static final String CLIENT_ID = "testClientBulkScope";
private static final String DATA_PRODUCT_SCOPE = "client-alleen-doorlopend";
private static final String REDIRECT_URI = "http://localhost:8000/callback";
private final List<String> huisnummers = List.of("8");
public static void main(String[] args) {
AuthorizeUrlGenerator authorizeUrlGenerator = new AuthorizeUrlGenerator();
authorizeUrlGenerator.generateUrl();
authorizeUrlGenerator.startWebserver();
}
private void generateUrl() {
// voor iedere url hetzelfde
StringBuilder builder = new StringBuilder(AUTHORIZATION_SERVER)
.append("?").append("response_type=code")
.append("&").append("client_id=").append(CLIENT_ID)
.append("&").append("redirect_uri=").append(REDIRECT_URI)
.append("&").append("scope=").append(DATA_PRODUCT_SCOPE);
// per url anders
List<String> authorizeUrls = huisnummers.stream().map(huisnummer -> {
builder.append("&").append("state=").append(UUID.randomUUID())
.append("&").append("verify=").append(huisnummer)
.append("&").append("code_challenge=").append(generateCodeChallenge(generateCodeVerifier()))
.append("&").append("code_challenge_method=").append(CODE_CHALLENGE_METHOD);
return builder.toString();
}).toList();
authorizeUrls.forEach(System.out::println);
}
private void startWebserver(){
try {
HttpServer server = HttpServer.create(new InetSocketAddress(8000), 0);
// Create a context for a specific path and set the handler
server.createContext("/callback", new MyHandler());
// Start the server
server.setExecutor(null); // Use the default executor
server.start();
System.out.println("Server is running on port 8000");
} catch (IOException e) {
throw new RuntimeException(e);
}
}
static class MyHandler implements HttpHandler {
@Override
public void handle(HttpExchange exchange) throws IOException
{
// handle the request
String query = exchange.getRequestURI().getQuery();
String response = "Code ontvangen " + query;
exchange.sendResponseHeaders(200, response.length());
OutputStream os = exchange.getResponseBody();
os.write(response.getBytes());
os.close();
}
}
private String generateCodeVerifier() {
java.security.SecureRandom secureRandom = new SecureRandom();
byte[] codeVerifier = new byte[32];
secureRandom.nextBytes(codeVerifier);
return Base64.getUrlEncoder().withoutPadding().encodeToString(codeVerifier);
}
private String generateCodeChallenge(String codeVerifier) {
try {
byte[] bytes = codeVerifier.getBytes(StandardCharsets.US_ASCII);
MessageDigest messageDigest = MessageDigest.getInstance("SHA-256");
messageDigest.update(bytes, 0, bytes.length);
byte[] digest = messageDigest.digest();
return Base64.getUrlEncoder().withoutPadding().encodeToString(digest);
} catch (NoSuchAlgorithmException e) {
throw new IllegalStateException("Cannot generate code challenge", e);
}
}
}
Genereer een client-assertion
import java.io.File;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.Signature;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import java.util.UUID;
public class GenerateClientAssertion {
private static final String AUTORISATIEREGISTER = "https://www.mijnenergiedata.nl/autorisatieregister";
private static final String CLIENT_ID = "demo-client-id";
private static final String ISSUER = CLIENT_ID;
private static final String SUBJECT = CLIENT_ID;
private static final String KEY_ID = "new-demo-key-id";
private static final String PRIVATE_KEY_FILE_NAME = "demo-private.pem";
private static final String DOT = ".";
private static final String HEADER_TEMPLATE = "{\"alg\":\"RS256\", \"kid\": \"%s\"}";
private static final String BODY_TEMPLATE = "{\"iss\": \"%s\", \"sub\": \"%s\", \"aud\": \"%s\", \"exp\": %s, \"jti\": \"%s\"}";
public String generateClientAssertion() {
Base64.Encoder encoder = Base64.getUrlEncoder().withoutPadding();
StringBuilder token = new StringBuilder();
try {
// Prepare claims
Long exp = (System.currentTimeMillis() / 1000) + 60 * 15;
String jti = UUID.randomUUID().toString();
String payload = String.format(BODY_TEMPLATE, ISSUER, SUBJECT, AUTORISATIEREGISTER, exp, jti);
// Build token
token.append(encoder.encodeToString(HEADER_TEMPLATE.formatted(KEY_ID).getBytes(StandardCharsets.UTF_8)))
.append(DOT)
.append(encoder.encodeToString(payload.getBytes(StandardCharsets.UTF_8)));
String headerAndPayload = token.toString();
token.append(DOT).append(encoder.encodeToString(signPayload(headerAndPayload)));
return token.toString();
} catch (Exception e) {
System.out.println(e.getMessage());
}
return null;
}
private byte[] signPayload(String payload) throws Exception {
File keyFile = new File(PRIVATE_KEY_FILE_NAME);
if (!keyFile.exists()) {
throw new Exception("private key not found");
}
String key = Files.readString(keyFile.toPath(), Charset.defaultCharset());
String privateKeyPEM = key.replace("-----BEGIN PRIVATE KEY-----", "")
.replaceAll(System.lineSeparator(), "")
.replace("-----END PRIVATE KEY-----", "");
byte[] base64DecodedPrivateKey = Base64.getDecoder().decode(privateKeyPEM);
PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(base64DecodedPrivateKey);
KeyFactory kf = KeyFactory.getInstance("RSA");
PrivateKey privateKey = kf.generatePrivate(spec);
Signature signature = Signature.getInstance("SHA256withRSA");
signature.initSign(privateKey);
signature.update(payload.getBytes(StandardCharsets.UTF_8));
return signature.sign();
}
}