0

In my application I can identify user by providerId and providerUserId. But initially, I have only following information:

  • providerId,
  • accessToken,
  • secret.

Thus, I need to acquire providerUserId by this information.

I'm trying to use following code:

ConnectionData connectionData = newConnectionData(providerId, accessToken, secret);

ConnectionFactory<?> connectionFactory = connectionFactoryLocator.getConnectionFactory(providerId);
Connection<?> connection = connectionFactory.createConnection(connectionData);

if(connection.test()) {
    connection.sync();
} else {
    throw new AuthException();
}

return userEntityService.findOneByConnectionKey(connection.getKey());

But problem is that connection key is not initialized: providerUserId is null.

How can I acquire it in this case?

Victor Dombrovsky
  • 2,955
  • 3
  • 21
  • 33

2 Answers2

1

Generally, this code is intended to be used internally by Spring Social's connection framework (e.g., ConnectController, ConnectionRepository, ConnectionFactory, etc). Normally, you wouldn't use it directly unless you were looking to extend the framework or achieve something that the framework doesn't do for you.

Provider ID is determined by the connection factory being used. For example, the FacebookConnectionFactory defines it as "facebook". For Twitter it's "twitter". The value isn't terribly important, except that it be (1) consistently used for all connections against the same provider and (2) it be unique among all providers. Generally, it's good to just use the provider's name in all lowercase.

The access token is obtained by going through the OAuth "dance" (e.g., a series of redirects and prompts to obtain user authorization). ConnectController handles this for you...so does ProviderSignInController. If the token is an OAuth2 token, there will be no secret. If it's an OAuth 1.0(a) token, then you'll be given the secret along with the token at the end of the dance.

Craig Walls
  • 2,080
  • 1
  • 12
  • 13
  • I'll try to explain, why I use this code. My code is intended to protect access to my REST API. I want that only registered users will be able to access it. Registered users have "providerId" and "providerUserId" properties. This combination can be used to identify a user. When an user try to access my API he send "providerId", "accessToken" and, probably, "secret", which he acquired during OAuth "dance" on the client side. – Victor Dombrovsky Nov 09 '15 at 16:34
  • As soon as information was received by server, server checks that connection is valid. And if it is valid, server must check existence of user in database. That is why I need to acquire "providerUserId" using available information. – Victor Dombrovsky Nov 09 '15 at 16:34
  • Currently I have explored source codes of the framework and have found a solution. Spring Social uses: `Long.toString(twitter.userOperations().getProfileId())` and `google.plusOperations().getGoogleProfile().getId()` for this purpose. But may be you can give me an advice: may be I need to do what I do in other way using this framework? – Victor Dombrovsky Nov 09 '15 at 16:39
1

A bit late, however, if you are following the spring-social "philosophy", there is a UserConnection table. You can query it for providerUserId.

The schema is in JdbcUsersConnectionRepository.sql:

-- This SQL contains a "create table" that can be used to create a table that JdbcUsersConnectionRepository can persist
-- connection in. It is, however, not to be assumed to be production-ready, all-purpose SQL. It is merely representative
-- of the kind of table that JdbcUsersConnectionRepository works with. The table and column names, as well as the general
-- column types, are what is important. Specific column types and sizes that work may vary across database vendors and
-- the required sizes may vary across API providers. 

create table UserConnection (userId varchar(255) not null,
providerId varchar(255) not null,
providerUserId varchar(255),
rank int not null,
displayName varchar(255),
profileUrl varchar(512),
imageUrl varchar(512),
accessToken varchar(512) not null,
secret varchar(512),
refreshToken varchar(512),
expireTime bigint,
primary key (userId, providerId, providerUserId));
create unique index UserConnectionRank on UserConnection(userId, providerId, rank);
kmansoor
  • 4,265
  • 9
  • 52
  • 95