1 package de.juplo.yourshouter;
5 import java.math.BigInteger;
6 import javax.inject.Inject;
7 import javax.sql.DataSource;
8 import org.apache.http.HttpRequestFactory;
9 import org.springframework.beans.factory.annotation.Value;
10 import org.springframework.context.annotation.Bean;
11 import org.springframework.context.annotation.Configuration;
12 import org.springframework.context.annotation.Scope;
13 import org.springframework.context.annotation.ScopedProxyMode;
14 import org.springframework.social.UserIdSource;
15 import org.springframework.core.env.Environment;
16 import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
17 import org.springframework.security.core.context.SecurityContext;
18 import org.springframework.security.crypto.encrypt.Encryptors;
19 import org.springframework.social.config.annotation.ConnectionFactoryConfigurer;
20 import org.springframework.social.config.annotation.EnableSocial;
21 import org.springframework.social.config.annotation.SocialConfigurerAdapter;
22 import org.springframework.social.connect.Connection;
23 import org.springframework.social.connect.ConnectionFactoryLocator;
24 import org.springframework.social.connect.ConnectionRepository;
25 import org.springframework.social.connect.ConnectionSignUp;
26 import org.springframework.social.connect.UsersConnectionRepository;
27 import org.springframework.social.connect.jdbc.JdbcUsersConnectionRepository;
28 import org.springframework.social.connect.web.ConnectController;
29 import org.springframework.social.connect.web.ProviderSignInController;
30 import org.springframework.social.connect.web.SignInAdapter;
31 import org.springframework.social.facebook.api.Facebook;
32 import org.springframework.social.facebook.connect.FacebookConnectionFactory;
33 import org.springframework.social.facebook.web.CanvasSignInController;
37 * Spring Social Configuration.
43 public class SocialConfig extends SocialConfigurerAdapter
46 DataSource dataSource;
48 ConnectionSignUp connectionSignUp;
50 SignInAdapter signInAdapter;
52 @Value("${facebook.app.secret}")
54 @Value("${facebook.app.salt}")
59 * Add a {@link FacebookConnectionFactory} to the configuration.
60 * The factory is configured through the keys <code>facebook.app.id</code>
61 * and <code>facebook.app.secret</code>.
67 public void addConnectionFactories(
68 ConnectionFactoryConfigurer config,
72 config.addConnectionFactory(
73 new FacebookConnectionFactory(
74 env.getProperty("facebook.app.id"),
75 env.getProperty("facebook.app.secret")
83 * Configure an instance of {@link JdbcUsersConnection} as persistent
84 * store of user/connection-mappings.
86 * The app-secret is reused as password for the encryption of the data.
87 * The salt can be changed in the <code>pom.xml</code>
89 * This does only work, if you have the Java Crypto Extension (JCE) in
90 * full strength version, since Spring Security is using a 256-bit key.
92 * @see http://stackoverflow.com/a/17637354
95 public UsersConnectionRepository getUsersConnectionRepository(
96 ConnectionFactoryLocator connectionFactoryLocator
99 JdbcUsersConnectionRepository repository =
100 new JdbcUsersConnectionRepository(
102 connectionFactoryLocator,
105 String.format("%08x", new BigInteger(1, salt.getBytes()))
108 repository.setConnectionSignUp(connectionSignUp);
113 * Configure our new implementation of {@link UserIdSource}, that retrieves
114 * the current user from the {@link SecurityContext}.
117 * An instance of {@link AnonymousUserIdSource}.
119 * @see {@link SecurityContextUserIdSource}
120 * @see {@link SecurityContext}
121 * @see {@link UserCookieInterceptor}
124 public UserIdSource getUserIdSource()
126 return new SpringSecurityContextUserIdSource();
131 * Configuration of the controller, that handles the authorization against
132 * the Facebook-API, to connect a user to Facebook.
134 * At the moment, no special configuration is needed.
136 * @param factoryLocator
137 * The {@link ConnectionFactoryLocator} will be injected by Spring.
139 * The {@link ConnectionRepository} will be injected by Spring.
141 * The configured controller.
144 public ConnectController connectController(
145 ConnectionFactoryLocator factoryLocator,
146 ConnectionRepository repository
149 ConnectController controller =
150 new ConnectController(factoryLocator, repository);
155 * Configure the {@link ProviderSignInController} to use our implementation
156 * of {@link SignInAdapter} to sign in the user by storing the ID in the
157 * {@link SecurityContext} and the user-cookie.
159 * @param factoryLocator The {@link ConnectionFactoryLocator} will be injected by Spring.
160 * @param repository The {@link UserConnectionRepository} will be injected by Spring.
161 * @return The configured {@link ProviderSignInController}
164 public ProviderSignInController signInController(
165 ConnectionFactoryLocator factoryLocator,
166 UsersConnectionRepository repository
169 ProviderSignInController controller =
170 new ProviderSignInController(factoryLocator, repository, signInAdapter);
175 * Configure the {@link CanvasSignInController} to enable sign-in through
176 * the <code>signed_request</code>, that Facebook sends to the canvas-page.
178 * @param factoryLocator The {@link ConnectionFactoryLocator} will be injected by Spring.
179 * @param repository The {@link UserConnectionRepository} will be injected by Spring.
180 * @param env The {@link Environment}, to read additional parameters from.
181 * @return The configured {@link CanvasSignInController}
184 public CanvasSignInController canvasSignInController(
185 ConnectionFactoryLocator factoryLocator,
186 UsersConnectionRepository repository,
191 new CanvasSignInController(
195 env.getProperty("facebook.app.id"),
196 env.getProperty("facebook.app.secret"),
197 env.getProperty("facebook.app.canvas")
202 * Configure a scoped bean named <code>facebook</code>, that enables
203 * access to the Graph-API in the name of the current user.
206 * The {@link ConnectionRepository} will be injected by Spring.
208 * A {@Connection<Facebook>}, that represents the authorization of the
209 * current user against the Graph-API, or <code>null</code>, if the
210 * current user is not connected to the API.
213 @Scope(value = "request", proxyMode = ScopedProxyMode.INTERFACES)
214 public Facebook facebook(ConnectionRepository repository)
216 Connection<Facebook> connection =
217 repository.findPrimaryConnection(Facebook.class);
218 return connection != null ? connection.getApi() : null;
222 * Use the <code>HttpClient</code> from Apaches <code>HttpComponents</code>
225 * We also configure shorter intervals for the connection timeout and the
228 * @param env The {@link Environment}, to read additional parameters from.
229 * @return The alternative implementation of {@link HttpRequestFactory}.
232 public HttpComponentsClientHttpRequestFactory requestFactory(Environment env)
234 HttpComponentsClientHttpRequestFactory factory =
235 new HttpComponentsClientHttpRequestFactory();
236 factory.setConnectTimeout(
237 Integer.parseInt(env.getProperty("httpclient.timeout.connection"))
239 factory.setReadTimeout(
240 Integer.parseInt(env.getProperty("httpclient.timeout.read"))