Summary
I'll be covering the usage of the RFC 7523 authorization grant type in this post. I'll create a server-side implementation as a Google Cloud Function and a simple client in Node.js.
Architecture
The implementation consists of a Google Cloud Function that is triggered on an HTTP POST request. The request has a form-urlencoded body consisting of the grant_type parameter and an assertion with the JSON web token (JWT) - per the RFC. The response is a JSON object consisting of the token type, bearer token, and the unencoded version of the original JWT received. That last item isn't required, but I included it to aid in troubleshooting.
Server-side Snippet
As discussed, the server is implemented as a GCF. For a Node implementation, that consists of an Express server. The express-jwt middleware is used to implement the JWT handling.
- app.use(expressJwt({
- secret: sharedKey,
- issuer: issuer,
- audience: audience,
- algorithms: ['HS256', 'HS384', 'HS512'],
- requestProperty: 'token',
- getToken: (req) => {
- return req.body.assertion;
- }
- }));
- app.post('/rfc7523', (req, res) => {
- if (req.token) {
- console.log(`Received token: ${JSON.stringify(req.token)}`);
- const alg = 'HS512'
- const payload = {
- "iss": 'oauth issuer',
- "sub": 'oauth authority',
- "aud": 'm2mclient',
- "exp": Math.round(Date.now()/1000 + 3) //3 second expiration
- };
- const accessToken = jwt.sign(payload, privateKey, {algorithm: alg});
- res.status(200)
- .json({
- token_type: 'bearer',
- rec_token: req.token,
- access_token: accessToken
- });
- }
- else {
- res.status(400).json({error: 'no token found'});
- }
- });
Client-side Snippet
- (async () => {
- const payload = {
- "iss": issuer,
- "sub": subject,
- "aud": audience,
- "exp": Math.round(Date.now()/1000 + 3) //3 second expiration
- };
- const alg = 'HS512'
- const token = jwt.sign(payload, sharedKey, {algorithm: alg});
- const authGrant = encodeURI('urn:ietf:params:oauth:grant-type:jwt-bearer');
- const response = await fetch(url, {
- method: 'POST',
- headers: {'Content-Type': 'application/x-www-form-urlencoded'},
- body: `grant_type=${authGrant}&assertion=${token}`
- });
- const json = await response.json();
- console.log(`Results: ${JSON.stringify(json, null, 4)}`);
- })();
Results
Results: { ... "access_token": "eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJvYXV0aCBpc3 - abbreviated" }
Source
Copyright ©1993-2024 Joey E Whelan, All rights reserved.