Search code examples
springsecurityoauth-2.0spring-security-oauth2

Spring Security OAuth 2.0 - client secret always required for authorization code grant


According to the spec, requests for a token using the authorization code grant are not required to be authenticated as long as the client_id is included in the request and the client_id is the same one used to generate the code. However, with the Spring Security OAuth 2.0 implementation, it appears that basic auth is always required on the /oauth/token endpoint even if the client was never assigned a secret.

It looks like there is support for allowing clients without a secret due to the isSecretRequired() method in the ClientDetails interface. What do I need to do to enable clients without a secret to be authenticated at the /oauth/token URL?

4.1.3. Access Token Request

The client makes a request to the token endpoint by sending the
following parameters using the "application/x-www-form-urlencoded"
format per Appendix B with a character encoding of UTF-8 in the HTTP
request entity-body:

grant_type REQUIRED. Value MUST be set to "authorization_code".

code REQUIRED. The authorization code received from the authorization server.

redirect_uri REQUIRED, if the "redirect_uri" parameter was included in the authorization request as described in Section 4.1.1, and their values MUST be identical.

client_id REQUIRED, if the client is not authenticating with the authorization server as described in Section 3.2.1.

If the client type is confidential or the client was issued client credentials (or assigned other authentication requirements), the
client MUST authenticate with the authorization server as described
in Section 3.2.1.


Solution

  • Authenticating the client using the form parameters instead of basic auth is enabled using the allowFormAuthenticationForClients() method as shown in the code sample below.

    class AuthorizationServerConfigurer extends AuthorizationServerConfigurerAdapter {
    
        @Override
        void configure(AuthorizationServerSecurityConfigurer security) {
            security
                    .tokenKeyAccess("permitAll()")
                    .checkTokenAccess("isAuthenticated()")
                    .allowFormAuthenticationForClients()
        }
    }
    

    The allowFormAuthenticationForClients() method triggers the addition of the ClientCredentialsTokenEndpointFilter which allows for authentication via form parameters.