Authentication through the canvas-attribute signed_request
[examples/facebook-app] / src / main / java / de / juplo / yourshouter / SocialConfig.java
1 package de.juplo.yourshouter;
2
3
4
5 import org.springframework.context.annotation.Bean;
6 import org.springframework.context.annotation.Configuration;
7 import org.springframework.context.annotation.Scope;
8 import org.springframework.context.annotation.ScopedProxyMode;
9 import org.springframework.social.UserIdSource;
10 import org.springframework.core.env.Environment;
11 import org.springframework.social.config.annotation.ConnectionFactoryConfigurer;
12 import org.springframework.social.config.annotation.EnableSocial;
13 import org.springframework.social.config.annotation.SocialConfigurerAdapter;
14 import org.springframework.social.connect.Connection;
15 import org.springframework.social.connect.ConnectionFactoryLocator;
16 import org.springframework.social.connect.ConnectionRepository;
17 import org.springframework.social.connect.UsersConnectionRepository;
18 import org.springframework.social.connect.mem.InMemoryUsersConnectionRepository;
19 import org.springframework.social.connect.web.ConnectController;
20 import org.springframework.social.connect.web.ProviderSignInController;
21 import org.springframework.social.connect.web.SignInAdapter;
22 import org.springframework.social.facebook.api.Facebook;
23 import org.springframework.social.facebook.connect.FacebookConnectionFactory;
24 import org.springframework.social.facebook.web.CanvasSignInController;
25
26
27 /**
28  * Spring Social Configuration.
29  *
30  * @author Kai Moritz
31  */
32 @Configuration
33 @EnableSocial
34 public class SocialConfig extends SocialConfigurerAdapter
35 {
36   /**
37    * Add a {@link FacebookConnectionFactory} to the configuration.
38    * The factory is configured through the keys <code>facebook.app.id</code>
39    * and <code>facebook.app.secret</code>.
40    *
41    * @param config
42    * @param env 
43    */
44   @Override
45   public void addConnectionFactories(
46       ConnectionFactoryConfigurer config,
47       Environment env
48       )
49   {
50     config.addConnectionFactory(
51         new FacebookConnectionFactory(
52             env.getProperty("facebook.app.id"),
53             env.getProperty("facebook.app.secret")
54             )
55         );
56   }
57
58   /**
59    * Configure an instance of {@link InMemoryUsersConnection} as persistent
60    * store of user/connection-mappings.
61    *
62    * At the moment, no special configuration is needed.
63    *
64    * @param connectionFactoryLocator
65    *     The {@link ConnectionFactoryLocator} will be injected by Spring.
66    * @return
67    *     The configured {@link UsersConnectionRepository}.
68    */
69   @Override
70   public UsersConnectionRepository getUsersConnectionRepository(
71       ConnectionFactoryLocator connectionFactoryLocator
72       )
73   {
74     InMemoryUsersConnectionRepository repository =
75         new InMemoryUsersConnectionRepository(connectionFactoryLocator);
76     repository.setConnectionSignUp(new ProviderUserIdConnectionSignUp());
77     return repository;
78   }
79
80   /**
81    * Configure our new implementation of {@link UserIdSource}, that retrieves
82    * the current user from the {@link SecurityContext}.
83    *
84    * @return
85    *     An instance of {@link AnonymousUserIdSource}.
86    *
87    * @see {@link SecurityContextUserIdSource}
88    * @see {@link SecurityContext}
89    * @see {@link UserCookieInterceptor}
90    */
91   @Override
92   public UserIdSource getUserIdSource()
93   {
94     return new SecurityContextUserIdSource();
95   }
96
97
98   /**
99    * Configuration of the controller, that handles the authorization against
100    * the Facebook-API, to connect a user to Facebook.
101    *
102    * At the moment, no special configuration is needed.
103    *
104    * @param factoryLocator
105    *     The {@link ConnectionFactoryLocator} will be injected by Spring.
106    * @param repository
107    *     The {@link ConnectionRepository} will be injected by Spring.
108    * @return
109    *     The configured controller.
110    */
111   @Bean
112   public ConnectController connectController(
113       ConnectionFactoryLocator factoryLocator,
114       ConnectionRepository repository
115       )
116   {
117     ConnectController controller =
118         new ConnectController(factoryLocator, repository);
119     return controller;
120   }
121
122   /**
123    * Configure the {@link ProviderSignInController} to use our implementation
124    * of {@link SignInAdapter} to sign in the user by storing the ID in the
125    * {@link SecurityContext} and the user-cookie.
126    *
127    * @param factoryLocator The {@link ConnectionFactoryLocator} will be injected by Spring.
128    * @param repository The {@link UserConnectionRepository} will be injected by Spring.
129    * @return The configured {@link ProviderSignInController}
130    */
131   @Bean
132   public ProviderSignInController signInController(
133       ConnectionFactoryLocator factoryLocator,
134       UsersConnectionRepository repository
135       )
136   {
137     ProviderSignInController controller = new ProviderSignInController(
138         factoryLocator,
139         repository,
140         new UserCookieSignInAdapter()
141         );
142     return controller;
143   }
144
145   /**
146    * Configure the {@link CanvasSignInController} to enable sign-in through
147    * the <code>signed_request</code>, that Facebook sends to the canvas-page.
148    *
149    * @param factoryLocator The {@link ConnectionFactoryLocator} will be injected by Spring.
150    * @param repository The {@link UserConnectionRepository} will be injected by Spring.
151    * @param env The {@link Environment}, to read additional parameters from.
152    * @return The configured {@link CanvasSignInController}
153    */
154   @Bean
155   public CanvasSignInController canvasSignInController(
156       ConnectionFactoryLocator factoryLocator,
157       UsersConnectionRepository repository,
158       Environment env
159       )
160   {
161     return
162         new CanvasSignInController(
163             factoryLocator,
164             repository,
165             new UserCookieSignInAdapter(),
166             env.getProperty("facebook.app.id"),
167             env.getProperty("facebook.app.secret"),
168             env.getProperty("facebook.app.canvas")
169             );
170   }
171
172   /**
173    * Configure a scoped bean named <code>facebook</code>, that enables
174    * access to the Graph-API in the name of the current user.
175    *
176    * @param repository
177    *     The {@link ConnectionRepository} will be injected by Spring.
178    * @return
179    *     A {@Connection<Facebook>}, that represents the authorization of the
180    *     current user against the Graph-API, or <code>null</code>, if the
181    *     current user is not connected to the API.
182    */
183   @Bean
184   @Scope(value = "request", proxyMode = ScopedProxyMode.INTERFACES)
185   public Facebook facebook(ConnectionRepository repository)
186   {
187     Connection<Facebook> connection =
188         repository.findPrimaryConnection(Facebook.class);
189     return connection != null ? connection.getApi() : null;
190   }
191 }