Skip to content

Commit

Permalink
Fix oauth2 client basic http auth usage
Browse files Browse the repository at this point in the history
Per RFC 6749 section 2.3.1 the client_id and client_secret need
to be encoded using "application/x-www-form-urlencoded" encoding
first before just being send to the server as is.
  • Loading branch information
p2004a committed Feb 8, 2025
1 parent 8d0821a commit 4f14fa4
Show file tree
Hide file tree
Showing 3 changed files with 9 additions and 4 deletions.
4 changes: 2 additions & 2 deletions src/oauth2Client.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ suite('oauth2client', () => {
let tokenErr: Error | undefined;
tokenHandler = async (req) => {
try {
equal(req.headers.authorization, 'Basic dXNlcjE6cGFzczE=');
equal(req.headers.authorization, 'Basic dXNlcjE6cGFzczElM0QlM0Q=');
equal(req.headers['content-type'], 'application/x-www-form-urlencoded');
const params = new URLSearchParams(req.body as string);
equal(params.get('grant_type'), 'client_credentials');
Expand All @@ -61,7 +61,7 @@ suite('oauth2client', () => {
const token = await getAccessToken(
`http://localhost:${PORT}`,
'user1',
'pass1',
'pass1==',
'tachyon.lobby',
);
if (tokenErr) throw tokenErr;
Expand Down
4 changes: 3 additions & 1 deletion src/oauth2Client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,9 @@ export async function getAccessToken(
}

// Now let's try to get a new access token
const basicToken = Buffer.from(`${clientId}:${clientSecret}`).toString('base64');
const basicToken = Buffer.from(
`${encodeURIComponent(clientId)}:${encodeURIComponent(clientSecret)}`,
).toString('base64');
const tokenParams = new URLSearchParams({
grant_type: 'client_credentials',
});
Expand Down
5 changes: 4 additions & 1 deletion src/tachyonServer.fake.ts
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,10 @@ export async function createTachyonServer(options?: TachyonServerOpts) {
await server.register(FastifyFormBody);
await server.register(FastifyBasicAuth, {
validate: async (username, password, _req, reply) => {
if (username !== opts.clientId || password !== opts.clientSecret) {
if (
decodeURIComponent(username) !== opts.clientId ||
decodeURIComponent(password) !== opts.clientSecret
) {
reply.status(401);
reply.header('www-authenticate', 'Basic realm="tachyon_oauth2"');
return new Oauth2Error('invalid_client');
Expand Down

0 comments on commit 4f14fa4

Please sign in to comment.