b55eb3bb0af5ee54cd1fbc1a39eba99f8b7059a2
[facebook-utils] / src / main / java / de / juplo / facebook / FacebookUtils.java
1 package de.juplo.facebook;
2
3
4 import java.util.Arrays;
5 import java.util.LinkedList;
6 import java.util.List;
7 import javax.annotation.PostConstruct;
8 import org.codehaus.jackson.map.ObjectMapper;
9 import org.slf4j.Logger;
10 import org.slf4j.LoggerFactory;
11 import org.springframework.beans.BeansException;
12 import org.springframework.beans.factory.annotation.Autowired;
13 import org.springframework.beans.factory.config.BeanPostProcessor;
14 import org.springframework.context.annotation.Bean;
15 import org.springframework.context.annotation.Configuration;
16 import org.springframework.http.converter.HttpMessageConverter;
17 import org.springframework.http.converter.json.MappingJacksonHttpMessageConverter;
18 import org.springframework.security.oauth2.client.OAuth2RestTemplate;
19 import org.springframework.security.oauth2.client.http.OAuth2ErrorHandler;
20 import org.springframework.security.oauth2.client.token.AccessTokenProvider;
21 import org.springframework.security.oauth2.client.token.AccessTokenProviderChain;
22 import org.springframework.security.oauth2.client.token.grant.client.ClientCredentialsAccessTokenProvider;
23 import org.springframework.security.oauth2.client.token.grant.implicit.ImplicitAccessTokenProvider;
24 import org.springframework.security.oauth2.client.token.grant.password.ResourceOwnerPasswordAccessTokenProvider;
25 import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;
26
27
28
29 /**
30  * This class injects the facebook-utils into the spring-oauth2-configuration
31  *
32  * @author kai
33  */
34 @Configuration
35 public class FacebookUtils
36 {
37   private final Logger log = LoggerFactory.getLogger(FacebookUtils.class);
38
39
40   @Autowired(required=false)
41   private List<AccessTokenProvider> accessTokenProviderChain;
42   /**
43    * Needed, to extract Jackson-ObjectMapper.
44    * Defined by <mvc:annotation-driven />
45    */
46   @Autowired
47   private RequestMappingHandlerAdapter requestMappingHandlerAdapter;
48
49   private ObjectMapper objectMapper;
50
51
52   @PostConstruct
53   public void init()
54   {
55     for (HttpMessageConverter<?> messageConverter : requestMappingHandlerAdapter.getMessageConverters())
56     {
57       if (messageConverter instanceof MappingJacksonHttpMessageConverter)
58       {
59         MappingJacksonHttpMessageConverter m =
60             (MappingJacksonHttpMessageConverter)messageConverter;
61         objectMapper = m.getObjectMapper();
62         log.info(
63             "found ObjectMapper {} ({})",
64             objectMapper,
65             objectMapper.getClass().getCanonicalName()
66             );
67         break;
68       }
69     }
70     if (objectMapper == null)
71     {
72       throw new RuntimeException(
73           "Unable to find MappingJAcksonHttpMessageConverter!"
74           );
75     }
76
77     if (accessTokenProviderChain == null)
78     {
79       log.info("no AccessTokenProviderChain configured, creating default-chain");
80       accessTokenProviderChain =
81           Arrays.<AccessTokenProvider> asList(
82               new ImplicitAccessTokenProvider(),
83               new ResourceOwnerPasswordAccessTokenProvider(),
84               new ClientCredentialsAccessTokenProvider()
85               );
86     }
87   }
88
89
90   @Bean
91   public BeanPostProcessor getBeanPostProcessor(final String clientSecret)
92   {
93     log.debug("createing new instance of BeanPostProcessor");
94     return new BeanPostProcessor() {
95
96       @Override
97       public Object postProcessBeforeInitialization(
98           Object bean,
99           String beanName
100           )
101           throws
102             BeansException
103       {
104         if (bean instanceof OAuth2RestTemplate)
105         {
106           log.info("injecting signed_request-aware AccessTokenProviderChain");
107           OAuth2RestTemplate template = (OAuth2RestTemplate)bean;
108           List<AccessTokenProvider> chain =
109               new LinkedList<>(accessTokenProviderChain);
110           SignedRequestAwareAuthorizationCodeAccessTokenProvider provider =
111               new SignedRequestAwareAuthorizationCodeAccessTokenProvider();
112           provider.setSecret(clientSecret);
113           provider.setObjectMapper(objectMapper);
114           chain.add(provider);
115           template.setAccessTokenProvider(new AccessTokenProviderChain(chain));
116           log.info("injecting GraphApiErrorHandler");
117           template.setErrorHandler(
118               new GraphApiErrorHandler(
119                   (OAuth2ErrorHandler)template.getErrorHandler()
120                   )
121               );
122         }
123
124         return bean;
125       }
126
127       @Override
128       public Object postProcessAfterInitialization(
129           Object bean,
130           String beanName
131           )
132           throws
133             BeansException
134       {
135         return bean;
136       }
137     };
138   }
139 }