Skip to content

Commit 2b28f31

Browse files
committed
Change blob datatype to varchar when saving Oauth2Authorization to the database
Use CLOB instead of BLOB. With CLOB type the underlying schema can store varchars and clobs as well (if this is supported by the database) Closes gh-480
1 parent 5982d22 commit 2b28f31

File tree

2 files changed

+31
-36
lines changed

2 files changed

+31
-36
lines changed

oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/JdbcOAuth2AuthorizationService.java

Lines changed: 26 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
*/
1616
package org.springframework.security.oauth2.server.authorization;
1717

18-
import java.nio.charset.StandardCharsets;
1918
import java.sql.PreparedStatement;
2019
import java.sql.ResultSet;
2120
import java.sql.SQLException;
@@ -232,21 +231,21 @@ public OAuth2Authorization findByToken(String token, @Nullable OAuth2TokenType t
232231
List<SqlParameterValue> parameters = new ArrayList<>();
233232
if (tokenType == null) {
234233
parameters.add(new SqlParameterValue(Types.VARCHAR, token));
235-
parameters.add(new SqlParameterValue(Types.BLOB, token.getBytes(StandardCharsets.UTF_8)));
236-
parameters.add(new SqlParameterValue(Types.BLOB, token.getBytes(StandardCharsets.UTF_8)));
237-
parameters.add(new SqlParameterValue(Types.BLOB, token.getBytes(StandardCharsets.UTF_8)));
234+
parameters.add(new SqlParameterValue(Types.CLOB, token));
235+
parameters.add(new SqlParameterValue(Types.CLOB, token));
236+
parameters.add(new SqlParameterValue(Types.CLOB, token));
238237
return findBy(UNKNOWN_TOKEN_TYPE_FILTER, parameters);
239238
} else if (OAuth2ParameterNames.STATE.equals(tokenType.getValue())) {
240239
parameters.add(new SqlParameterValue(Types.VARCHAR, token));
241240
return findBy(STATE_FILTER, parameters);
242241
} else if (OAuth2ParameterNames.CODE.equals(tokenType.getValue())) {
243-
parameters.add(new SqlParameterValue(Types.BLOB, token.getBytes(StandardCharsets.UTF_8)));
242+
parameters.add(new SqlParameterValue(Types.CLOB, token));
244243
return findBy(AUTHORIZATION_CODE_FILTER, parameters);
245244
} else if (OAuth2TokenType.ACCESS_TOKEN.equals(tokenType)) {
246-
parameters.add(new SqlParameterValue(Types.BLOB, token.getBytes(StandardCharsets.UTF_8)));
245+
parameters.add(new SqlParameterValue(Types.CLOB, token));
247246
return findBy(ACCESS_TOKEN_FILTER, parameters);
248247
} else if (OAuth2TokenType.REFRESH_TOKEN.equals(tokenType)) {
249-
parameters.add(new SqlParameterValue(Types.BLOB, token.getBytes(StandardCharsets.UTF_8)));
248+
parameters.add(new SqlParameterValue(Types.CLOB, token));
250249
return findBy(REFRESH_TOKEN_FILTER, parameters);
251250
}
252251
return null;
@@ -352,22 +351,20 @@ public OAuth2Authorization mapRow(ResultSet rs, int rowNum) throws SQLException
352351
String tokenValue;
353352
Instant tokenIssuedAt;
354353
Instant tokenExpiresAt;
355-
byte[] authorizationCodeValue = this.lobHandler.getBlobAsBytes(rs, "authorization_code_value");
354+
String authorizationCodeValue = this.lobHandler.getClobAsString(rs, "authorization_code_value");
356355

357-
if (authorizationCodeValue != null) {
358-
tokenValue = new String(authorizationCodeValue, StandardCharsets.UTF_8);
356+
if (StringUtils.hasText(authorizationCodeValue)) {
359357
tokenIssuedAt = rs.getTimestamp("authorization_code_issued_at").toInstant();
360358
tokenExpiresAt = rs.getTimestamp("authorization_code_expires_at").toInstant();
361359
Map<String, Object> authorizationCodeMetadata = parseMap(rs.getString("authorization_code_metadata"));
362360

363361
OAuth2AuthorizationCode authorizationCode = new OAuth2AuthorizationCode(
364-
tokenValue, tokenIssuedAt, tokenExpiresAt);
362+
authorizationCodeValue, tokenIssuedAt, tokenExpiresAt);
365363
builder.token(authorizationCode, (metadata) -> metadata.putAll(authorizationCodeMetadata));
366364
}
367365

368-
byte[] accessTokenValue = this.lobHandler.getBlobAsBytes(rs, "access_token_value");
369-
if (accessTokenValue != null) {
370-
tokenValue = new String(accessTokenValue, StandardCharsets.UTF_8);
366+
String accessTokenValue = this.lobHandler.getClobAsString(rs, "access_token_value");
367+
if (StringUtils.hasText(accessTokenValue)) {
371368
tokenIssuedAt = rs.getTimestamp("access_token_issued_at").toInstant();
372369
tokenExpiresAt = rs.getTimestamp("access_token_expires_at").toInstant();
373370
Map<String, Object> accessTokenMetadata = parseMap(rs.getString("access_token_metadata"));
@@ -381,25 +378,23 @@ public OAuth2Authorization mapRow(ResultSet rs, int rowNum) throws SQLException
381378
if (accessTokenScopes != null) {
382379
scopes = StringUtils.commaDelimitedListToSet(accessTokenScopes);
383380
}
384-
OAuth2AccessToken accessToken = new OAuth2AccessToken(tokenType, tokenValue, tokenIssuedAt, tokenExpiresAt, scopes);
381+
OAuth2AccessToken accessToken = new OAuth2AccessToken(tokenType, accessTokenValue, tokenIssuedAt, tokenExpiresAt, scopes);
385382
builder.token(accessToken, (metadata) -> metadata.putAll(accessTokenMetadata));
386383
}
387384

388-
byte[] oidcIdTokenValue = this.lobHandler.getBlobAsBytes(rs, "oidc_id_token_value");
389-
if (oidcIdTokenValue != null) {
390-
tokenValue = new String(oidcIdTokenValue, StandardCharsets.UTF_8);
385+
String oidcIdTokenValue = this.lobHandler.getClobAsString(rs, "oidc_id_token_value");
386+
if (StringUtils.hasText(oidcIdTokenValue)) {
391387
tokenIssuedAt = rs.getTimestamp("oidc_id_token_issued_at").toInstant();
392388
tokenExpiresAt = rs.getTimestamp("oidc_id_token_expires_at").toInstant();
393389
Map<String, Object> oidcTokenMetadata = parseMap(rs.getString("oidc_id_token_metadata"));
394390

395391
OidcIdToken oidcToken = new OidcIdToken(
396-
tokenValue, tokenIssuedAt, tokenExpiresAt, (Map<String, Object>) oidcTokenMetadata.get(OAuth2Authorization.Token.CLAIMS_METADATA_NAME));
392+
oidcIdTokenValue, tokenIssuedAt, tokenExpiresAt, (Map<String, Object>) oidcTokenMetadata.get(OAuth2Authorization.Token.CLAIMS_METADATA_NAME));
397393
builder.token(oidcToken, (metadata) -> metadata.putAll(oidcTokenMetadata));
398394
}
399395

400-
byte[] refreshTokenValue = this.lobHandler.getBlobAsBytes(rs, "refresh_token_value");
401-
if (refreshTokenValue != null) {
402-
tokenValue = new String(refreshTokenValue, StandardCharsets.UTF_8);
396+
String refreshTokenValue = this.lobHandler.getClobAsString(rs, "refresh_token_value");
397+
if (StringUtils.hasText(refreshTokenValue)) {
403398
tokenIssuedAt = rs.getTimestamp("refresh_token_issued_at").toInstant();
404399
tokenExpiresAt = null;
405400
Timestamp refreshTokenExpiresAt = rs.getTimestamp("refresh_token_expires_at");
@@ -409,7 +404,7 @@ public OAuth2Authorization mapRow(ResultSet rs, int rowNum) throws SQLException
409404
Map<String, Object> refreshTokenMetadata = parseMap(rs.getString("refresh_token_metadata"));
410405

411406
OAuth2RefreshToken refreshToken = new OAuth2RefreshToken(
412-
tokenValue, tokenIssuedAt, tokenExpiresAt);
407+
refreshTokenValue, tokenIssuedAt, tokenExpiresAt);
413408
builder.token(refreshToken, (metadata) -> metadata.putAll(refreshTokenMetadata));
414409
}
415410
return builder.build();
@@ -520,12 +515,12 @@ protected final ObjectMapper getObjectMapper() {
520515

521516
private <T extends AbstractOAuth2Token> List<SqlParameterValue> toSqlParameterList(OAuth2Authorization.Token<T> token) {
522517
List<SqlParameterValue> parameters = new ArrayList<>();
523-
byte[] tokenValue = null;
518+
String tokenValue = null;
524519
Timestamp tokenIssuedAt = null;
525520
Timestamp tokenExpiresAt = null;
526521
String metadata = null;
527522
if (token != null) {
528-
tokenValue = token.getToken().getTokenValue().getBytes(StandardCharsets.UTF_8);
523+
tokenValue = token.getToken().getTokenValue();
529524
if (token.getToken().getIssuedAt() != null) {
530525
tokenIssuedAt = Timestamp.from(token.getToken().getIssuedAt());
531526
}
@@ -534,7 +529,7 @@ private <T extends AbstractOAuth2Token> List<SqlParameterValue> toSqlParameterLi
534529
}
535530
metadata = writeMap(token.getMetadata());
536531
}
537-
parameters.add(new SqlParameterValue(Types.BLOB, tokenValue));
532+
parameters.add(new SqlParameterValue(Types.CLOB, tokenValue));
538533
parameters.add(new SqlParameterValue(Types.TIMESTAMP, tokenIssuedAt));
539534
parameters.add(new SqlParameterValue(Types.TIMESTAMP, tokenExpiresAt));
540535
parameters.add(new SqlParameterValue(Types.VARCHAR, metadata));
@@ -563,13 +558,13 @@ private LobCreatorArgumentPreparedStatementSetter(LobCreator lobCreator, Object[
563558
protected void doSetValue(PreparedStatement ps, int parameterPosition, Object argValue) throws SQLException {
564559
if (argValue instanceof SqlParameterValue) {
565560
SqlParameterValue paramValue = (SqlParameterValue) argValue;
566-
if (paramValue.getSqlType() == Types.BLOB) {
561+
if (paramValue.getSqlType() == Types.CLOB) {
567562
if (paramValue.getValue() != null) {
568-
Assert.isInstanceOf(byte[].class, paramValue.getValue(),
569-
"Value of blob parameter must be byte[]");
563+
Assert.isInstanceOf(String.class, paramValue.getValue(),
564+
"Value of clob parameter must be String");
570565
}
571-
byte[] valueBytes = (byte[]) paramValue.getValue();
572-
this.lobCreator.setBlobAsBytes(ps, parameterPosition, valueBytes);
566+
String valueString = (String) paramValue.getValue();
567+
this.lobCreator.setClobAsString(ps, parameterPosition, valueString);
573568
return;
574569
}
575570
}

oauth2-authorization-server/src/main/resources/org/springframework/security/oauth2/server/authorization/oauth2-authorization-schema.sql

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,23 +3,23 @@ CREATE TABLE oauth2_authorization (
33
registered_client_id varchar(100) NOT NULL,
44
principal_name varchar(200) NOT NULL,
55
authorization_grant_type varchar(100) NOT NULL,
6-
attributes varchar(4000) DEFAULT NULL,
6+
attributes varchar(12000) DEFAULT NULL,
77
state varchar(500) DEFAULT NULL,
8-
authorization_code_value blob DEFAULT NULL,
8+
authorization_code_value varchar(1000) DEFAULT NULL,
99
authorization_code_issued_at timestamp DEFAULT NULL,
1010
authorization_code_expires_at timestamp DEFAULT NULL,
1111
authorization_code_metadata varchar(2000) DEFAULT NULL,
12-
access_token_value blob DEFAULT NULL,
12+
access_token_value varchar(1000) DEFAULT NULL,
1313
access_token_issued_at timestamp DEFAULT NULL,
1414
access_token_expires_at timestamp DEFAULT NULL,
1515
access_token_metadata varchar(2000) DEFAULT NULL,
1616
access_token_type varchar(100) DEFAULT NULL,
1717
access_token_scopes varchar(1000) DEFAULT NULL,
18-
oidc_id_token_value blob DEFAULT NULL,
18+
oidc_id_token_value varchar(1000) DEFAULT NULL,
1919
oidc_id_token_issued_at timestamp DEFAULT NULL,
2020
oidc_id_token_expires_at timestamp DEFAULT NULL,
2121
oidc_id_token_metadata varchar(2000) DEFAULT NULL,
22-
refresh_token_value blob DEFAULT NULL,
22+
refresh_token_value varchar(1000) DEFAULT NULL,
2323
refresh_token_issued_at timestamp DEFAULT NULL,
2424
refresh_token_expires_at timestamp DEFAULT NULL,
2525
refresh_token_metadata varchar(2000) DEFAULT NULL,

0 commit comments

Comments
 (0)