I am attempting to migrate the logic of the reference ATProtocol SDK into Java. I've simplified the reproduction of the error I'm seeing using curl.
If anyone can highlight where I am going wrong to generate this error that would be appreciated.
The error
When attempting to make a PAR request for a confidential web OAuth client I'm receiving an unexpected error :
client_assertion_type required for "private_key_jwt"
Although this is the very first parameter I am providing in the request. I have also tried providing this parameter already URL encoded.
To Reproduce
curl --location 'https://bsky.social/oauth/par' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer' \
--data-urlencode 'client_assertion=[signed_JWT_assertion]' \
--data-urlencode 'client_id=https://myapi.com/bluesky/client-metadata.json' \
--data-urlencode 'redirect_uri=https://myapi.com/v3/social/api/connect/redirect' \
--data-urlencode 'response_type=code' \
--data-urlencode 'scope=atproto transition:generic' \
--data-urlencode 'code_challenge=MqQ20leWJI2CClySgAT5_oZ1GyFjsCfywr35F6AIjt4' \
--data-urlencode 'code_challenge_method=S256' \
--data-urlencode 'state=12345'
client-metadata.json
{
"client_id": "https://myapi.com/bluesky/client-metadata.json",
"application_type": "web",
"redirect_uris": [
"https://myapi.com/v3/social/api/connect/redirect"
],
"response_types": [
"code"
],
"grant_types": [
"authorization_code",
"refresh_token"
],
"scope": "atproto transition:generic",
"token_endpoint_auth_method": "private_key_jwt",
"token_endpoint_auth_signing_alg": "ES256",
"dpop_bound_access_tokens": true,
"jwks": {
"keys": [
{
"crv": "P-256",
"x": "[val1]",
"y": "[val2]",
"kid": "v1",
"kty": "EC",
"use": "sig"
}
]
}
}
Expected behaviour
The PAR response containing the desired request_uri.
The eventual solution for this turned out to be correcting the encoding of the JWT.
The client assertion JWT was not being encoded in a URL safe way, and changing the library being used to generate it allowed the PAR request to be generated as expected.
The reason bluesky returned a non relevant error is that an earlier 'type parsing process' (server side) was returning a different request object (due to it not recognising the JWT).
I note that JWTs (incorrectly) encoded are accepted by other endpoints which prevented this issue being recognised earlier.