gabrielruiu / spring-social-yahoo

Spring Social Yahoo is an extension based on Spring Social that provides funcationality to communicate with the Yahoo Social Rest API.
Other
2 stars 2 forks source link

Spring Boot YahooAutoConfiguration YahooTemplate parameters issue #2

Open decisionwanted opened 9 years ago

decisionwanted commented 9 years ago

I'm trying to implement YahooAutoConfiguration like for example org.springframework.boot.autoconfigure.social.TwitterAutoConfiguration:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;
import org.springframework.context.annotation.ScopedProxyMode;
import org.springframework.social.config.annotation.EnableSocial;
import org.springframework.social.config.annotation.SocialConfigurerAdapter;
import org.springframework.social.connect.Connection;
import org.springframework.social.connect.ConnectionFactory;
import org.springframework.social.connect.ConnectionRepository;
import org.springframework.social.connect.web.GenericConnectionStatusView;
import org.springframework.social.oauth2.OAuth2Template;
import org.springframework.web.servlet.View;

import com.github.gabrielruiu.springsocial.yahoo.api.Yahoo;
import com.github.gabrielruiu.springsocial.yahoo.api.impl.YahooTemplate;
import com.github.gabrielruiu.springsocial.yahoo.connect.YahooConnectionFactory;

/**
 * {@link EnableAutoConfiguration Auto-configuration} for Spring Social
 * connectivity with Yahoo.
 *
 */
@Configuration
@ConditionalOnClass({ SocialConfigurerAdapter.class, YahooConnectionFactory.class })
@ConditionalOnProperty(prefix = "spring.social.yahoo.", value = "app-id")
@AutoConfigureBefore(SocialWebAutoConfiguration.class)
@AutoConfigureAfter(WebMvcAutoConfiguration.class)
public class YahooAutoConfiguration {

    @Configuration
    @EnableSocial
    @EnableConfigurationProperties(YahooProperties.class)
    @ConditionalOnWebApplication
    protected static class YahooAutoConfigurationAdapter extends SocialAutoConfigurerAdapter {

        @Autowired
        private YahooProperties properties;

        @Bean
        @ConditionalOnMissingBean(Yahoo.class)
        @Scope(value = "request", proxyMode = ScopedProxyMode.INTERFACES)
        public Yahoo yahoo(ConnectionRepository repository) {
            Connection<Yahoo> connection = repository.findPrimaryConnection(Yahoo.class);

            if (connection != null) {
                return connection.getApi();
            }

            return connection != null ? connection.getApi() : new YahooTemplate(this.properties.getAppId(),
                    this.properties.getAppSecret(), ???????);
        }

        @Bean(name = { "connect/yahooConnect", "connect/yahooConnected" })
        @ConditionalOnProperty(prefix = "spring.social.", value = "auto-connection-views")
        public View yahooConnectView() {
            return new GenericConnectionStatusView("yahoo", "Yahoo");
        }

        @Override
        protected ConnectionFactory<?> createConnectionFactory() {
            YahooConnectionFactory factory = new YahooConnectionFactory(this.properties.getAppId(), this.properties.getAppSecret());
            return factory;
        }

    }

}

and right now I don't know where to get

String accessToken, String accessTokenSecret, String guid

for YahooTemplate. I have only this.properties.getAppId() and this.properties.getAppSecret()

It was enough for example for Google and GitHub OAuth providers. Why do I need to provide String accessToken, String accessTokenSecret, String guid parameters here ?

gabrielruiu commented 9 years ago

A bit of background: the GUID is used to identify the person on behalf of which the calls are made. And this needs to be appended to each call.

Now I'm looking to see if I can construct the template without the GUID and postpone or get the GUID some other way.

And thank you for raising the issue :)

decisionwanted commented 9 years ago

Sure, no problem and thank you very much!

I have implemented my application with Google, Facebook, GitHub, LinkedIn, Twitter OAuth providers with no needs to provide these additional 3 parameters.. It will be nice to avoid these parameters for YahooTemplate also.

decisionwanted commented 9 years ago

sorry to disturb you, but do you have any news on this issue ?

gabrielruiu commented 9 years ago

So far only did some research to see if there is a best-practice from which I can inspire from. But all OAuth1a-based implementations (Yahoo is one of them) require the accessToken and accessTokenSecret when building the template. See https://github.com/spring-projects/spring-social/wiki/Api-Providers for some examples of OAuth1a implementations.

I can't promise I will fix this anytime soon. I think best-case would be sometime this weekend or the next one.

What you can try in the meantime is to rely on getting the api from the Connection instance:

@Bean
@ConditionalOnMissingBean(Yahoo.class)
@Scope(value = "request", proxyMode = ScopedProxyMode.INTERFACES)
public Yahoo yahoo(ConnectionRepository repository) {
      Connection<Yahoo> connection = repository.findPrimaryConnection(Yahoo.class);
      return connection != null ? connection.getApi() : null;
}

Here is an example of how LinkedIn did. The LinkedInTemplate is similar to the YahooTemplate https://github.com/spring-projects/spring-boot/blob/master/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/social/LinkedInAutoConfiguration.java

decisionwanted commented 9 years ago

Thanks !

Maybe I'm doing something wrong, but right now it fails on https://api.login.yahoo.com/oauth/v2/get_request_token with

org.springframework.web.client.HttpClientErrorException: 401 Authorization Required
    at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:91) ~[spring-web-4.1.6.RELEASE.jar:4.1.6.RELEASE]
    at org.springframework.web.client.RestTemplate.handleResponse(RestTemplate.java:614) ~[spring-web-4.1.6.RELEASE.jar:4.1.6.RELEASE]
    at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:570) ~[spring-web-4.1.6.RELEASE.jar:4.1.6.RELEASE]
    at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:545) ~[spring-web-4.1.6.RELEASE.jar:4.1.6.RELEASE]
    at org.springframework.web.client.RestTemplate.exchange(RestTemplate.java:466) ~[spring-web-4.1.6.RELEASE.jar:4.1.6.RELEASE]
    at org.springframework.social.oauth1.OAuth1Template.exchangeForToken(OAuth1Template.java:187) ~[spring-social-core-1.1.0.RELEASE.jar:1.1.0.RELEASE]
    at org.springframework.social.oauth1.OAuth1Template.fetchRequestToken(OAuth1Template.java:115) ~[spring-social-core-1.1.0.RELEASE.jar:1.1.0.RELEASE]
    at org.springframework.social.security.provider.OAuth1AuthenticationService.getAuthToken(OAuth1AuthenticationService.java:91) ~[spring-social-security-1.1.0.RELEASE.jar:1.1.0.RELEASE]
    at org.springframework.social.security.SocialAuthenticationFilter.attemptAuthService(SocialAuthenticationFilter.java:239) ~[spring-social-security-1.1.0.RELEASE.jar:1.1.0.RELEASE]
    at org.springframework.social.security.SocialAuthenticationFilter.attemptAuthentication(SocialAuthenticationFilter.java:157) ~[spring-social-security-1.1.0.RELEASE.jar:1.1.0.RELEASE]
    at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:211) ~[spring-security-web-3.2.3.RELEASE.jar:3.2.3.RELEASE]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) ~[spring-security-web-3.2.3.RELEASE.jar:3.2.3.RELEASE]

this my html form

<form action="http://localhost:8080/auth/yahoo" method="POST">
 <button type="submit">Sign in with Yahoo</button>
</form>

What can be wrong ?