boncey / Flickr4Java

Java API For Flickr. Fork of FlickrJ
BSD 2-Clause "Simplified" License
176 stars 154 forks source link

How resolve 401 unauthorized nobody in springboot #480

Closed shanmukhavarma11 closed 3 years ago

shanmukhavarma11 commented 3 years ago

I am doing a health project where i need to implement fitbit login using oauth2.

fitbit authorization and ,token url are below

   https://www.fitbit.com/oauth2/authorize?response_type=code&client_id=XXXXX&redirect_uri=
    http://localhost:XXXX/oauth2/code/fitbit&scope=activity

to get token from fitbit url is we use

  POST https://api.fitbit.com/oauth2/token
  Authorization: Basic Y2xpZW50X2lkOmNsaWVudCBzZWNyZXQ=
  Content-Type: application/x-www-form-urlencoded
  client_id=XXXXX&grant_type=auhorization_code&redirect_uri=
  http://localhost:8080/oauth2/code/fitbit&code=XXXXX

Above are url for getting authorization code and access_token

I my problem I could able to implement the oauth2 flow using springboot but where I hit the url

 http://localhost:8080/login or 
 http://localhost:8080/oauth2/authorize/fitbit

I am getting error like

   [invalid_token_response] An error occurred while attempting to retrieve the OAuth 2.0 
   Access Token Response: 401 Unauthorized: [no body]

here is the application.yml file

       spring:
           security:
              oauth2:
                 client:
                    registration:
                        fitbit:
                          clientId: XXXXXX
                          clientSecret: XXXXXXXXXXXXXXX
                          clientAuthenticationMethod: post
                          authorizationGrantType: authorization_code
                          redirectUri: http://localhost:8080/oauth2/code/fitbit
                          scope: activity
                   provider:
                      fitbit:
                         authorizationUri: https://www.fitbit.com/oauth2/authorize
                         tokenUri: https://api.fitbit.com/oauth2/token
                         userInfoUri: https://api.fitbit.com/1/user/-/profile.json

