Terug

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();
    }
}