Kunle Ajiboye
Kunle Ajiboye

Reputation: 793

Handling error: InvalidRequestException, Missing grant type

Can someone be of help Please, I keep getting missing grant type, but the grant type exist. I have search online but still can get a solution to it.

@Configuration
@EnableAuthorizationServer
public class OAuth2Config extends AuthorizationServerConfigurerAdapter {

    @Value("${security.oauth2.client.access-token-validity-seconds}")
    int refreshTokenValiditySeconds;

    @Value("${security.oauth2.client.refresh-token-validity-seconds}")
    int accessTokenValiditySeconds;

    @Autowired
    private AuthenticationManager authenticationManager;

    @Bean
    public JwtAccessTokenConverter tokenConverter() {
        JwtAccessTokenConverter tokenConverter = new JwtAccessTokenConverter();
        tokenConverter.setSigningKey(PRIVATE_KEY);
        tokenConverter.setVerifierKey(PUBLIC_KEY);
        return tokenConverter;
    }

    @Bean
    public JwtTokenStore tokenStore() {
        return new JwtTokenStore(tokenConverter());
    }

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpointsConfigurer) throws Exception {
        endpointsConfigurer.authenticationManager(authenticationManager)
                .tokenStore(tokenStore())
                .accessTokenConverter(tokenConverter());
    }

    //defines the security contrains on the token endpoint
    @Override
    public void configure(AuthorizationServerSecurityConfigurer securityConfigurer) throws Exception {
        securityConfigurer
                .tokenKeyAccess("permitAll()")
                .checkTokenAccess("isAuthenticated()");
    }

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.inMemory()
                .withClient(CLIENT_ID)
                .secret(CLIENT_SECRET)
                //.resourceIds("oauth2-resource")
                //.authorities("ROLE_CLIENT","ROLE_TRUSTED_CLIENT")
                .scopes("read","write")
                .authorizedGrantTypes("authorization_code", "refresh_token", "password")
                .accessTokenValiditySeconds(accessTokenValiditySeconds)
                .refreshTokenValiditySeconds(accessTokenValiditySeconds);
                //.autoApprove(true);
    }
}

And when I run it on Post-man I get the following.

enter image description here

enter image description here

enter image description here

This is the application console log as requested, but it does not have much information :

""2018-04-02 10:20:35 [main] INFO  o.s.b.a.e.mvc.EndpointHandlerMapping - Mapped "{[/trace || /trace.json],methods=[GET],produces=[application/vnd.spring-boot.actuator.v1+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
""2018-04-02 10:20:35 [main] INFO  o.s.s.web.DefaultSecurityFilterChain - Creating filter chain: org.springframework.boot.actuate.autoconfigure.ManagementWebSecurityAutoConfiguration$LazyEndpointPathRequestMatcher@11180750, [org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@210635fd, org.springframework.security.web.context.SecurityContextPersistenceFilter@4b98225c, org.springframework.security.web.header.HeaderWriterFilter@7d61468c, org.springframework.web.filter.CorsFilter@63814bbe, org.springframework.security.web.authentication.logout.LogoutFilter@32e697ac, org.springframework.security.web.authentication.www.BasicAuthenticationFilter@655621fd, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@4beae1e3, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@3c488b34, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@3cb195dd, org.springframework.security.web.session.SessionManagementFilter@45796b2a, org.springframework.security.web.access.ExceptionTranslationFilter@c318864, org.springframework.security.web.access.intercept.FilterSecurityInterceptor@65a48cab]
""2018-04-02 10:20:36 [main] INFO  o.s.j.e.a.AnnotationMBeanExporter - Registering beans for JMX exposure on startup
""2018-04-02 10:20:36 [main] INFO  o.s.j.e.a.AnnotationMBeanExporter - Bean with name 'configurationPropertiesRebinder' has been autodetected for JMX exposure
""2018-04-02 10:20:36 [main] INFO  o.s.j.e.a.AnnotationMBeanExporter - Bean with name 'refreshEndpoint' has been autodetected for JMX exposure
""2018-04-02 10:20:36 [main] INFO  o.s.j.e.a.AnnotationMBeanExporter - Bean with name 'restartEndpoint' has been autodetected for JMX exposure
""2018-04-02 10:20:36 [main] INFO  o.s.j.e.a.AnnotationMBeanExporter - Bean with name 'environmentManager' has been autodetected for JMX exposure
""2018-04-02 10:20:36 [main] INFO  o.s.j.e.a.AnnotationMBeanExporter - Bean with name 'refreshScope' has been autodetected for JMX exposure
""2018-04-02 10:20:36 [main] INFO  o.s.j.e.a.AnnotationMBeanExporter - Located managed bean 'environmentManager': registering with JMX server as MBean [org.springframework.cloud.context.environment:name=environmentManager,type=EnvironmentManager]
""2018-04-02 10:20:36 [main] INFO  o.s.j.e.a.AnnotationMBeanExporter - Located managed bean 'restartEndpoint': registering with JMX server as MBean [org.springframework.cloud.context.restart:name=restartEndpoint,type=RestartEndpoint]
""2018-04-02 10:20:36 [main] INFO  o.s.j.e.a.AnnotationMBeanExporter - Located managed bean 'refreshScope': registering with JMX server as MBean [org.springframework.cloud.context.scope.refresh:name=refreshScope,type=RefreshScope]
""2018-04-02 10:20:36 [main] INFO  o.s.j.e.a.AnnotationMBeanExporter - Located managed bean 'configurationPropertiesRebinder': registering with JMX server as MBean [org.springframework.cloud.context.properties:name=configurationPropertiesRebinder,context=68dc098b,type=ConfigurationPropertiesRebinder]
""2018-04-02 10:20:36 [main] INFO  o.s.j.e.a.AnnotationMBeanExporter - Located managed bean 'refreshEndpoint': registering with JMX server as MBean [org.springframework.cloud.endpoint:name=refreshEndpoint,type=RefreshEndpoint]
""2018-04-02 10:20:36 [main] INFO  o.s.c.s.DefaultLifecycleProcessor - Starting beans in phase 0
""2018-04-02 10:20:36 [main] INFO  o.s.b.c.e.t.TomcatEmbeddedServletContainer - Tomcat started on port(s): 8085 (http)
""2018-04-02 10:20:36 [main] INFO  com.deanace.AuthFlexpayApplication - Started AuthFlexpayApplication in 17.884 seconds (JVM running for 19.345)
""2018-04-02 10:21:19 [http-nio-8085-exec-2] INFO  o.a.c.c.C.[.[localhost].[/auth] - Initializing Spring FrameworkServlet 'dispatcherServlet'
""2018-04-02 10:21:19 [http-nio-8085-exec-2] INFO  o.s.s.o.p.endpoint.TokenEndpoint - Handling error: InvalidRequestException, Missing grant type
"

Please I need someone to help me out

Upvotes: 1

Views: 5990

Answers (3)

uday
uday

Reputation: 11

It worked for me

  1. use post method with url = http://localhost:8888/oauth/token?username=username&password=password&grant_type=password
  2. go to Authorization Tab and select Basic Auth
         username = <client-id>
         password = <client-secret>
  1. go to Headers Tab and add header with key = value Content-Type = application/x-www-form-urlencoded

Note: Don't add username, password, and grant_type in the body. add them in URL

Upvotes: 1

Bart
Bart

Reputation: 61

I had the same issue after upgrading from spring-boot 1.5.0 to spring-boot 2.2.6. It turns out i was using logbook and it removed my x-www-form-urlencoded body.

Everything worked again after adding: -Dlogbook.servlet.form-request=parameter

https://github.com/zalando/logbook/issues/382

Upvotes: 0

Vijay Nandwana
Vijay Nandwana

Reputation: 2634

Posting this as answer because of the text size restriction in comments.

Logs were not helpful. Well, it appears that the token request is not generating properly.

Let me share with you what happens behind the scene when we make request to /oauth/token endpoint. Request goes to TokenEndpoint#postAccessToken(..) class. Then client detail service will try to load a client by Client ID (in your case, its InMemoryClientDetailsService). In this loaded client's object, authorizedGrantTypes should have a password in it. Then token request factory tries to create a token request based on the parameters passed in the request. Most probably it'd be at DefaultOAuth2RequestFactory#createTokenRequest(..). TokenRequest should have password set in grantType. Please use breakpoints in these classes to debug.

Following excerpt is from TokenEndpoint class: Please check authenticatedClient and tokenRequest object.

public ResponseEntity<OAuth2AccessToken> postAccessToken(Principal principal, @RequestParam Map<String, String> parameters) throws HttpRequestMethodNotSupportedException {
    if (!(principal instanceof Authentication)) {
        throw new InsufficientAuthenticationException("There is no client authentication. Try adding an appropriate authentication filter.");
    } else {
        String clientId = this.getClientId(principal);
        ClientDetails authenticatedClient = this.getClientDetailsService().loadClientByClientId(clientId);
        TokenRequest tokenRequest = this.getOAuth2RequestFactory().createTokenRequest(parameters, authenticatedClient);
        if (clientId != null && !clientId.equals("") && !clientId.equals(tokenRequest.getClientId())) {
            throw new InvalidClientException("Given client ID does not match authenticated client");
        } else {
            if (authenticatedClient != null) {
                this.oAuth2RequestValidator.validateScope(tokenRequest, authenticatedClient);
            }

            if (!StringUtils.hasText(tokenRequest.getGrantType())) {
                throw new InvalidRequestException("Missing grant type");
            }

Also, before making a request in Postman please delete all Cookies.

enter image description here

Upvotes: 3

Related Questions