Spring securitycongif class code

       @EnableWebSecurity
 public class SecurityFor extends WebSecurityConfigurerAdapter {

@Override
protected void configure(HttpSecurity http) throws Exception {
    http
        .authorizeRequests().antMatchers("/home","/login","/oauth2/code/fitbit" ,"/test/login/**","/callback/", "/webjars/**", "/error**", "**/oauth2/**")
        .permitAll()
            .anyRequest().authenticated()
            .and()
        .oauth2Login().authorizationEndpoint()
        .baseUri("/oauth2/authorize/*")
        .and()
        .redirectionEndpoint()
        .baseUri("/oauth2/code/fitbit")
        .and()
            .tokenEndpoint()
                .accessTokenResponseClient(authorizationCodeTokenResponseClient());
}

private OAuth2AccessTokenResponseClient<OAuth2AuthorizationCodeGrantRequest> authorizationCodeTokenResponseClient() {
    OAuth2AccessTokenResponseHttpMessageConverter tokenResponseHttpMessageConverter =
            new OAuth2AccessTokenResponseHttpMessageConverter();

    tokenResponseHttpMessageConverter.setTokenResponseConverter(new OAuth2AccessTokenResponseConverterWithDefaults());

    RestTemplate restTemplate = new RestTemplate(Arrays.asList(
            new FormHttpMessageConverter(), tokenResponseHttpMessageConverter));

    restTemplate.setErrorHandler(new OAuth2ErrorResponseErrorHandler());

    DefaultAuthorizationCodeTokenResponseClient tokenResponseClient = new DefaultAuthorizationCodeTokenResponseClient();

    tokenResponseClient.setRestOperations(restTemplate);

    return tokenResponseClient;
}

OAuth2AccessTokenResponseConverterWithDefaults class

                         public class OAuth2AccessTokenResponseConverterWithDefaults implements Converter<Map<String, String>, OAuth2AccessTokenResponse> {
private static final Set<String> TOKEN_RESPONSE_PARAMETER_NAMES = Stream.of(
        OAuth2ParameterNames.ACCESS_TOKEN,
        OAuth2ParameterNames.TOKEN_TYPE,
        OAuth2ParameterNames.EXPIRES_IN,
        OAuth2ParameterNames.REFRESH_TOKEN,
        OAuth2ParameterNames.SCOPE).collect(Collectors.toSet());

private OAuth2AccessToken.TokenType defaultAccessTokenType = OAuth2AccessToken.TokenType.BEARER;

@Override
public OAuth2AccessTokenResponse convert(Map<String, String> tokenResponseParameters) {
    System.out.println(OAuth2ParameterNames.ACCESS_TOKEN);
    String accessToken = tokenResponseParameters.get(OAuth2ParameterNames.ACCESS_TOKEN);
    System.out.println("%%%%%%%%%%%%%%%%%%%%%%%%%"+accessToken);
    OAuth2AccessToken.TokenType accessTokenType = this.defaultAccessTokenType;
    if (OAuth2AccessToken.TokenType.BEARER.getValue().equalsIgnoreCase(
            tokenResponseParameters.get(OAuth2ParameterNames.TOKEN_TYPE))) {

        accessTokenType = OAuth2AccessToken.TokenType.BEARER;
    }

    long expiresIn = 0;
    if (tokenResponseParameters.containsKey(OAuth2ParameterNames.EXPIRES_IN)) {
        try {

            expiresIn = Long.valueOf(tokenResponseParameters.get(OAuth2ParameterNames.EXPIRES_IN));
        } catch (NumberFormatException ex) { }
    }

    Set<String> scopes = Collections.emptySet();
    if (tokenResponseParameters.containsKey(OAuth2ParameterNames.SCOPE)) {
        String scope = tokenResponseParameters.get(OAuth2ParameterNames.SCOPE);
        scopes = Arrays.stream(StringUtils.delimitedListToStringArray(scope, " ")).collect(Collectors.toSet());
    }

    Map<String, Object> additionalParameters = new LinkedHashMap<>();
    tokenResponseParameters.entrySet().stream()
            .filter(e -> !TOKEN_RESPONSE_PARAMETER_NAMES.contains(e.getKey()))
            .forEach(e -> additionalParameters.put(e.getKey(), e.getValue()));

    return OAuth2AccessTokenResponse.withToken(accessToken)
            .tokenType(accessTokenType)
            .expiresIn(expiresIn)
            .scopes(scopes)
            .additionalParameters(additionalParameters)
            .build();
}

public final void setDefaultAccessTokenType(OAuth2AccessToken.TokenType defaultAccessTokenType) {
    Assert.notNull(defaultAccessTokenType, "defaultAccessTokenType cannot be null");
    this.defaultAccessTokenType = defaultAccessTokenType;
}

}

websecurityconfig class

            @Configuration
  public class WebClientConfig {

@Bean
public WebClient webClient(ClientRegistrationRepository clientRegistrationRepository,
                            OAuth2AuthorizedClientRepository authorizedClientRepository) {
    System.out.println("&&&&&&&&&&&");
    ServletOAuth2AuthorizedClientExchangeFilterFunction oauth2 = new ServletOAuth2AuthorizedClientExchangeFilterFunction(
            clientRegistrationRepository, authorizedClientRepository);
    System.out.println(oauth2.oauth2Configuration());

    return WebClient.builder()
            .apply(oauth2.oauth2Configuration())
            .build();
}

}

I will be repeating my problem again

when ever I give hit to the url localhost:8080/oauth2/authorize/fitbit or localhost:8080/login I am getting the error

[invalid_token_response] An error occurred while attempting to retrieve the OAuth 2.0 Access Token Response: 401 Unauthorized: [no body]

here is the image for the error enter image description here

Thank you

shanmukhavarma11 commented 3 years ago

springboot, springboot oauth2