spring-attic / spring-security-oauth

Support for adding OAuth1(a) and OAuth2 features (consumer and provider) for Spring web applications.
http://github.com/spring-projects/spring-security-oauth
Apache License 2.0
4.69k stars 4.05k forks source link

Bad client credentials when using allowFormAuthenticationForClients #1498

Open jrhenderson1988 opened 5 years ago

jrhenderson1988 commented 5 years ago

I am trying to allow OAuth2 authentication by passing the client credentials in the body of a POST request, by using allowFormAuthenticationForClients. I have the following Authorization Server config setup in my project:

@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
    @Autowired
    private TokenStore tokenStore;

    @Autowired
    private UserApprovalHandler userApprovalHandler;

    @Autowired
    @Qualifier("authenticationManagerBean")
    private AuthenticationManager authenticationManager;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.inMemory()
                .withClient("client_id")
                .secret("secret")
                .authorizedGrantTypes("password", "authorization_code", "refresh_token")
                .scopes("read", "write")
                .accessTokenValiditySeconds(600)
                .refreshTokenValiditySeconds(3600);
    }

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
        endpoints.tokenStore(this.tokenStore)
                .userApprovalHandler(this.userApprovalHandler)
                .authenticationManager(this.authenticationManager);
    }

    @Override
    public void configure(AuthorizationServerSecurityConfigurer security) {
        security.tokenKeyAccess("permitAll()")
                .checkTokenAccess("isAuthenticated()")
                .passwordEncoder(this.passwordEncoder)
                .allowFormAuthenticationForClients();
    }
}

I am trying to hit the /oauth/token end point with a POST request (Without the Authorization header), with the x-www-form-urlencoded body as

client_id=client_id&secret=secret&scope=read&username=user&password=pass&grant_type=password

but I am getting back a 401 Unauthorized response with the following body:

{
    "error": "invalid_client",
    "error_description": "Bad client credentials"
}
screenshot 2018-10-07 at 21 40 27

Even if I add the correct Authorization header I still get the same result.

Authorization: Basic Y2xpZW50X2lkOnNlY3JldA==

Omitting the client_id parameter seems to allow the process to revert to the default of accepting client credentials from the request's Authorization header which is successful with a 200 Ok and typical access token/refresh token response.

I feel that this could be a bug, but I'm unsure as I am relatively new to Spring and it's quite possible that I'm doing something wrong. Any feedback will be appreciated.

sergeymironov0001 commented 5 years ago

@jrhenderson1988 Please change in your ClientDetailsServiceConfigurer configuration .secret("secret") to .secret(passwordEncoder().encode("secret")). And you have to use in your post request _clientsecret parameter instead of secret.