--- /dev/null
+package de.juplo.facebook;
+
+
+import java.util.Arrays;
+import java.util.LinkedList;
+import java.util.List;
+import javax.annotation.PostConstruct;
+import org.codehaus.jackson.map.ObjectMapper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.config.BeanPostProcessor;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.http.converter.HttpMessageConverter;
+import org.springframework.http.converter.json.MappingJacksonHttpMessageConverter;
+import org.springframework.security.oauth2.client.OAuth2RestTemplate;
+import org.springframework.security.oauth2.client.token.AccessTokenProvider;
+import org.springframework.security.oauth2.client.token.AccessTokenProviderChain;
+import org.springframework.security.oauth2.client.token.grant.client.ClientCredentialsAccessTokenProvider;
+import org.springframework.security.oauth2.client.token.grant.implicit.ImplicitAccessTokenProvider;
+import org.springframework.security.oauth2.client.token.grant.password.ResourceOwnerPasswordAccessTokenProvider;
+import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;
+
+
+
+/**
+ * This class injects the facebook-utils into the spring-oauth2-configuration
+ *
+ * @author kai
+ */
+@Configuration
+public class FacebookUtils
+{
+ private final Logger log = LoggerFactory.getLogger(FacebookUtils.class);
+
+
+ @Autowired(required=false)
+ private List<AccessTokenProvider> accessTokenProviderChain;
+ /**
+ * Needed, to extract Jackson-ObjectMapper.
+ * Defined by <mvc:annotation-driven />
+ */
+ @Autowired
+ private RequestMappingHandlerAdapter requestMappingHandlerAdapter;
+
+ private ObjectMapper objectMapper;
+
+
+ @PostConstruct
+ public void init()
+ {
+ for (HttpMessageConverter<?> messageConverter : requestMappingHandlerAdapter.getMessageConverters())
+ {
+ if (messageConverter instanceof MappingJacksonHttpMessageConverter)
+ {
+ MappingJacksonHttpMessageConverter m =
+ (MappingJacksonHttpMessageConverter)messageConverter;
+ objectMapper = m.getObjectMapper();
+ log.info(
+ "found ObjectMapper {} ({})",
+ objectMapper,
+ objectMapper.getClass().getCanonicalName()
+ );
+ break;
+ }
+ }
+ if (objectMapper == null)
+ {
+ throw new RuntimeException(
+ "Unable to find MappingJAcksonHttpMessageConverter!"
+ );
+ }
+
+ if (accessTokenProviderChain == null)
+ {
+ log.info("no AccessTokenProviderChain configured, creating default-chain");
+ accessTokenProviderChain =
+ Arrays.<AccessTokenProvider> asList(
+ new ImplicitAccessTokenProvider(),
+ new ResourceOwnerPasswordAccessTokenProvider(),
+ new ClientCredentialsAccessTokenProvider()
+ );
+ }
+ }
+
+
+ @Bean
+ public BeanPostProcessor getBeanPostProcessor(final String clientSecret)
+ {
+ log.debug("createing new instance of BeanPostProcessor");
+ return new BeanPostProcessor() {
+
+ @Override
+ public Object postProcessBeforeInitialization(
+ Object bean,
+ String beanName
+ )
+ throws
+ BeansException
+ {
+ if (bean instanceof OAuth2RestTemplate)
+ {
+ log.info("injecting signed_request-aware AccessTokenProviderChain");
+ OAuth2RestTemplate template = (OAuth2RestTemplate)bean;
+ List<AccessTokenProvider> chain =
+ new LinkedList<>(accessTokenProviderChain);
+ SignedRequestAwareAuthorizationCodeAccessTokenProvider provider =
+ new SignedRequestAwareAuthorizationCodeAccessTokenProvider();
+ provider.setSecret(clientSecret);
+ provider.setObjectMapper(objectMapper);
+ chain.add(provider);
+ template.setAccessTokenProvider(new AccessTokenProviderChain(chain));
+ }
+
+ return bean;
+ }
+
+ @Override
+ public Object postProcessAfterInitialization(
+ Object bean,
+ String beanName
+ )
+ throws
+ BeansException
+ {
+ return bean;
+ }
+ };
+ }
+}