nginxinc / nginx-openid-connect

Reference implementation of OpenID Connect integration for NGINX Plus
https://www.nginx.com/products/nginx/
Other
199 stars 94 forks source link

client_secret_basic Client Authentication not supported #93

Closed fabriziofiorucci closed 4 months ago

fabriziofiorucci commented 6 months ago

Based on https://openid.net/specs/openid-connect-core-1_0.html#ClientAuthentication we have:

This section defines a set of Client Authentication methods that are used by Clients to authenticate to the Authorization Server when using the Token Endpoint. During Client Registration, the RP (Client) MAY register a Client Authentication method. If no method is registered, the default method is client_secret_basic.

These Client Authentication methods are:

client_secret_basic
    Clients that have received a client_secret value from the Authorization Server authenticate with the Authorization Server in accordance with Section 2.3.1 of [OAuth 2.0](https://openid.net/specs/openid-connect-core-1_0.html#RFC6749) [RFC6749] using the HTTP Basic authentication scheme. 
client_secret_post
    Clients that have received a client_secret value from the Authorization Server, authenticate with the Authorization Server in accordance with Section 2.3.1 of [OAuth 2.0](https://openid.net/specs/openid-connect-core-1_0.html#RFC6749) [RFC6749] by including the Client Credentials in the request body.

The current nginx-openid-connect implementation doesn't seem to support client_secret_basic, it rather does client_secret_post.

In https://github.com/nginxinc/nginx-openid-connect/blob/main/openid_connect.js we have:

function idpClientAuth(r) {
    // If PKCE is enabled we have to use the code_verifier
    if ( r.variables.oidc_pkce_enable == 1 ) {
        r.variables.pkce_id = r.variables.arg_state;
        return "code=" + r.variables.arg_code + "&code_verifier=" + r.variables.pkce_code_verifier;
    } else {
        return "code=" + r.variables.arg_code + "&client_secret=" + r.variables.oidc_client_secret;
    }   
}

This only seem to manage client_secret_post .

In https://github.com/nginxinc/nginx-openid-connect/blob/main/openid_connect.server_conf the snippet

    location = /_token {
        # This location is called by oidcCodeExchange(). We use the proxy_ directives
        # to construct the OpenID Connect token request, as per:
        #  http://openid.net/specs/openid-connect-core-1_0.html#TokenRequest
        internal;
        proxy_ssl_server_name on; # For SNI to the IdP
        proxy_set_header      Content-Type "application/x-www-form-urlencoded";
        proxy_set_body        "grant_type=authorization_code&client_id=$oidc_client&$args&redirect_uri=$redirect_base$redir_location";
        proxy_method          POST;
        proxy_pass            $oidc_token_endpoint;
   }

is where the Basic authentication header should be added.