1 of 11

PKCE-enhanced Authorization Code

PKCE - Proof Key for Code Exchange

2 of 11

User

Mobile App

Connect to

API Service

API Service

Facebook, Google, �Your API

Authorization Server

Authorization request

?response_type=code&scope={Scopes}&state={CSRF}&...

GET /authorize

?response_type=code // Required. Must be “code”&state=hv8hf0h2i7d // Recommended

&redirect_uri= {Redirect uri} // Optional

&scope={Scopes} // Optional

&client_id={Client Id} // Required

&code_challenge=-sUEoAV-txYvhniiuJ4-gwNCtsiD2XiIPvLQYm-sUsE

&code_challenge_method=S256

code_verifier = jWJS7olsI78LF-hcNHO1QBMqVX06iN5Z837vD6UXO3g

or “plain”

3 of 11

User

Mobile App

Connect to

API Service

API Service

Tap

Facebook, Google, �Your API

Authorization Server

Authorization request

?response_type=code&scope={Scopes}&state={CSRF}&...

Response

http://localhost:8083/callback

?state=h4u8fF2okGBio38uE &code=b06c44f3-71be-4525-81f8-9c88472154c6.20af20a8-7146-4a97-a636-a59c784ad59b.0c9b74af-f0cb-48b8-9762-1bd23841c73a

curl --location --request POST 'http://localhost:8080/auth/realms/appsdeveloperblog/protocol/openid-connect/token' 'code=b06c44f3-71be-4525-81f8-9c88472154c6.20af20a8-7146-4a97-a636-a59c784ad59b.0c9b74af-f0cb-48b8-9762-1bd23841c73a' 'code_verifier=c3cxd2UzNHJmZGUzNHJneWh1NzhpazFxd2U0cmZkZXI1Nnl1N3lnZnJ0NmpraW85NHJkc3dlcg'

4 of 11

curl --location --request GET 'http://localhost:8080/auth/realms/appsdeveloperblog/protocol/openid-connect/auth

?client_id=photo-app-pkce

&response_type=code

&scope=openid

&redirect_uri=http://localhost:8083/callback

&state=h4u8fF2okGBio38uE

&code_challenge=NDEyYjM0YzhkZTZhNWVlMzE3YWVjYmJkZWJiYTg4ZDFhMTIxNjQyMGQwZTU0NjE1NjlmZjMzNTg0NzkwODVlYQ

&code_challenge_method=S256'

Request for an OAuth Code

5 of 11

curl --location --request POST 'http://localhost:8080/auth/realms/appsdeveloperblog/protocol/openid-connect/token' \

--header 'Content-Type: application/x-www-form-urlencoded' \

--data-urlencode 'grant_type=authorization_code' \

--data-urlencode 'client_id=photo-app-pkce' \

--data-urlencode 'code=b06c44f3-71be-4525-81f8-9c88472154c6.20af20a8-7146-4a97-a636-a59c784ad59b.0c9b74af-f0cb-48b8-9762-1bd23841c73a' \

--data-urlencode 'redirect_uri=http://localhost:8083/callback' \

--data-urlencode 'code_verifier=c3cxd2UzNHJmZGUzNHJneWh1NzhpazFxd2U0cmZkZXI1Nnl1N3lnZnJ0NmpraW85NHJkc3dlcg'

Exchange OAuth Code for an Access Token

6 of 11

Generating

Code Verifier

7 of 11

8 of 11

package com.appsdeveloperblog.pkce;

import java.io.UnsupportedEncodingException;

import java.security.MessageDigest;

import java.security.NoSuchAlgorithmException;

import java.security.SecureRandom;

import java.util.Base64;

public class PkceUtil {

String generateCodeVerifier() throws UnsupportedEncodingException {

SecureRandom secureRandom = new SecureRandom();

byte[] codeVerifier = new byte[32];

secureRandom.nextBytes(codeVerifier);

return Base64.getUrlEncoder().withoutPadding().encodeToString(codeVerifier);

}

}

5GIuDRih4mQPRoG4C4WylsHp0l--aBbOcwGO1MPEfLA

9 of 11

Generating

Code Challenge

10 of 11

1

2

3

4

11 of 11

String generateCodeChallange(String codeVerifier) throws UnsupportedEncodingException, NoSuchAlgorithmException {�

byte[] bytes = codeVerifier.getBytes("US-ASCII");

MessageDigest messageDigest = MessageDigest.getInstance("SHA-256");

messageDigest.update(bytes, 0, bytes.length);

byte[] digest = messageDigest.digest();

return Base64.getUrlEncoder().withoutPadding().encodeToString(digest);�

}

ZQNn8kfypf2X6j0HFdoApXgndA1LJr2-jm6kKJgsNDQ