Skip to content

Commit 7bb91c7

Browse files
author
Valérian Girard
committed
Add client_secret_basic auth exchangeCode Method. See related DuendeArchive#892
1 parent dcfc9dc commit 7bb91c7

File tree

3 files changed

+38
-4
lines changed

3 files changed

+38
-4
lines changed

src/JsonService.js

+7-1
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ export class JsonService {
9696
});
9797
}
9898

99-
postForm(url, payload) {
99+
postForm(url, payload, basicAuth) {
100100
if (!url){
101101
Log.error("JsonService.postForm: No url passed");
102102
throw new Error("url");
@@ -197,6 +197,12 @@ export class JsonService {
197197
}
198198

199199
req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
200+
201+
if (basicAuth !== undefined)
202+
{
203+
req.setRequestHeader("Authorization", "Basic " + btoa(basicAuth));
204+
}
205+
200206
req.send(body);
201207
});
202208
}

src/OidcClientSettings.js

+7-1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ const OidcMetadataUrlPath = '.well-known/openid-configuration';
1010

1111
const DefaultResponseType = "id_token";
1212
const DefaultScope = "openid";
13+
const DefaultClientAuthentication = "client_secret_post" // The default value must be client_secret_basic, as explained in https://openid.net/specs/openid-connect-core-1_0.html#ClientAuthentication
1314
const DefaultStaleStateAge = 60 * 15; // seconds
1415
const DefaultClockSkewInSeconds = 60 * 5;
1516

@@ -20,6 +21,7 @@ export class OidcClientSettings {
2021
// client related
2122
client_id, client_secret, response_type = DefaultResponseType, scope = DefaultScope,
2223
redirect_uri, post_logout_redirect_uri,
24+
client_authentication = DefaultClientAuthentication,
2325
// optional protocol
2426
prompt, display, max_age, ui_locales, acr_values, resource, response_mode,
2527
// behavior flags
@@ -46,6 +48,7 @@ export class OidcClientSettings {
4648
this._scope = scope;
4749
this._redirect_uri = redirect_uri;
4850
this._post_logout_redirect_uri = post_logout_redirect_uri;
51+
this._client_authentication = client_authentication;
4952

5053
this._prompt = prompt;
5154
this._display = display;
@@ -98,7 +101,10 @@ export class OidcClientSettings {
98101
get post_logout_redirect_uri() {
99102
return this._post_logout_redirect_uri;
100103
}
101-
104+
get client_authentication() {
105+
return this._client_authentication;
106+
}
107+
102108

103109
// optional protocol params
104110
get prompt() {

src/TokenClient.js

+24-2
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,17 @@ export class TokenClient {
2020
exchangeCode(args = {}) {
2121
args = Object.assign({}, args);
2222

23+
var basicAuth = undefined;
24+
var urlQuery = "";
25+
2326
args.grant_type = args.grant_type || "authorization_code";
2427
args.client_id = args.client_id || this._settings.client_id;
28+
args.client_secret = args.client_secret || this._settings.client_secret;
2529
args.redirect_uri = args.redirect_uri || this._settings.redirect_uri;
2630

31+
var client_authentication = args._client_authentication || this._settings._client_authentication;
32+
delete args._client_authentication;
33+
2734
if (!args.code) {
2835
Log.error("TokenClient.exchangeCode: No code passed");
2936
return Promise.reject(new Error("A code is required"));
@@ -40,11 +47,26 @@ export class TokenClient {
4047
Log.error("TokenClient.exchangeCode: No client_id passed");
4148
return Promise.reject(new Error("A client_id is required"));
4249
}
50+
if (!args.client_secret && client_authentication == "client_secret_basic") {
51+
Log.error("TokenClient.exchangeCode: No client_secret passed");
52+
return Promise.reject(new Error("A client_secret is required"));
53+
}
54+
55+
56+
// Sending the client credentials using the Basic Auth method
57+
if(client_authentication == "client_secret_basic")
58+
{
59+
basicAuth = args.client_id + ':' + args.client_secret;
60+
urlQuery = "?grant_type=" + encodeURIComponent(args.grant_type) +
61+
"&redirect_uri="+ encodeURIComponent(args.redirect_uri) +
62+
"&code="+ encodeURIComponent(args.code);
63+
64+
args = {};
65+
}
4366

4467
return this._metadataService.getTokenEndpoint(false).then(url => {
4568
Log.debug("TokenClient.exchangeCode: Received token endpoint");
46-
47-
return this._jsonService.postForm(url, args).then(response => {
69+
return this._jsonService.postForm(url + urlQuery, args, basicAuth).then(response => {
4870
Log.debug("TokenClient.exchangeCode: response received");
4971
return response;
5072
});

0 commit comments

Comments
 (0)