|
@@ -68,16 +68,18 @@ import org.springframework.util.StringUtils;
|
|
* {@link JdbcOperations} for {@link OAuth2Authorization} persistence.
|
|
* {@link JdbcOperations} for {@link OAuth2Authorization} persistence.
|
|
*
|
|
*
|
|
* <p>
|
|
* <p>
|
|
- * <b>IMPORTANT:</b> This {@code OAuth2AuthorizationService} depends on the table definition
|
|
|
|
- * described in
|
|
|
|
- * "classpath:org/springframework/security/oauth2/server/authorization/oauth2-authorization-schema.sql" and
|
|
|
|
- * therefore MUST be defined in the database schema.
|
|
|
|
|
|
+ * <b>IMPORTANT:</b> This {@code OAuth2AuthorizationService} depends on the table
|
|
|
|
+ * definition described in
|
|
|
|
+ * "classpath:org/springframework/security/oauth2/server/authorization/oauth2-authorization-schema.sql"
|
|
|
|
+ * and therefore MUST be defined in the database schema.
|
|
*
|
|
*
|
|
* <p>
|
|
* <p>
|
|
- * <b>NOTE:</b> This {@code OAuth2AuthorizationService} is a simplified JDBC implementation that MAY be used in a production environment.
|
|
|
|
- * However, it does have limitations as it likely won't perform well in an environment requiring high throughput.
|
|
|
|
- * The expectation is that the consuming application will provide their own implementation of {@code OAuth2AuthorizationService}
|
|
|
|
- * that meets the performance requirements for its deployment environment.
|
|
|
|
|
|
+ * <b>NOTE:</b> This {@code OAuth2AuthorizationService} is a simplified JDBC
|
|
|
|
+ * implementation that MAY be used in a production environment. However, it does have
|
|
|
|
+ * limitations as it likely won't perform well in an environment requiring high
|
|
|
|
+ * throughput. The expectation is that the consuming application will provide their own
|
|
|
|
+ * implementation of {@code OAuth2AuthorizationService} that meets the performance
|
|
|
|
+ * requirements for its deployment environment.
|
|
*
|
|
*
|
|
* @author Ovidiu Popa
|
|
* @author Ovidiu Popa
|
|
* @author Joe Grandja
|
|
* @author Joe Grandja
|
|
@@ -128,16 +130,23 @@ public class JdbcOAuth2AuthorizationService implements OAuth2AuthorizationServic
|
|
private static final String TABLE_NAME = "oauth2_authorization";
|
|
private static final String TABLE_NAME = "oauth2_authorization";
|
|
|
|
|
|
private static final String PK_FILTER = "id = ?";
|
|
private static final String PK_FILTER = "id = ?";
|
|
|
|
+
|
|
private static final String UNKNOWN_TOKEN_TYPE_FILTER = "state = ? OR authorization_code_value = ? OR "
|
|
private static final String UNKNOWN_TOKEN_TYPE_FILTER = "state = ? OR authorization_code_value = ? OR "
|
|
+ "access_token_value = ? OR oidc_id_token_value = ? OR refresh_token_value = ? OR user_code_value = ? OR "
|
|
+ "access_token_value = ? OR oidc_id_token_value = ? OR refresh_token_value = ? OR user_code_value = ? OR "
|
|
+ "device_code_value = ?";
|
|
+ "device_code_value = ?";
|
|
|
|
|
|
private static final String STATE_FILTER = "state = ?";
|
|
private static final String STATE_FILTER = "state = ?";
|
|
|
|
+
|
|
private static final String AUTHORIZATION_CODE_FILTER = "authorization_code_value = ?";
|
|
private static final String AUTHORIZATION_CODE_FILTER = "authorization_code_value = ?";
|
|
|
|
+
|
|
private static final String ACCESS_TOKEN_FILTER = "access_token_value = ?";
|
|
private static final String ACCESS_TOKEN_FILTER = "access_token_value = ?";
|
|
|
|
+
|
|
private static final String ID_TOKEN_FILTER = "oidc_id_token_value = ?";
|
|
private static final String ID_TOKEN_FILTER = "oidc_id_token_value = ?";
|
|
|
|
+
|
|
private static final String REFRESH_TOKEN_FILTER = "refresh_token_value = ?";
|
|
private static final String REFRESH_TOKEN_FILTER = "refresh_token_value = ?";
|
|
|
|
+
|
|
private static final String USER_CODE_FILTER = "user_code_value = ?";
|
|
private static final String USER_CODE_FILTER = "user_code_value = ?";
|
|
|
|
+
|
|
private static final String DEVICE_CODE_FILTER = "device_code_value = ?";
|
|
private static final String DEVICE_CODE_FILTER = "device_code_value = ?";
|
|
|
|
|
|
// @formatter:off
|
|
// @formatter:off
|
|
@@ -168,14 +177,16 @@ public class JdbcOAuth2AuthorizationService implements OAuth2AuthorizationServic
|
|
private static Map<String, ColumnMetadata> columnMetadataMap;
|
|
private static Map<String, ColumnMetadata> columnMetadataMap;
|
|
|
|
|
|
private final JdbcOperations jdbcOperations;
|
|
private final JdbcOperations jdbcOperations;
|
|
|
|
+
|
|
private final LobHandler lobHandler;
|
|
private final LobHandler lobHandler;
|
|
|
|
+
|
|
private RowMapper<OAuth2Authorization> authorizationRowMapper;
|
|
private RowMapper<OAuth2Authorization> authorizationRowMapper;
|
|
|
|
+
|
|
private Function<OAuth2Authorization, List<SqlParameterValue>> authorizationParametersMapper;
|
|
private Function<OAuth2Authorization, List<SqlParameterValue>> authorizationParametersMapper;
|
|
|
|
|
|
/**
|
|
/**
|
|
* Constructs a {@code JdbcOAuth2AuthorizationService} using the provided parameters.
|
|
* Constructs a {@code JdbcOAuth2AuthorizationService} using the provided parameters.
|
|
- *
|
|
|
|
- * @param jdbcOperations the JDBC operations
|
|
|
|
|
|
+ * @param jdbcOperations the JDBC operations
|
|
* @param registeredClientRepository the registered client repository
|
|
* @param registeredClientRepository the registered client repository
|
|
*/
|
|
*/
|
|
public JdbcOAuth2AuthorizationService(JdbcOperations jdbcOperations,
|
|
public JdbcOAuth2AuthorizationService(JdbcOperations jdbcOperations,
|
|
@@ -185,10 +196,9 @@ public class JdbcOAuth2AuthorizationService implements OAuth2AuthorizationServic
|
|
|
|
|
|
/**
|
|
/**
|
|
* Constructs a {@code JdbcOAuth2AuthorizationService} using the provided parameters.
|
|
* Constructs a {@code JdbcOAuth2AuthorizationService} using the provided parameters.
|
|
- *
|
|
|
|
- * @param jdbcOperations the JDBC operations
|
|
|
|
|
|
+ * @param jdbcOperations the JDBC operations
|
|
* @param registeredClientRepository the registered client repository
|
|
* @param registeredClientRepository the registered client repository
|
|
- * @param lobHandler the handler for large binary fields and large text fields
|
|
|
|
|
|
+ * @param lobHandler the handler for large binary fields and large text fields
|
|
*/
|
|
*/
|
|
public JdbcOAuth2AuthorizationService(JdbcOperations jdbcOperations,
|
|
public JdbcOAuth2AuthorizationService(JdbcOperations jdbcOperations,
|
|
RegisteredClientRepository registeredClientRepository, LobHandler lobHandler) {
|
|
RegisteredClientRepository registeredClientRepository, LobHandler lobHandler) {
|
|
@@ -197,7 +207,8 @@ public class JdbcOAuth2AuthorizationService implements OAuth2AuthorizationServic
|
|
Assert.notNull(lobHandler, "lobHandler cannot be null");
|
|
Assert.notNull(lobHandler, "lobHandler cannot be null");
|
|
this.jdbcOperations = jdbcOperations;
|
|
this.jdbcOperations = jdbcOperations;
|
|
this.lobHandler = lobHandler;
|
|
this.lobHandler = lobHandler;
|
|
- OAuth2AuthorizationRowMapper authorizationRowMapper = new OAuth2AuthorizationRowMapper(registeredClientRepository);
|
|
|
|
|
|
+ OAuth2AuthorizationRowMapper authorizationRowMapper = new OAuth2AuthorizationRowMapper(
|
|
|
|
+ registeredClientRepository);
|
|
authorizationRowMapper.setLobHandler(lobHandler);
|
|
authorizationRowMapper.setLobHandler(lobHandler);
|
|
this.authorizationRowMapper = authorizationRowMapper;
|
|
this.authorizationRowMapper = authorizationRowMapper;
|
|
this.authorizationParametersMapper = new OAuth2AuthorizationParametersMapper();
|
|
this.authorizationParametersMapper = new OAuth2AuthorizationParametersMapper();
|
|
@@ -210,7 +221,8 @@ public class JdbcOAuth2AuthorizationService implements OAuth2AuthorizationServic
|
|
OAuth2Authorization existingAuthorization = findById(authorization.getId());
|
|
OAuth2Authorization existingAuthorization = findById(authorization.getId());
|
|
if (existingAuthorization == null) {
|
|
if (existingAuthorization == null) {
|
|
insertAuthorization(authorization);
|
|
insertAuthorization(authorization);
|
|
- } else {
|
|
|
|
|
|
+ }
|
|
|
|
+ else {
|
|
updateAuthorization(authorization);
|
|
updateAuthorization(authorization);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -239,8 +251,7 @@ public class JdbcOAuth2AuthorizationService implements OAuth2AuthorizationServic
|
|
public void remove(OAuth2Authorization authorization) {
|
|
public void remove(OAuth2Authorization authorization) {
|
|
Assert.notNull(authorization, "authorization cannot be null");
|
|
Assert.notNull(authorization, "authorization cannot be null");
|
|
SqlParameterValue[] parameters = new SqlParameterValue[] {
|
|
SqlParameterValue[] parameters = new SqlParameterValue[] {
|
|
- new SqlParameterValue(Types.VARCHAR, authorization.getId())
|
|
|
|
- };
|
|
|
|
|
|
+ new SqlParameterValue(Types.VARCHAR, authorization.getId()) };
|
|
PreparedStatementSetter pss = new ArgumentPreparedStatementSetter(parameters);
|
|
PreparedStatementSetter pss = new ArgumentPreparedStatementSetter(parameters);
|
|
this.jdbcOperations.update(REMOVE_AUTHORIZATION_SQL, pss);
|
|
this.jdbcOperations.update(REMOVE_AUTHORIZATION_SQL, pss);
|
|
}
|
|
}
|
|
@@ -268,25 +279,32 @@ public class JdbcOAuth2AuthorizationService implements OAuth2AuthorizationServic
|
|
parameters.add(mapToSqlParameter("user_code_value", token));
|
|
parameters.add(mapToSqlParameter("user_code_value", token));
|
|
parameters.add(mapToSqlParameter("device_code_value", token));
|
|
parameters.add(mapToSqlParameter("device_code_value", token));
|
|
return findBy(UNKNOWN_TOKEN_TYPE_FILTER, parameters);
|
|
return findBy(UNKNOWN_TOKEN_TYPE_FILTER, parameters);
|
|
- } else if (OAuth2ParameterNames.STATE.equals(tokenType.getValue())) {
|
|
|
|
|
|
+ }
|
|
|
|
+ else if (OAuth2ParameterNames.STATE.equals(tokenType.getValue())) {
|
|
parameters.add(new SqlParameterValue(Types.VARCHAR, token));
|
|
parameters.add(new SqlParameterValue(Types.VARCHAR, token));
|
|
return findBy(STATE_FILTER, parameters);
|
|
return findBy(STATE_FILTER, parameters);
|
|
- } else if (OAuth2ParameterNames.CODE.equals(tokenType.getValue())) {
|
|
|
|
|
|
+ }
|
|
|
|
+ else if (OAuth2ParameterNames.CODE.equals(tokenType.getValue())) {
|
|
parameters.add(mapToSqlParameter("authorization_code_value", token));
|
|
parameters.add(mapToSqlParameter("authorization_code_value", token));
|
|
return findBy(AUTHORIZATION_CODE_FILTER, parameters);
|
|
return findBy(AUTHORIZATION_CODE_FILTER, parameters);
|
|
- } else if (OAuth2TokenType.ACCESS_TOKEN.equals(tokenType)) {
|
|
|
|
|
|
+ }
|
|
|
|
+ else if (OAuth2TokenType.ACCESS_TOKEN.equals(tokenType)) {
|
|
parameters.add(mapToSqlParameter("access_token_value", token));
|
|
parameters.add(mapToSqlParameter("access_token_value", token));
|
|
return findBy(ACCESS_TOKEN_FILTER, parameters);
|
|
return findBy(ACCESS_TOKEN_FILTER, parameters);
|
|
- } else if (OidcParameterNames.ID_TOKEN.equals(tokenType.getValue())) {
|
|
|
|
|
|
+ }
|
|
|
|
+ else if (OidcParameterNames.ID_TOKEN.equals(tokenType.getValue())) {
|
|
parameters.add(mapToSqlParameter("oidc_id_token_value", token));
|
|
parameters.add(mapToSqlParameter("oidc_id_token_value", token));
|
|
return findBy(ID_TOKEN_FILTER, parameters);
|
|
return findBy(ID_TOKEN_FILTER, parameters);
|
|
- } else if (OAuth2TokenType.REFRESH_TOKEN.equals(tokenType)) {
|
|
|
|
|
|
+ }
|
|
|
|
+ else if (OAuth2TokenType.REFRESH_TOKEN.equals(tokenType)) {
|
|
parameters.add(mapToSqlParameter("refresh_token_value", token));
|
|
parameters.add(mapToSqlParameter("refresh_token_value", token));
|
|
return findBy(REFRESH_TOKEN_FILTER, parameters);
|
|
return findBy(REFRESH_TOKEN_FILTER, parameters);
|
|
- } else if (OAuth2ParameterNames.USER_CODE.equals(tokenType.getValue())) {
|
|
|
|
|
|
+ }
|
|
|
|
+ else if (OAuth2ParameterNames.USER_CODE.equals(tokenType.getValue())) {
|
|
parameters.add(mapToSqlParameter("user_code_value", token));
|
|
parameters.add(mapToSqlParameter("user_code_value", token));
|
|
return findBy(USER_CODE_FILTER, parameters);
|
|
return findBy(USER_CODE_FILTER, parameters);
|
|
- } else if (OAuth2ParameterNames.DEVICE_CODE.equals(tokenType.getValue())) {
|
|
|
|
|
|
+ }
|
|
|
|
+ else if (OAuth2ParameterNames.DEVICE_CODE.equals(tokenType.getValue())) {
|
|
parameters.add(mapToSqlParameter("device_code_value", token));
|
|
parameters.add(mapToSqlParameter("device_code_value", token));
|
|
return findBy(DEVICE_CODE_FILTER, parameters);
|
|
return findBy(DEVICE_CODE_FILTER, parameters);
|
|
}
|
|
}
|
|
@@ -297,7 +315,8 @@ public class JdbcOAuth2AuthorizationService implements OAuth2AuthorizationServic
|
|
try (LobCreator lobCreator = getLobHandler().getLobCreator()) {
|
|
try (LobCreator lobCreator = getLobHandler().getLobCreator()) {
|
|
PreparedStatementSetter pss = new LobCreatorArgumentPreparedStatementSetter(lobCreator,
|
|
PreparedStatementSetter pss = new LobCreatorArgumentPreparedStatementSetter(lobCreator,
|
|
parameters.toArray());
|
|
parameters.toArray());
|
|
- List<OAuth2Authorization> result = getJdbcOperations().query(LOAD_AUTHORIZATION_SQL + filter, pss, getAuthorizationRowMapper());
|
|
|
|
|
|
+ List<OAuth2Authorization> result = getJdbcOperations().query(LOAD_AUTHORIZATION_SQL + filter, pss,
|
|
|
|
+ getAuthorizationRowMapper());
|
|
return !result.isEmpty() ? result.get(0) : null;
|
|
return !result.isEmpty() ? result.get(0) : null;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -306,9 +325,8 @@ public class JdbcOAuth2AuthorizationService implements OAuth2AuthorizationServic
|
|
* Sets the {@link RowMapper} used for mapping the current row in
|
|
* Sets the {@link RowMapper} used for mapping the current row in
|
|
* {@code java.sql.ResultSet} to {@link OAuth2Authorization}. The default is
|
|
* {@code java.sql.ResultSet} to {@link OAuth2Authorization}. The default is
|
|
* {@link OAuth2AuthorizationRowMapper}.
|
|
* {@link OAuth2AuthorizationRowMapper}.
|
|
- *
|
|
|
|
* @param authorizationRowMapper the {@link RowMapper} used for mapping the current
|
|
* @param authorizationRowMapper the {@link RowMapper} used for mapping the current
|
|
- * row in {@code ResultSet} to {@link OAuth2Authorization}
|
|
|
|
|
|
+ * row in {@code ResultSet} to {@link OAuth2Authorization}
|
|
*/
|
|
*/
|
|
public final void setAuthorizationRowMapper(RowMapper<OAuth2Authorization> authorizationRowMapper) {
|
|
public final void setAuthorizationRowMapper(RowMapper<OAuth2Authorization> authorizationRowMapper) {
|
|
Assert.notNull(authorizationRowMapper, "authorizationRowMapper cannot be null");
|
|
Assert.notNull(authorizationRowMapper, "authorizationRowMapper cannot be null");
|
|
@@ -316,12 +334,11 @@ public class JdbcOAuth2AuthorizationService implements OAuth2AuthorizationServic
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
- * Sets the {@code Function} used for mapping {@link OAuth2Authorization} to
|
|
|
|
- * a {@code List} of {@link SqlParameterValue}. The default is
|
|
|
|
|
|
+ * Sets the {@code Function} used for mapping {@link OAuth2Authorization} to a
|
|
|
|
+ * {@code List} of {@link SqlParameterValue}. The default is
|
|
* {@link OAuth2AuthorizationParametersMapper}.
|
|
* {@link OAuth2AuthorizationParametersMapper}.
|
|
- *
|
|
|
|
* @param authorizationParametersMapper the {@code Function} used for mapping
|
|
* @param authorizationParametersMapper the {@code Function} used for mapping
|
|
- * {@link OAuth2Authorization} to a {@code List} of {@link SqlParameterValue}
|
|
|
|
|
|
+ * {@link OAuth2Authorization} to a {@code List} of {@link SqlParameterValue}
|
|
*/
|
|
*/
|
|
public final void setAuthorizationParametersMapper(
|
|
public final void setAuthorizationParametersMapper(
|
|
Function<OAuth2Authorization, List<SqlParameterValue>> authorizationParametersMapper) {
|
|
Function<OAuth2Authorization, List<SqlParameterValue>> authorizationParametersMapper) {
|
|
@@ -350,8 +367,11 @@ public class JdbcOAuth2AuthorizationService implements OAuth2AuthorizationServic
|
|
* {@code java.sql.ResultSet} to {@link OAuth2Authorization}.
|
|
* {@code java.sql.ResultSet} to {@link OAuth2Authorization}.
|
|
*/
|
|
*/
|
|
public static class OAuth2AuthorizationRowMapper implements RowMapper<OAuth2Authorization> {
|
|
public static class OAuth2AuthorizationRowMapper implements RowMapper<OAuth2Authorization> {
|
|
|
|
+
|
|
private final RegisteredClientRepository registeredClientRepository;
|
|
private final RegisteredClientRepository registeredClientRepository;
|
|
|
|
+
|
|
private LobHandler lobHandler = new DefaultLobHandler();
|
|
private LobHandler lobHandler = new DefaultLobHandler();
|
|
|
|
+
|
|
private ObjectMapper objectMapper = new ObjectMapper();
|
|
private ObjectMapper objectMapper = new ObjectMapper();
|
|
|
|
|
|
public OAuth2AuthorizationRowMapper(RegisteredClientRepository registeredClientRepository) {
|
|
public OAuth2AuthorizationRowMapper(RegisteredClientRepository registeredClientRepository) {
|
|
@@ -370,8 +390,8 @@ public class JdbcOAuth2AuthorizationService implements OAuth2AuthorizationServic
|
|
String registeredClientId = rs.getString("registered_client_id");
|
|
String registeredClientId = rs.getString("registered_client_id");
|
|
RegisteredClient registeredClient = this.registeredClientRepository.findById(registeredClientId);
|
|
RegisteredClient registeredClient = this.registeredClientRepository.findById(registeredClientId);
|
|
if (registeredClient == null) {
|
|
if (registeredClient == null) {
|
|
- throw new DataRetrievalFailureException(
|
|
|
|
- "The RegisteredClient with id '" + registeredClientId + "' was not found in the RegisteredClientRepository.");
|
|
|
|
|
|
+ throw new DataRetrievalFailureException("The RegisteredClient with id '" + registeredClientId
|
|
|
|
+ + "' was not found in the RegisteredClientRepository.");
|
|
}
|
|
}
|
|
|
|
|
|
OAuth2Authorization.Builder builder = OAuth2Authorization.withRegisteredClient(registeredClient);
|
|
OAuth2Authorization.Builder builder = OAuth2Authorization.withRegisteredClient(registeredClient);
|
|
@@ -386,10 +406,10 @@ public class JdbcOAuth2AuthorizationService implements OAuth2AuthorizationServic
|
|
Map<String, Object> attributes = parseMap(getLobValue(rs, "attributes"));
|
|
Map<String, Object> attributes = parseMap(getLobValue(rs, "attributes"));
|
|
|
|
|
|
builder.id(id)
|
|
builder.id(id)
|
|
- .principalName(principalName)
|
|
|
|
- .authorizationGrantType(new AuthorizationGrantType(authorizationGrantType))
|
|
|
|
- .authorizedScopes(authorizedScopes)
|
|
|
|
- .attributes((attrs) -> attrs.putAll(attributes));
|
|
|
|
|
|
+ .principalName(principalName)
|
|
|
|
+ .authorizationGrantType(new AuthorizationGrantType(authorizationGrantType))
|
|
|
|
+ .authorizedScopes(authorizedScopes)
|
|
|
|
+ .attributes((attrs) -> attrs.putAll(attributes));
|
|
|
|
|
|
String state = rs.getString("state");
|
|
String state = rs.getString("state");
|
|
if (StringUtils.hasText(state)) {
|
|
if (StringUtils.hasText(state)) {
|
|
@@ -403,10 +423,11 @@ public class JdbcOAuth2AuthorizationService implements OAuth2AuthorizationServic
|
|
if (StringUtils.hasText(authorizationCodeValue)) {
|
|
if (StringUtils.hasText(authorizationCodeValue)) {
|
|
tokenIssuedAt = rs.getTimestamp("authorization_code_issued_at").toInstant();
|
|
tokenIssuedAt = rs.getTimestamp("authorization_code_issued_at").toInstant();
|
|
tokenExpiresAt = rs.getTimestamp("authorization_code_expires_at").toInstant();
|
|
tokenExpiresAt = rs.getTimestamp("authorization_code_expires_at").toInstant();
|
|
- Map<String, Object> authorizationCodeMetadata = parseMap(getLobValue(rs, "authorization_code_metadata"));
|
|
|
|
|
|
+ Map<String, Object> authorizationCodeMetadata = parseMap(
|
|
|
|
+ getLobValue(rs, "authorization_code_metadata"));
|
|
|
|
|
|
- OAuth2AuthorizationCode authorizationCode = new OAuth2AuthorizationCode(
|
|
|
|
- authorizationCodeValue, tokenIssuedAt, tokenExpiresAt);
|
|
|
|
|
|
+ OAuth2AuthorizationCode authorizationCode = new OAuth2AuthorizationCode(authorizationCodeValue,
|
|
|
|
+ tokenIssuedAt, tokenExpiresAt);
|
|
builder.token(authorizationCode, (metadata) -> metadata.putAll(authorizationCodeMetadata));
|
|
builder.token(authorizationCode, (metadata) -> metadata.putAll(authorizationCodeMetadata));
|
|
}
|
|
}
|
|
|
|
|
|
@@ -425,7 +446,8 @@ public class JdbcOAuth2AuthorizationService implements OAuth2AuthorizationServic
|
|
if (accessTokenScopes != null) {
|
|
if (accessTokenScopes != null) {
|
|
scopes = StringUtils.commaDelimitedListToSet(accessTokenScopes);
|
|
scopes = StringUtils.commaDelimitedListToSet(accessTokenScopes);
|
|
}
|
|
}
|
|
- OAuth2AccessToken accessToken = new OAuth2AccessToken(tokenType, accessTokenValue, tokenIssuedAt, tokenExpiresAt, scopes);
|
|
|
|
|
|
+ OAuth2AccessToken accessToken = new OAuth2AccessToken(tokenType, accessTokenValue, tokenIssuedAt,
|
|
|
|
+ tokenExpiresAt, scopes);
|
|
builder.token(accessToken, (metadata) -> metadata.putAll(accessTokenMetadata));
|
|
builder.token(accessToken, (metadata) -> metadata.putAll(accessTokenMetadata));
|
|
}
|
|
}
|
|
|
|
|
|
@@ -435,8 +457,8 @@ public class JdbcOAuth2AuthorizationService implements OAuth2AuthorizationServic
|
|
tokenExpiresAt = rs.getTimestamp("oidc_id_token_expires_at").toInstant();
|
|
tokenExpiresAt = rs.getTimestamp("oidc_id_token_expires_at").toInstant();
|
|
Map<String, Object> oidcTokenMetadata = parseMap(getLobValue(rs, "oidc_id_token_metadata"));
|
|
Map<String, Object> oidcTokenMetadata = parseMap(getLobValue(rs, "oidc_id_token_metadata"));
|
|
|
|
|
|
- OidcIdToken oidcToken = new OidcIdToken(
|
|
|
|
- oidcIdTokenValue, tokenIssuedAt, tokenExpiresAt, (Map<String, Object>) oidcTokenMetadata.get(OAuth2Authorization.Token.CLAIMS_METADATA_NAME));
|
|
|
|
|
|
+ OidcIdToken oidcToken = new OidcIdToken(oidcIdTokenValue, tokenIssuedAt, tokenExpiresAt,
|
|
|
|
+ (Map<String, Object>) oidcTokenMetadata.get(OAuth2Authorization.Token.CLAIMS_METADATA_NAME));
|
|
builder.token(oidcToken, (metadata) -> metadata.putAll(oidcTokenMetadata));
|
|
builder.token(oidcToken, (metadata) -> metadata.putAll(oidcTokenMetadata));
|
|
}
|
|
}
|
|
|
|
|
|
@@ -450,8 +472,8 @@ public class JdbcOAuth2AuthorizationService implements OAuth2AuthorizationServic
|
|
}
|
|
}
|
|
Map<String, Object> refreshTokenMetadata = parseMap(getLobValue(rs, "refresh_token_metadata"));
|
|
Map<String, Object> refreshTokenMetadata = parseMap(getLobValue(rs, "refresh_token_metadata"));
|
|
|
|
|
|
- OAuth2RefreshToken refreshToken = new OAuth2RefreshToken(
|
|
|
|
- refreshTokenValue, tokenIssuedAt, tokenExpiresAt);
|
|
|
|
|
|
+ OAuth2RefreshToken refreshToken = new OAuth2RefreshToken(refreshTokenValue, tokenIssuedAt,
|
|
|
|
+ tokenExpiresAt);
|
|
builder.token(refreshToken, (metadata) -> metadata.putAll(refreshTokenMetadata));
|
|
builder.token(refreshToken, (metadata) -> metadata.putAll(refreshTokenMetadata));
|
|
}
|
|
}
|
|
|
|
|
|
@@ -486,9 +508,11 @@ public class JdbcOAuth2AuthorizationService implements OAuth2AuthorizationServic
|
|
if (columnValueBytes != null) {
|
|
if (columnValueBytes != null) {
|
|
columnValue = new String(columnValueBytes, StandardCharsets.UTF_8);
|
|
columnValue = new String(columnValueBytes, StandardCharsets.UTF_8);
|
|
}
|
|
}
|
|
- } else if (Types.CLOB == columnMetadata.getDataType()) {
|
|
|
|
|
|
+ }
|
|
|
|
+ else if (Types.CLOB == columnMetadata.getDataType()) {
|
|
columnValue = this.lobHandler.getClobAsString(rs, columnName);
|
|
columnValue = this.lobHandler.getClobAsString(rs, columnName);
|
|
- } else {
|
|
|
|
|
|
+ }
|
|
|
|
+ else {
|
|
columnValue = rs.getString(columnName);
|
|
columnValue = rs.getString(columnName);
|
|
}
|
|
}
|
|
return columnValue;
|
|
return columnValue;
|
|
@@ -518,8 +542,10 @@ public class JdbcOAuth2AuthorizationService implements OAuth2AuthorizationServic
|
|
|
|
|
|
private Map<String, Object> parseMap(String data) {
|
|
private Map<String, Object> parseMap(String data) {
|
|
try {
|
|
try {
|
|
- return this.objectMapper.readValue(data, new TypeReference<Map<String, Object>>() {});
|
|
|
|
- } catch (Exception ex) {
|
|
|
|
|
|
+ return this.objectMapper.readValue(data, new TypeReference<Map<String, Object>>() {
|
|
|
|
+ });
|
|
|
|
+ }
|
|
|
|
+ catch (Exception ex) {
|
|
throw new IllegalArgumentException(ex.getMessage(), ex);
|
|
throw new IllegalArgumentException(ex.getMessage(), ex);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -530,7 +556,9 @@ public class JdbcOAuth2AuthorizationService implements OAuth2AuthorizationServic
|
|
* The default {@code Function} that maps {@link OAuth2Authorization} to a
|
|
* The default {@code Function} that maps {@link OAuth2Authorization} to a
|
|
* {@code List} of {@link SqlParameterValue}.
|
|
* {@code List} of {@link SqlParameterValue}.
|
|
*/
|
|
*/
|
|
- public static class OAuth2AuthorizationParametersMapper implements Function<OAuth2Authorization, List<SqlParameterValue>> {
|
|
|
|
|
|
+ public static class OAuth2AuthorizationParametersMapper
|
|
|
|
+ implements Function<OAuth2Authorization, List<SqlParameterValue>> {
|
|
|
|
+
|
|
private ObjectMapper objectMapper = new ObjectMapper();
|
|
private ObjectMapper objectMapper = new ObjectMapper();
|
|
|
|
|
|
public OAuth2AuthorizationParametersMapper() {
|
|
public OAuth2AuthorizationParametersMapper() {
|
|
@@ -564,46 +592,46 @@ public class JdbcOAuth2AuthorizationService implements OAuth2AuthorizationServic
|
|
}
|
|
}
|
|
parameters.add(new SqlParameterValue(Types.VARCHAR, state));
|
|
parameters.add(new SqlParameterValue(Types.VARCHAR, state));
|
|
|
|
|
|
- OAuth2Authorization.Token<OAuth2AuthorizationCode> authorizationCode =
|
|
|
|
- authorization.getToken(OAuth2AuthorizationCode.class);
|
|
|
|
- List<SqlParameterValue> authorizationCodeSqlParameters = toSqlParameterList(
|
|
|
|
- "authorization_code_value", "authorization_code_metadata", authorizationCode);
|
|
|
|
|
|
+ OAuth2Authorization.Token<OAuth2AuthorizationCode> authorizationCode = authorization
|
|
|
|
+ .getToken(OAuth2AuthorizationCode.class);
|
|
|
|
+ List<SqlParameterValue> authorizationCodeSqlParameters = toSqlParameterList("authorization_code_value",
|
|
|
|
+ "authorization_code_metadata", authorizationCode);
|
|
parameters.addAll(authorizationCodeSqlParameters);
|
|
parameters.addAll(authorizationCodeSqlParameters);
|
|
|
|
|
|
- OAuth2Authorization.Token<OAuth2AccessToken> accessToken =
|
|
|
|
- authorization.getToken(OAuth2AccessToken.class);
|
|
|
|
- List<SqlParameterValue> accessTokenSqlParameters = toSqlParameterList(
|
|
|
|
- "access_token_value", "access_token_metadata", accessToken);
|
|
|
|
|
|
+ OAuth2Authorization.Token<OAuth2AccessToken> accessToken = authorization.getToken(OAuth2AccessToken.class);
|
|
|
|
+ List<SqlParameterValue> accessTokenSqlParameters = toSqlParameterList("access_token_value",
|
|
|
|
+ "access_token_metadata", accessToken);
|
|
parameters.addAll(accessTokenSqlParameters);
|
|
parameters.addAll(accessTokenSqlParameters);
|
|
String accessTokenType = null;
|
|
String accessTokenType = null;
|
|
String accessTokenScopes = null;
|
|
String accessTokenScopes = null;
|
|
if (accessToken != null) {
|
|
if (accessToken != null) {
|
|
accessTokenType = accessToken.getToken().getTokenType().getValue();
|
|
accessTokenType = accessToken.getToken().getTokenType().getValue();
|
|
if (!CollectionUtils.isEmpty(accessToken.getToken().getScopes())) {
|
|
if (!CollectionUtils.isEmpty(accessToken.getToken().getScopes())) {
|
|
- accessTokenScopes = StringUtils.collectionToDelimitedString(accessToken.getToken().getScopes(), ",");
|
|
|
|
|
|
+ accessTokenScopes = StringUtils.collectionToDelimitedString(accessToken.getToken().getScopes(),
|
|
|
|
+ ",");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
parameters.add(new SqlParameterValue(Types.VARCHAR, accessTokenType));
|
|
parameters.add(new SqlParameterValue(Types.VARCHAR, accessTokenType));
|
|
parameters.add(new SqlParameterValue(Types.VARCHAR, accessTokenScopes));
|
|
parameters.add(new SqlParameterValue(Types.VARCHAR, accessTokenScopes));
|
|
|
|
|
|
OAuth2Authorization.Token<OidcIdToken> oidcIdToken = authorization.getToken(OidcIdToken.class);
|
|
OAuth2Authorization.Token<OidcIdToken> oidcIdToken = authorization.getToken(OidcIdToken.class);
|
|
- List<SqlParameterValue> oidcIdTokenSqlParameters = toSqlParameterList(
|
|
|
|
- "oidc_id_token_value", "oidc_id_token_metadata", oidcIdToken);
|
|
|
|
|
|
+ List<SqlParameterValue> oidcIdTokenSqlParameters = toSqlParameterList("oidc_id_token_value",
|
|
|
|
+ "oidc_id_token_metadata", oidcIdToken);
|
|
parameters.addAll(oidcIdTokenSqlParameters);
|
|
parameters.addAll(oidcIdTokenSqlParameters);
|
|
|
|
|
|
OAuth2Authorization.Token<OAuth2RefreshToken> refreshToken = authorization.getRefreshToken();
|
|
OAuth2Authorization.Token<OAuth2RefreshToken> refreshToken = authorization.getRefreshToken();
|
|
- List<SqlParameterValue> refreshTokenSqlParameters = toSqlParameterList(
|
|
|
|
- "refresh_token_value", "refresh_token_metadata", refreshToken);
|
|
|
|
|
|
+ List<SqlParameterValue> refreshTokenSqlParameters = toSqlParameterList("refresh_token_value",
|
|
|
|
+ "refresh_token_metadata", refreshToken);
|
|
parameters.addAll(refreshTokenSqlParameters);
|
|
parameters.addAll(refreshTokenSqlParameters);
|
|
|
|
|
|
OAuth2Authorization.Token<OAuth2UserCode> userCode = authorization.getToken(OAuth2UserCode.class);
|
|
OAuth2Authorization.Token<OAuth2UserCode> userCode = authorization.getToken(OAuth2UserCode.class);
|
|
- List<SqlParameterValue> userCodeSqlParameters = toSqlParameterList(
|
|
|
|
- "user_code_value", "user_code_metadata", userCode);
|
|
|
|
|
|
+ List<SqlParameterValue> userCodeSqlParameters = toSqlParameterList("user_code_value", "user_code_metadata",
|
|
|
|
+ userCode);
|
|
parameters.addAll(userCodeSqlParameters);
|
|
parameters.addAll(userCodeSqlParameters);
|
|
|
|
|
|
OAuth2Authorization.Token<OAuth2DeviceCode> deviceCode = authorization.getToken(OAuth2DeviceCode.class);
|
|
OAuth2Authorization.Token<OAuth2DeviceCode> deviceCode = authorization.getToken(OAuth2DeviceCode.class);
|
|
- List<SqlParameterValue> deviceCodeSqlParameters = toSqlParameterList(
|
|
|
|
- "device_code_value", "device_code_metadata", deviceCode);
|
|
|
|
|
|
+ List<SqlParameterValue> deviceCodeSqlParameters = toSqlParameterList("device_code_value",
|
|
|
|
+ "device_code_metadata", deviceCode);
|
|
parameters.addAll(deviceCodeSqlParameters);
|
|
parameters.addAll(deviceCodeSqlParameters);
|
|
|
|
|
|
return parameters;
|
|
return parameters;
|
|
@@ -618,8 +646,8 @@ public class JdbcOAuth2AuthorizationService implements OAuth2AuthorizationServic
|
|
return this.objectMapper;
|
|
return this.objectMapper;
|
|
}
|
|
}
|
|
|
|
|
|
- private <T extends OAuth2Token> List<SqlParameterValue> toSqlParameterList(
|
|
|
|
- String tokenColumnName, String tokenMetadataColumnName, OAuth2Authorization.Token<T> token) {
|
|
|
|
|
|
+ private <T extends OAuth2Token> List<SqlParameterValue> toSqlParameterList(String tokenColumnName,
|
|
|
|
+ String tokenMetadataColumnName, OAuth2Authorization.Token<T> token) {
|
|
|
|
|
|
List<SqlParameterValue> parameters = new ArrayList<>();
|
|
List<SqlParameterValue> parameters = new ArrayList<>();
|
|
String tokenValue = null;
|
|
String tokenValue = null;
|
|
@@ -647,7 +675,8 @@ public class JdbcOAuth2AuthorizationService implements OAuth2AuthorizationServic
|
|
private String writeMap(Map<String, Object> data) {
|
|
private String writeMap(Map<String, Object> data) {
|
|
try {
|
|
try {
|
|
return this.objectMapper.writeValueAsString(data);
|
|
return this.objectMapper.writeValueAsString(data);
|
|
- } catch (Exception ex) {
|
|
|
|
|
|
+ }
|
|
|
|
+ catch (Exception ex) {
|
|
throw new IllegalArgumentException(ex.getMessage(), ex);
|
|
throw new IllegalArgumentException(ex.getMessage(), ex);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -655,6 +684,7 @@ public class JdbcOAuth2AuthorizationService implements OAuth2AuthorizationServic
|
|
}
|
|
}
|
|
|
|
|
|
private static final class LobCreatorArgumentPreparedStatementSetter extends ArgumentPreparedStatementSetter {
|
|
private static final class LobCreatorArgumentPreparedStatementSetter extends ArgumentPreparedStatementSetter {
|
|
|
|
+
|
|
private final LobCreator lobCreator;
|
|
private final LobCreator lobCreator;
|
|
|
|
|
|
private LobCreatorArgumentPreparedStatementSetter(LobCreator lobCreator, Object[] args) {
|
|
private LobCreatorArgumentPreparedStatementSetter(LobCreator lobCreator, Object[] args) {
|
|
@@ -691,7 +721,9 @@ public class JdbcOAuth2AuthorizationService implements OAuth2AuthorizationServic
|
|
}
|
|
}
|
|
|
|
|
|
private static final class ColumnMetadata {
|
|
private static final class ColumnMetadata {
|
|
|
|
+
|
|
private final String columnName;
|
|
private final String columnName;
|
|
|
|
+
|
|
private final int dataType;
|
|
private final int dataType;
|
|
|
|
|
|
private ColumnMetadata(String columnName, int dataType) {
|
|
private ColumnMetadata(String columnName, int dataType) {
|
|
@@ -741,7 +773,8 @@ public class JdbcOAuth2AuthorizationService implements OAuth2AuthorizationServic
|
|
columnMetadataMap.put(columnMetadata.getColumnName(), columnMetadata);
|
|
columnMetadataMap.put(columnMetadata.getColumnName(), columnMetadata);
|
|
}
|
|
}
|
|
|
|
|
|
- private static ColumnMetadata getColumnMetadata(JdbcOperations jdbcOperations, String columnName, int defaultDataType) {
|
|
|
|
|
|
+ private static ColumnMetadata getColumnMetadata(JdbcOperations jdbcOperations, String columnName,
|
|
|
|
+ int defaultDataType) {
|
|
Integer dataType = jdbcOperations.execute((ConnectionCallback<Integer>) conn -> {
|
|
Integer dataType = jdbcOperations.execute((ConnectionCallback<Integer>) conn -> {
|
|
DatabaseMetaData databaseMetaData = conn.getMetaData();
|
|
DatabaseMetaData databaseMetaData = conn.getMetaData();
|
|
ResultSet rs = databaseMetaData.getColumns(null, null, TABLE_NAME, columnName);
|
|
ResultSet rs = databaseMetaData.getColumns(null, null, TABLE_NAME, columnName);
|
|
@@ -749,10 +782,13 @@ public class JdbcOAuth2AuthorizationService implements OAuth2AuthorizationServic
|
|
return rs.getInt("DATA_TYPE");
|
|
return rs.getInt("DATA_TYPE");
|
|
}
|
|
}
|
|
// NOTE: (Applies to HSQL)
|
|
// NOTE: (Applies to HSQL)
|
|
- // When a database object is created with one of the CREATE statements or renamed with the ALTER statement,
|
|
|
|
- // if the name is enclosed in double quotes, the exact name is used as the case-normal form.
|
|
|
|
|
|
+ // When a database object is created with one of the CREATE statements or
|
|
|
|
+ // renamed with the ALTER statement,
|
|
|
|
+ // if the name is enclosed in double quotes, the exact name is used as the
|
|
|
|
+ // case-normal form.
|
|
// But if it is not enclosed in double quotes,
|
|
// But if it is not enclosed in double quotes,
|
|
- // the name is converted to uppercase and this uppercase version is stored in the database as the case-normal form.
|
|
|
|
|
|
+ // the name is converted to uppercase and this uppercase version is stored in
|
|
|
|
+ // the database as the case-normal form.
|
|
rs = databaseMetaData.getColumns(null, null, TABLE_NAME.toUpperCase(), columnName.toUpperCase());
|
|
rs = databaseMetaData.getColumns(null, null, TABLE_NAME.toUpperCase(), columnName.toUpperCase());
|
|
if (rs.next()) {
|
|
if (rs.next()) {
|
|
return rs.getInt("DATA_TYPE");
|
|
return rs.getInt("DATA_TYPE");
|
|
@@ -764,9 +800,9 @@ public class JdbcOAuth2AuthorizationService implements OAuth2AuthorizationServic
|
|
|
|
|
|
private static SqlParameterValue mapToSqlParameter(String columnName, String value) {
|
|
private static SqlParameterValue mapToSqlParameter(String columnName, String value) {
|
|
ColumnMetadata columnMetadata = columnMetadataMap.get(columnName);
|
|
ColumnMetadata columnMetadata = columnMetadataMap.get(columnName);
|
|
- return Types.BLOB == columnMetadata.getDataType() && StringUtils.hasText(value) ?
|
|
|
|
- new SqlParameterValue(Types.BLOB, value.getBytes(StandardCharsets.UTF_8)) :
|
|
|
|
- new SqlParameterValue(columnMetadata.getDataType(), value);
|
|
|
|
|
|
+ return Types.BLOB == columnMetadata.getDataType() && StringUtils.hasText(value)
|
|
|
|
+ ? new SqlParameterValue(Types.BLOB, value.getBytes(StandardCharsets.UTF_8))
|
|
|
|
+ : new SqlParameterValue(columnMetadata.getDataType(), value);
|
|
}
|
|
}
|
|
|
|
|
|
}
|
|
}
|