3

I’m trying to use Strava to authenticate customers that want to use my web application using Spring Boot, and I’m stuck in this error:

.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]

I would appreciate any help to move forward and solve this error. I simplified the reproduction of the error to just 2 classes:

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

and you will need to register an app with Strava (https://www.strava.com/settings/api) to get your client_secret and client_id. In strava, the callback needs to be added as localhost to run this test.

Finally, to reproduce the error, you only need to run the application in your IDE and go to http://localhost:8080/login in your browser.

Thank you very much

This is my 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

This is my 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>

This is my 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);
    }

}

This is my 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()
    ;
}


}
Marcos Pastor
  • 61
  • 1
  • 6

2 Answers2

0

Looking at your application.yml, I can see your missing the user-info-uri and user-name-attribute: Since it's oauth2 and not oidc, Spring needs to know were it can find the user and what field is the unique id of the user. I had a quick look at stravas api documentation, I think it might be this.

user-info-uri: https://www.strava.com/api/v3/athlete

user-name-attribute: id

But you might need to check out their docs or contact their support team to confirm, basically your just looking for an api call that will return the users details, and confirm which field is the unique identifier or username of the user.

  • Thank you for analyzing it and trying it, I got the same error. I start thinking it may be a bug in Spring Boot, if I build manually the URL from Strava documentation, it works perfectly: UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl("https://www.strava.com/api/v3/oauth/token/") .queryParam("client_id", CLIENT_ID) .queryParam("client_secret",CLIENT_SECRET) .queryParam("grant_type","authorization_code") .queryParam("code",code); – Marcos Pastor Jul 10 '20 at 02:42
  • hmm, hard to say without your full code, but here is a little demo for strava, which might help, you just need to add your client id and secret to it. https://github.com/wlesniak/demo-strava – Wojciech Lesniak Jul 10 '20 at 08:46
  • Well, I downloaded your demo and it works perfectly, then, I changed my source code to match yours, and surprisingly, my project keeps failing, and your project works perfectly. It's very weird, I' can't believe it... – Marcos Pastor Jul 11 '20 at 04:56
0

After testing what Wojciech Lesniak answered (thank you), nothing made sense, but I figured it out, at least, partially.

These are the logs of my project failing:

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]

Ans these are the logs of the project working with the same source code:

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

the only possibility was the configuration, reviewing line by line, it was something as silly as not including "/" at the end of the url:

    tokenUri: https://www.strava.com/api/v3/oauth/token
Marcos Pastor
  • 61
  • 1
  • 6