Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -453,9 +453,11 @@ private static ColumnMetadata getColumnMetadata(JdbcOperations jdbcOperations, S

private static SqlParameterValue mapToSqlParameter(String columnName, String value) {
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);
if ((Types.BLOB == columnMetadata.getDataType() || Types.BINARY == columnMetadata.getDataType())
&& StringUtils.hasText(value)) {
return new SqlParameterValue(columnMetadata.getDataType(), value.getBytes(StandardCharsets.UTF_8));
}
return new SqlParameterValue(columnMetadata.getDataType(), value);
}

/**
Expand Down Expand Up @@ -608,6 +610,19 @@ private String getLobValue(ResultSet rs, String columnName) throws SQLException
columnValue = new String(columnValueBytes, StandardCharsets.UTF_8);
}
}
else if (Types.BINARY == columnMetadata.getDataType()) {
byte[] columnValueBytes = this.lobHandler.getBlobAsBytes(rs, columnName);
if (columnValueBytes != null) {
// Trim trailing null bytes that may be present with fixed-length BINARY columns
int length = columnValueBytes.length;
while (length > 0 && columnValueBytes[length - 1] == 0) {
length--;
}
if (length > 0) {
columnValue = new String(columnValueBytes, 0, length, StandardCharsets.UTF_8);
}
}
}
else if (Types.CLOB == columnMetadata.getDataType()) {
columnValue = this.lobHandler.getClobAsString(rs, columnName);
}
Expand Down Expand Up @@ -803,6 +818,20 @@ protected void doSetValue(PreparedStatement ps, int parameterPosition, Object ar
this.lobCreator.setBlobAsBytes(ps, parameterPosition, valueBytes);
return;
}
if (paramValue.getSqlType() == Types.BINARY) {
byte[] valueBytes = null;
if (paramValue.getValue() != null) {
Object value = paramValue.getValue();
if (value instanceof byte[] byteArray) {
valueBytes = byteArray;
}
else if (value instanceof String stringValue) {
valueBytes = stringValue.getBytes(StandardCharsets.UTF_8);
}
}
this.lobCreator.setBlobAsBytes(ps, parameterPosition, valueBytes);
return;
}
if (paramValue.getSqlType() == Types.CLOB) {
if (paramValue.getValue() != null) {
Assert.isInstanceOf(String.class, paramValue.getValue(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@ public class JdbcOAuth2AuthorizationServiceTests {

private static final String OAUTH2_AUTHORIZATION_SCHEMA_CLOB_DATA_TYPE_SQL_RESOURCE = "org/springframework/security/oauth2/server/authorization/custom-oauth2-authorization-schema-clob-data-type.sql";

private static final String OAUTH2_AUTHORIZATION_SCHEMA_BINARY_DATA_TYPE_SQL_RESOURCE = "org/springframework/security/oauth2/server/authorization/custom-oauth2-authorization-schema-binary-data-type.sql";

private static final OAuth2TokenType AUTHORIZATION_CODE_TOKEN_TYPE = new OAuth2TokenType(OAuth2ParameterNames.CODE);

private static final OAuth2TokenType STATE_TOKEN_TYPE = new OAuth2TokenType(OAuth2ParameterNames.STATE);
Expand Down Expand Up @@ -520,6 +522,35 @@ public void tableDefinitionWhenClobSqlTypeThenAuthorizationUpdated() {
db.shutdown();
}

@Test
public void tableDefinitionWhenBinarySqlTypeThenAuthorizationUpdated() {
given(this.registeredClientRepository.findById(eq(REGISTERED_CLIENT.getId()))).willReturn(REGISTERED_CLIENT);

EmbeddedDatabase db = createDb(OAUTH2_AUTHORIZATION_SCHEMA_BINARY_DATA_TYPE_SQL_RESOURCE);
OAuth2AuthorizationService authorizationService = new JdbcOAuth2AuthorizationService(new JdbcTemplate(db),
this.registeredClientRepository);
OAuth2Authorization originalAuthorization = OAuth2Authorization.withRegisteredClient(REGISTERED_CLIENT)
.id(ID)
.principalName(PRINCIPAL_NAME)
.authorizationGrantType(AUTHORIZATION_GRANT_TYPE)
.token(AUTHORIZATION_CODE)
.build();
authorizationService.save(originalAuthorization);

OAuth2Authorization authorization = authorizationService.findById(originalAuthorization.getId());
assertThat(authorization).isEqualTo(originalAuthorization);

OAuth2Authorization updatedAuthorization = OAuth2Authorization.from(authorization)
.attribute("custom-name-1", "custom-value-1")
.build();
authorizationService.save(updatedAuthorization);

authorization = authorizationService.findById(updatedAuthorization.getId());
assertThat(authorization).isEqualTo(updatedAuthorization);
assertThat(authorization).isNotEqualTo(originalAuthorization);
db.shutdown();
}

private static EmbeddedDatabase createDb() {
return createDb(OAUTH2_AUTHORIZATION_SCHEMA_SQL_RESOURCE);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
CREATE TABLE oauth2_authorization (
id varchar(100) NOT NULL,
registered_client_id varchar(100) NOT NULL,
principal_name varchar(200) NOT NULL,
authorization_grant_type varchar(100) NOT NULL,
authorized_scopes varchar(1000) DEFAULT NULL,
attributes varchar(4000) DEFAULT NULL,
state varchar(500) DEFAULT NULL,
authorization_code_value binary(10000) DEFAULT NULL,
authorization_code_issued_at timestamp DEFAULT NULL,
authorization_code_expires_at timestamp DEFAULT NULL,
authorization_code_metadata varchar(2000) DEFAULT NULL,
access_token_value binary(10000) DEFAULT NULL,
access_token_issued_at timestamp DEFAULT NULL,
access_token_expires_at timestamp DEFAULT NULL,
access_token_metadata varchar(2000) DEFAULT NULL,
access_token_type varchar(100) DEFAULT NULL,
access_token_scopes varchar(1000) DEFAULT NULL,
oidc_id_token_value binary(10000) DEFAULT NULL,
oidc_id_token_issued_at timestamp DEFAULT NULL,
oidc_id_token_expires_at timestamp DEFAULT NULL,
oidc_id_token_metadata varchar(2000) DEFAULT NULL,
refresh_token_value binary(10000) DEFAULT NULL,
refresh_token_issued_at timestamp DEFAULT NULL,
refresh_token_expires_at timestamp DEFAULT NULL,
refresh_token_metadata varchar(2000) DEFAULT NULL,
user_code_value binary(10000) DEFAULT NULL,
user_code_issued_at timestamp DEFAULT NULL,
user_code_expires_at timestamp DEFAULT NULL,
user_code_metadata varchar(2000) DEFAULT NULL,
device_code_value binary(10000) DEFAULT NULL,
device_code_issued_at timestamp DEFAULT NULL,
device_code_expires_at timestamp DEFAULT NULL,
device_code_metadata varchar(2000) DEFAULT NULL,
PRIMARY KEY (id)
);