我们希望推动定期或事件驱动的Glass Timeline更新,我们遇到了Java Glass入门项目中提供的AuthUtil问题。
通常情况下,我们只需在用户启用具有Google权限的应用后调用以下内容:
Credential credential = AuthUtil.getCredential(googleUserToken);
在身份验证servlet或通知servlet期间从HttpRequest检索Google UserToken时,这非常有效。
我们在App身份验证阶段坚持用户的Google用户令牌。但是,尝试从Quartz作业或消息队列中获取Google凭据时,相同的有效Google UserTokens会返回null Credential对象。
我们调试了代码并注意到AuthUtil正在使用ListableMemoryCredentialStore,并且当尝试从Quartz作业中检索Credential时,此存储为空。
答案 0 :(得分:2)
在这里回答我自己的问题。与starter项目一起打包的AuthUtil帮助程序仅提供Google Credentials的内存缓存。如果服务器重新启动或新实例,缓存将消失,然后用户将被定向到Google OAuth流程。
要防止这种情况并为Glass应用程序提供可伸缩性,请使用以下CredentialStore实现并替换AuthUtil中ListableMemoryCredentialStore的使用。它不是最干净的,但它是轻量级的并且保留了AuthUtil的单一意图。
将JDBC路径替换为每个数据库帮助程序方法的数据库,模式,用户名和密码。 Google凭证表只不过是一个存储userId作为PK,accessToken,resfreshToken和expriationTimeInMillis的四列表。显然,您可以根据需要随意调整数据模型。
/**
* Created by Dayel Ostraco
* Date: 12/4/13
*
* This extends the Google OAuth2 CredentialStore interface and uses a Database backend to persist Google Credentials
* in a thread safe manner.
*
*/
public class DatabaseCredentialStore implements CredentialStore {
private static final Logger LOGGER = LoggerFactory.getLogger(DatabaseCredentialStore.class);
/**
* Lock on access to the database Credential store.
*/
private final Lock lock = new ReentrantLock();
/**
* Stores a Google OAuth2 Credential in the database.
*
* @param userId String
* @param credential Google OAuth2 Credential
*/
public void store(String userId, Credential credential) {
lock.lock();
try {
DatabasePersistedCredential item = findByUserId(userId);
if (item == null) {
item = new DatabasePersistedCredential();
item.store(userId, credential);
create(item);
}
item.store(userId, credential);
} finally {
lock.unlock();
}
}
/**
* Removes a persisted Google Credential from the database.
*
* @param userId String
* @param credential Google OAuth2 Credential
*/
public void delete(String userId, Credential credential) {
lock.lock();
try {
DatabasePersistedCredential item = findByUserId(credential.getAccessToken());
delete(item);
} finally {
lock.unlock();
}
}
/**
* Loads a Google Credential with the contents of the persisted Google Credentials.
*
* @param userId String
* @param credential Google OAuth2 Credential
* @return boolean
*/
public boolean load(String userId, Credential credential) {
lock.lock();
try {
DatabasePersistedCredential item = findByUserId(userId);
if (item != null) {
item.load(userId, credential);
}
return item != null;
} finally {
lock.unlock();
}
}
/**
* Returns all users in the Google Credentials Table
* @return List of all persisted Google authenticated user IDs
*/
public List<String> listAllUsers() {
List<String> userIds = new ArrayList<>();
for(DatabasePersistedCredential credential : findAll()) {
userIds.add(credential.getUserId());
}
return userIds;
}
/****************
* JDBC Methods *
***************/
/**
* Persists a new Google Credential to the database.
*
* @param credential DatabasePersistedCredential
*/
private void create(DatabasePersistedCredential credential) {
Connection connect;
PreparedStatement preparedStatement;
try {
Class.forName("com.mysql.jdbc.Driver");
connect = DriverManager.getConnection("jdbc:mysql://yourdatabaseurl:3306/schema?user=un&password=password");
preparedStatement = connect.prepareStatement("INSERT INTO GoogleCredential values (?, ?, ?, ?)");
preparedStatement.setString(1, credential.getUserId());
preparedStatement.setString(2, credential.getAccessToken());
preparedStatement.setString(3, credential.getRefreshToken());
preparedStatement.setLong(4, credential.getExpirationTimeInMillis());
preparedStatement.executeUpdate();
} catch (ClassNotFoundException e) {
LOGGER.error("Could not load MySQL Driver.", e);
} catch (SQLException e) {
LOGGER.error("Could not persist DatabasePersistedCredential.", e);
}
}
/**
* Removes a Google credential from the database.
*
* @param credential DatabasePersistedCredential
*/
private void delete(DatabasePersistedCredential credential) {
Connection connect;
PreparedStatement preparedStatement;
ResultSet resultSet;
try {
Class.forName("com.mysql.jdbc.Driver");
connect = DriverManager.getConnection("jdbc:mysql://yourdatabaseurl:3306/schema?user=un&password=password");
preparedStatement = connect.prepareStatement("DELETE * FROM spgglassdb.GoogleCredential WHERE userId = ?;");
preparedStatement.setString(1, credential.getUserId());
preparedStatement.executeQuery();
} catch (ClassNotFoundException e) {
LOGGER.error("Could not load MySQL Driver.", e);
} catch (SQLException e) {
LOGGER.error("Could not persist DatabasePersistedCredential.", e);
}
}
/**
* Returns the Google credentials for a user with the passed in userId.
*
* @param userId String
* @return DatabasePersistedCredential
*/
private DatabasePersistedCredential findByUserId(String userId) {
Connection connect;
PreparedStatement preparedStatement;
ResultSet resultSet;
try {
Class.forName("com.mysql.jdbc.Driver");
connect = DriverManager.getConnection("jjdbc:mysql://yourdatabaseurl:3306/schema?user=un&password=password");
preparedStatement = connect.prepareStatement("SELECT * FROM spgglassdb.GoogleCredential WHERE userId = ?;");
preparedStatement.setString(1, userId);
resultSet = preparedStatement.executeQuery();
List<DatabasePersistedCredential> credentials = convertResultsSet(resultSet);
if(credentials.size()==1) {
return credentials.get(0);
} else {
return null;
}
} catch (ClassNotFoundException e) {
LOGGER.error("Could not load MySQL Driver.", e);
} catch (SQLException e) {
LOGGER.error("Could not persist DatabasePersistedCredential.", e);
}
return null;
}
/**
* Returns all DatabasePersistedCredentials located in the database.
*
* @return List<DatabasePersistedCredential>
*/
private List<DatabasePersistedCredential> findAll() {
Connection connect;
PreparedStatement preparedStatement;
ResultSet resultSet;
try {
Class.forName("com.mysql.jdbc.Driver");
connect = DriverManager.getConnection("jdbc:mysql://yourdatabaseurl:3306/schema?user=un&password=password");
preparedStatement = connect.prepareStatement("SELECT * FROM spgglassdb.GoogleCredential;");
resultSet = preparedStatement.executeQuery();
List<DatabasePersistedCredential> credentials = convertResultsSet(resultSet);
return credentials;
} catch (ClassNotFoundException e) {
LOGGER.error("Could not load MySQL Driver.", e);
} catch (SQLException e) {
LOGGER.error("Could not persist DatabasePersistedCredential.", e);
}
return null;
}
/**
* Converts a ResultSet to a collection of DatabasePersistedCredentials.
*
* @param resultSet JDBC ResultSet
* @return List<DatabasePersistedCredential>
* @throws SQLException
*/
private List<DatabasePersistedCredential> convertResultsSet(ResultSet resultSet) throws SQLException {
List<DatabasePersistedCredential> credentials = new ArrayList<>();
while (resultSet.next()) {
DatabasePersistedCredential credential = new DatabasePersistedCredential();
String accessToken = resultSet.getString("accessToken");
String refreshToken = resultSet.getString("refreshToken");
Long expirationTimeInMillis = resultSet.getLong("expirationTimeInMillis");
credential.setAccessToken(accessToken);
credential.setRefreshToken(refreshToken);
credential.setExpirationTimeInMillis(expirationTimeInMillis);
credentials.add(credential);
}
return credentials;
}
}