-
Notifications
You must be signed in to change notification settings - Fork 6k
OAuth2 Client - JdbcOAuth2AuthorizedClientService - Issue with PostgreSQL #8539
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
@joshdcollins Is the FYI, it is very difficult to provide an implementation that works out of the box for all databases. This implementation strives to use standard sql datatypes and is a simplified JDBC implementation. However, it is designed to be customizable so user's can provide customizations for database vendors that deviate from the standard sql types.
Take a look at If the |
Thanks @jgrandja I'm in alignment with closing and supporting as-is |
In case this helps anyone in future: once you've updated the schema, the following custom JDBC parameters mapper works for PostgreSQL:
Set it on your
|
Postgres has alternatives if not using a BLOB and its better the framework uses ORM specifications (JPA) so that most of the databases are supported. |
there's one more related issue - timestamps are saved as NON UTC, so that clients from different timezones faced expired tokens (however jwt token itself contained right timestamp) ; public class PostgreSqlOAuth2AuthorizedClientParametersMapper extends JdbcOAuth2AuthorizedClientService.OAuth2AuthorizedClientParametersMapper {
@Override
public List<SqlParameterValue> apply(JdbcOAuth2AuthorizedClientService.OAuth2AuthorizedClientHolder holder) {
return super.apply(holder).stream()
.map(parameter -> {
if (parameter.getSqlType() == Types.BLOB) {
return new SqlParameterValue(Types.BINARY, parameter.getValue());
} else if (parameter.getSqlType() == Types.TIMESTAMP) {
// saving as UTC stamp!
Object value = parameter.getValue();
Timestamp timestampValue = (Timestamp) value;
if (timestampValue != null) {
Instant instant = timestampValue.toInstant();
LocalDateTime dateTimeUtc = LocalDateTime.ofInstant(instant, ZoneOffset.UTC);
Timestamp timestampUtc = Timestamp.valueOf(dateTimeUtc);
return new SqlParameterValue(Types.TIMESTAMP, timestampUtc);
}
}
return parameter;
})
.collect(Collectors.toList());
}
} and another one: public class UtcOAuth2AuthorizedClientRowMapper
extends JdbcOAuth2AuthorizedClientService.OAuth2AuthorizedClientRowMapper {
public UtcOAuth2AuthorizedClientRowMapper(ClientRegistrationRepository clientRegistrationRepository) {
super(clientRegistrationRepository);
}
@Override
public OAuth2AuthorizedClient mapRow(ResultSet rs, int i) throws SQLException {
ResultSet rsWrapper = (ResultSet) Proxy.newProxyInstance(
getClass().getClassLoader(),
new Class[]{ResultSet.class},
(proxy, method, args) -> {
if (method.getName().equals("getTimestamp") && args.length == 1) {
// getting as UTC stamp!
Calendar cal = Calendar.getInstance();
cal.setTimeZone(TimeZone.getTimeZone("UTC"));
Object theOnlyArg = args[0];
if (theOnlyArg.getClass() == String.class) {
return rs.getTimestamp((String) theOnlyArg, cal);
} else if (theOnlyArg.getClass() == Integer.class) {
return rs.getTimestamp((Integer) theOnlyArg, cal);
}
}
return method.invoke(rs, args);
});
return super.mapRow(rsWrapper, i);
}
} all together: @Bean
OAuth2AuthorizedClientService authorizedClientService(DataSource dataSource,
ClientRegistrationRepository clientRegRepo) {
logger.info(" - JDBC: creating JdbcOAuth2AuthorizedClientService");
JdbcTemplate jdbcOps = new JdbcTemplate(dataSource);
JdbcOAuth2AuthorizedClientService clientService = new JdbcOAuth2AuthorizedClientService(jdbcOps, clientRegRepo);
clientService.setAuthorizedClientParametersMapper(new PostgreSqlOAuth2AuthorizedClientParametersMapper());
clientService.setAuthorizedClientRowMapper(new UtcOAuth2AuthorizedClientRowMapper(clientRegRepo));
return clientService;
} |
Hi, @jgrandja. I noticed that the problem with the blob type for different JDBC drivers is quite a common issue. Maybe it would be a good idea to add a constructor with |
Describe the bug
I receive an exception from the Postgres driver due to type mismatches when using the default functionality of the JdbcOauth2AuthorizedClientService.
To Reproduce
setObject(int parameterIndex, Object in, int targetSqlType, int scale)
inPgPreparedStatement
- line 650. The logic from lines 643-650, when a Sql.Types.BLOB is provided, Postgres expects the value to be either a java.sql.Blob or an InputStream.Expected behavior
JdbcOAuth2AuthorizedClientService works with Postgres.
** Other Notes **
I was able to work around this by using setAuthorizedClientParametersMapper and providing my own implementation that used Types.BINARY instead of Types.BLOB. But I did not test this on other RDBMS for broader compatibility.
The text was updated successfully, but these errors were encountered: