【问题标题】:Handling error: InvalidRequestException, Missing grant type处理错误:InvalidRequestException,缺少授权类型
【发布时间】:2018-09-11 03:47:53
【问题描述】:

有人可以帮忙吗,我一直缺少授权类型,但授权类型存在。我在网上搜索过,但仍然可以找到解决方案。

@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);
    }
}

当我在 Post-man 上运行它时,我得到以下信息。

这是请求的应用程序控制台日志,但它没有太多信息:

""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
"

我需要有人来帮助我

【问题讨论】:

  • 请启用logging.level.org.springframework.security=DEBUG 调试标志并共享堆栈跟踪。
  • @Vijay Nandwana 更新了日志详细信息

标签: java spring-boot oauth-2.0 spring-security-oauth2


【解决方案1】:

由于 cmets 中的文本大小限制,将此作为答案发布。

日志没有帮助。好吧,似乎令牌请求没有正确生成。

让我与您分享当我们向 /oauth/token 端点发出请求时幕后发生的事情。请求转到TokenEndpoint#postAccessToken(..) 类。然后客户端详细信息服务将尝试通过客户端 ID(在您的情况下为 InMemoryClientDetailsService)加载客户端。在这个加载的客户端对象中,authorizedGrantTypes 中应该有一个password。然后令牌请求工厂尝试根据请求中传递的参数创建令牌请求。很可能是DefaultOAuth2RequestFactory#createTokenRequest(..)TokenRequest 应该在grantType 中设置password。请在这些类中使用断点进行调试。

以下摘录来自 TokenEndpoint 类:请检查 authenticatedClienttokenRequest 对象。

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");
            }

另外,在 Postman 中发出请求之前,请删除所有 Cookie。

【讨论】:

  • 你有没有发现这个问题?我有同样的问题,我的 tokenRequest 有空参数...我不知道为什么。
【解决方案2】:

从 spring-boot 1.5.0 升级到 spring-boot 2.2.6 后,我遇到了同样的问题。 原来我正在使用日志,它删除了我的 x-www-form-urlencoded 正文。

添加后一切正常:-Dlogbook.servlet.form-request=parameter

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

【讨论】:

    【解决方案3】:

    它对我有用

    1. 使用url = http://localhost:8888/oauth/token?username=username&amp;password=password&amp;grant_type=password的post方法
    2. 转到授权选项卡并选择基本身份验证
             username = <client-id>
             password = <client-secret>
    
    1. 转到标题选项卡并使用键 = 值添加标题 Content-Type = application/x-www-form-urlencoded

    注意:不要在正文中添加用户名、密码和grant_type。在 URL 中添加它们

    【讨论】:

      猜你喜欢
      • 2017-12-11
      • 1970-01-01
      • 2018-05-03
      • 2017-01-14
      • 1970-01-01
      • 2015-04-09
      • 1970-01-01
      • 2017-08-14
      • 2021-06-09
      相关资源
      最近更新 更多