【问题标题】:Error trying to authenticate a web application with Oauth2 and Strava using Spring Boot尝试使用 Spring Boot 使用 Oauth2 和 Strava 对 Web 应用程序进行身份验证时出错
【发布时间】:2020-07-08 22:09:18
【问题描述】:

我正在尝试使用 Strava 对想要通过 Spring Boot 使用我的 Web 应用程序的客户进行身份验证,但我遇到了这个错误:

.s.o.c.w.OAuth2LoginAuthenticationFilter :身份验证请求 失败的: org.springframework.security.oauth2.core.OAuth2AuthenticationException: [invalid_token_response] 尝试 检索 OAuth 2.0 访问令牌响应:无法提取 响应:没有找到适合响应类型的 HttpMessageConverter [班级 org.springframework.security.oauth2.core.endpoint.OAuth2AccessTokenResponse] 和内容类型 [text/html]

如果能帮助我继续前进并解决此错误,我将不胜感激。我将错误的重现简化为 2 个类:

DemoSecurity.java extending WebSecurityConfigurerAdapter 
DemoApplication.java as the entry to the application with @SpringBootApplication, 

您需要在 Strava (https://www.strava.com/settings/api) 上注册一个应用,以获取您的 client_secretclient_id。在 strava 中,需要将回调添加为 localhost 才能运行此测试。

最后,要重现错误,您只需在 IDE 中运行应用程序并在浏览器中访问 http://localhost:8080/login。

非常感谢

这是我的 application.yml:

spring:   
  security:
    oauth2:
      client:
        registration:
          strava:
            provider: strava-provider
            client-id: XXXXX
            client-secret: XXXXXXXXXXXXXXXXX
            client-authentication-method: POST
            authorization-grant-type: authorization_code
            redirect-uri: http://localhost:8080/login/oauth2/code/
            scope:
              - read
        provider:
          strava-provider:
            tokenUri: https://www.strava.com/api/v3/oauth/token/
            authorizationUri: https://www.strava.com/api/v3/oauth/authorize?response_type=code

这是我的 pom.xml:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    

<modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.1.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>demo</name>
    <description>Demo project for Spring Boot</description>

<properties>
    <java.version>1.8</java.version>
</properties>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-oauth2-client</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
        <exclusions>
            <exclusion>
                <groupId>org.junit.vintage</groupId>
                <artifactId>junit-vintage-engine</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

这是我的 DemoApplication.java:

package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.security.oauth2.client.servlet.OAuth2ClientAutoConfiguration;
import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration;

@SpringBootApplication
public class DemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }

}

这是我的 DemoSecurity.java:

package com.example.demo;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

@EnableWebSecurity
@Configuration
public class DemoSecurity extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
    http
            .authorizeRequests()
            .antMatchers("/login**","/", "/error", "/webjars/**").permitAll()
            .anyRequest()
            .authenticated().and()
            .oauth2Login()
    ;
}


}

【问题讨论】:

  • 想说你的问题拯救了我的一天。多年来一直在努力解决这个错误。谢谢!

标签: java spring-boot spring-oauth2 oauth2client strava


【解决方案1】:

查看您的 application.yml,我可以看到您缺少 user-info-uri 和 user-name-attribute: 由于它是 oauth2 而不是 oidc,因此 Spring 需要知道它是否可以找到用户以及用户的唯一 id 是什么字段。 我快速浏览了一下 stravas api 文档,我认为可能是这样。

用户信息 uri:https://www.strava.com/api/v3/athlete

用户名属性:id

但您可能需要查看他们的文档或联系他们的支持团队进行确认,基本上您只是在寻找一个将返回用户详细信息的 api 调用,并确认哪个字段是用户的唯一标识符或用户名。

【讨论】:

  • 感谢您的分析和尝试,我遇到了同样的错误。我开始认为这可能是 Spring Boot 中的一个错误,如果我从 Strava 文档手动构建 URL,它会完美运行: UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl("strava.com/api/v3/oauth/token/") .queryParam("client_id", CLIENT_ID) .queryParam( "client_secret",CLIENT_SECRET) .queryParam("grant_type","authorization_code") .queryParam("code",code);
  • hmm,没有完整代码很难说,但这里有一个 strava 的小演示,它可能会有所帮助,你只需要添加你的客户端 ID 和密码。 github.com/wlesniak/demo-strava
  • 好吧,我下载了你的演示,它运行良好,然后,我更改了我的源代码以匹配你的,令人惊讶的是,我的项目一直失败,而你的项目运行良好。太奇怪了,我不敢相信……
