I'm attempting to add OAuth support to an existing Spring webapp to allow people to login with their Google/Facebook/Twitter/etc. accounts. To do this I'm using the 'spring-social' framework, and the 'spring-social-google' library for it. I'm also trying to do this while working within a number of constraints:
- The existing webapp does not use spring-security for authentication or for controlling access to resources, it provides its own form-based authentication.
- The existing webapp does not track the authenticated user details using the servlet-container's
Principal
, instead it stores a reference to the authenticated user in the HTTP session. - The existing webapp does not (and cannot) have a Spring DispatcherServlet bound to the webapp root URL (i.e.
/
).
Accounts in the database are uniquely keyed by e-mail, so really all I'm attempting to do is glue together a flow that goes roughly like:
Login Page (user chooses between OAuth and direct login)
-> <Provider OAuth Flow> (user completes OAuth authorization)
-> OAuth Callback URL (grab user email, check for existing account, create if needed)
-> Post-login Landing Page (done)
Anyhow, the limitations noted above caused a variety of problems, most of which I've managed to find workarounds for. However I'm getting some bizarre behavior from the Google OAuth connector (Twitter and Facebook appear to work correctly). Basically, it appears that it is not sending the OAuth clientId
or clientSecret
during the final request to Google:
DEBUG: org.springframework.web.client.RestTemplate - Writing [
{code=[4/dVVrFDpNLDGTmXCuuQj6fcfaetEU.UkLPQd7NOLYbgrKXntQAax0INYiydQI],
redirect_uri=[http://localhost:8080/oauth/signin/google],
grant_type=[authorization_code]}] as "application/x-www-form-urlencoded"
This returns a code 400 ("bad request").
If I head over to hurl.it and POST the same data to the same URL (https://accounts.google.com/o/oauth2/token) and manually add in the client_id
and client_secret
values, the call returns a successful response.
So what could be causing the Google connector to omit these values?
For reference, I'm including the spring-social-google library in my project like:
<dependency>
<groupId>org.springframework.social</groupId>
<artifactId>spring-social-google</artifactId>
<version>1.0.0.M1</version>
</dependency>
...and then in my @Configuration
class I've got:
@Bean
@Scope(value="singleton", proxyMode=ScopedProxyMode.INTERFACES)
public ConnectionFactoryLocator connectionFactoryLocator() {
ConnectionFactoryRegistry registry = new ConnectionFactoryRegistry();
registry.addConnectionFactory(
new GoogleConnectionFactory(
"<google client id>",
"<google secret key>"));
registry.addConnectionFactory(
new FacebookConnectionFactory(
"<facebook client id>",
"<facebook secret key>"));
registry.addConnectionFactory(
new TwitterConnectionFactory(
"<twitter client id>",
"<twitter secret key>"));
return registry;
}
The rest of what I'm using is pretty much standard straight out of the spring-social-showcase example (albeit hacked up to remove extraneous things and to work within the constraints noted above). Strangely, attempting to log in with Google does correctly show the OAuth authorization page on Google with my app/project name correctly displayed. The error happens after I hit the "Allow" button to authorize the OAuth login and return to the webapp.
Anyhow, what might be causing this issue, and how might it be fixed?