【解决方案2】:

在测试了 Wojciech Lesniak 的回答(谢谢)之后,没有任何意义,但我至少部分理解了。

这些是我的项目失败的日志:

2020-07-10 06:19:19.946 DEBUG 56091 --- [nio-8080-exec-2] .s.o.c.w.OAuth2LoginAuthenticationFilter : Request is to process authentication
2020-07-10 06:19:19.948 DEBUG 56091 --- [nio-8080-exec-2] o.s.s.authentication.ProviderManager     : Authentication attempt using org.springframework.security.oauth2.client.authentication.OAuth2LoginAuthenticationProvider
2020-07-10 06:19:20.734 DEBUG 56091 --- [nio-8080-exec-2] o.s.s.authentication.ProviderManager     : Authentication attempt using org.springframework.security.oauth2.client.oidc.authentication.OidcAuthorizationCodeAuthenticationProvider
2020-07-10 06:19:20.735 DEBUG 56091 --- [nio-8080-exec-2] .s.a.DefaultAuthenticationEventPublisher : No event was found for the exception org.springframework.security.oauth2.core.OAuth2AuthenticationException
2020-07-10 06:19:20.741 DEBUG 56091 --- [nio-8080-exec-2] .s.o.c.w.OAuth2LoginAuthenticationFilter : Authentication request failed: org.springframework.security.oauth2.core.OAuth2AuthenticationException: [invalid_token_response] An error occurred while attempting to retrieve the OAuth 2.0 Access Token Response: Could not extract response: no suitable HttpMessageConverter found for response type [class org.springframework.security.oauth2.core.endpoint.OAuth2AccessTokenResponse] and content type [text/html]

这些是使用相同源代码的项目的日志:

2020-07-10 06:20:09.917 DEBUG 56106 --- [nio-8080-exec-2] .s.o.c.w.OAuth2LoginAuthenticationFilter : Request is to process authentication
2020-07-10 06:20:09.920 DEBUG 56106 --- [nio-8080-exec-2] o.s.s.authentication.ProviderManager     : Authentication attempt using org.springframework.security.oauth2.client.authentication.OAuth2LoginAuthenticationProvider
2020-07-10 06:20:10.689 DEBUG 56106 --- [nio-8080-exec-2] s.CompositeSessionAuthenticationStrategy : Delegating to org.springframework.security.web.authentication.session.ChangeSessionIdAuthenticationStrategy@30f74e79
2020-07-10 06:20:10.690 DEBUG 56106 --- [nio-8080-exec-2] s.CompositeSessionAuthenticationStrategy : Delegating to org.springframework.security.web.csrf.CsrfAuthenticationStrategy@8a8639c
2020-07-10 06:20:10.690 DEBUG 56106 --- [nio-8080-exec-2] .s.o.c.w.OAuth2LoginAuthenticationFilter : Authentication success. Updating SecurityContextHolder to contain: org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken@efd72585: Principal: Name: [60310151], Granted Authorities: [[ROLE_USER, SCOPE_read]], User Attributes: [{id=60310151, username=null, resource_state=2, firstname=Marcos, lastname=Garcia, city=Chicago, state=Illinois, country=United States, sex=null, premium=false, summit=false, created_at=2020-06-03T11:18:54Z, updated_at=2020-07-07T16:10:35Z, badge_type_id=0, profile_medium=avatar/athlete/medium.png, profile=avatar/athlete/large.png, friend=null, follower=null}]; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@0: RemoteIpAddress: 127.0.0.1; SessionId: 858ADB4064C6112BD3EE7909CA036E06; Granted Authorities: ROLE_USER, SCOPE_read

唯一的可能是配置,逐行查看,这就像在url末尾不包含“/”一样愚蠢:

    tokenUri: https://www.strava.com/api/v3/oauth/token

【讨论】:

    猜你喜欢
    • 2021-10-07
    • 1970-01-01
    • 2020-05-29
    • 1970-01-01
    • 2017-10-01
    • 2019-02-12
    • 2022-01-13
    • 2017-02-21
    • 2015-02-13
    相关资源
    最近更新 更多