This is an automated email from the ASF dual-hosted git repository.
fpapon pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/shiro.git
The following commit(s) were added to refs/heads/master by this push:
new 2b4594e SHIRO-552 Use base64 encoding of salt in JdbcRealm with
SaltStyle.COLUMN
new 010e456 Merge pull request #138 from
steinarb/shiro-jdbcrealm-bas64-coded-salt
2b4594e is described below
commit 2b4594e8ab750065801a0df88f9e5c979bcbd303
Author: Steinar Bang <[email protected]>
AuthorDate: Thu May 30 01:18:05 2019 +0200
SHIRO-552 Use base64 encoding of salt in JdbcRealm with SaltStyle.COLUMN
---
.../org/apache/shiro/realm/jdbc/JdbcRealm.java | 20 ++++++++-
.../org/apache/shiro/realm/jdbc/JDBCRealmTest.java | 47 ++++++++++++++++++++--
2 files changed, 62 insertions(+), 5 deletions(-)
diff --git a/core/src/main/java/org/apache/shiro/realm/jdbc/JdbcRealm.java
b/core/src/main/java/org/apache/shiro/realm/jdbc/JdbcRealm.java
index 6ec7fd9..fb54cdf 100644
--- a/core/src/main/java/org/apache/shiro/realm/jdbc/JdbcRealm.java
+++ b/core/src/main/java/org/apache/shiro/realm/jdbc/JdbcRealm.java
@@ -28,6 +28,7 @@ import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationException;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
+import org.apache.shiro.codec.Base64;
import org.apache.shiro.config.ConfigurationException;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
@@ -114,6 +115,8 @@ public class JdbcRealm extends AuthorizingRealm {
protected SaltStyle saltStyle = SaltStyle.NO_SALT;
+ protected boolean saltIsBase64Encoded = true;
+
/*--------------------------------------------
| C O N S T R U C T O R S |
============================================*/
@@ -201,6 +204,17 @@ public class JdbcRealm extends AuthorizingRealm {
}
}
+ /**
+ * Makes it possible to switch off base64 encoding of password salt.
+ * The default value is true, ie. expect the salt from a string
+ * value in a database to be base64 encoded.
+ *
+ * @param saltIsBase64Encoded the saltIsBase64Encoded to set
+ */
+ public void setSaltIsBase64Encoded(boolean saltIsBase64Encoded) {
+ this.saltIsBase64Encoded = saltIsBase64Encoded;
+ }
+
/*--------------------------------------------
| M E T H O D S |
============================================*/
@@ -247,7 +261,11 @@ public class JdbcRealm extends AuthorizingRealm {
info = new SimpleAuthenticationInfo(username,
password.toCharArray(), getName());
if (salt != null) {
- info.setCredentialsSalt(ByteSource.Util.bytes(salt));
+ if (saltStyle == SaltStyle.COLUMN && saltIsBase64Encoded) {
+
info.setCredentialsSalt(ByteSource.Util.bytes(Base64.decode(salt)));
+ } else {
+ info.setCredentialsSalt(ByteSource.Util.bytes(salt));
+ }
}
} catch (SQLException e) {
diff --git a/core/src/test/java/org/apache/shiro/realm/jdbc/JDBCRealmTest.java
b/core/src/test/java/org/apache/shiro/realm/jdbc/JDBCRealmTest.java
index e3c34f9..49a8a4a 100644
--- a/core/src/test/java/org/apache/shiro/realm/jdbc/JDBCRealmTest.java
+++ b/core/src/test/java/org/apache/shiro/realm/jdbc/JDBCRealmTest.java
@@ -22,6 +22,8 @@ import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UsernamePasswordToken;
+import org.apache.shiro.codec.Base64;
+import org.apache.shiro.codec.CodecSupport;
import org.apache.shiro.config.Ini;
import org.apache.shiro.config.IniSecurityManagerFactory;
import org.apache.shiro.crypto.hash.Sha256Hash;
@@ -142,8 +144,9 @@ public class JDBCRealmTest {
public void testSaltColumnSuccess() throws Exception {
String testMethodName = name.getMethodName();
JdbcRealm realm = realmMap.get(testMethodName);
- createSaltColumnSchema(testMethodName);
+ createSaltColumnSchema(testMethodName, false);
realm.setSaltStyle(JdbcRealm.SaltStyle.COLUMN);
+ realm.setSaltIsBase64Encoded(false);
Subject.Builder builder = new Subject.Builder(securityManager);
Subject currentUser = builder.buildSubject();
@@ -153,11 +156,26 @@ public class JDBCRealmTest {
}
@Test
+ public void testBase64EncodedSaltColumnSuccess() throws Exception {
+ String testMethodName = name.getMethodName();
+ JdbcRealm realm = realmMap.get(testMethodName);
+ createSaltColumnSchema(testMethodName, true);
+ realm.setSaltStyle(JdbcRealm.SaltStyle.COLUMN);
+
+ Subject.Builder builder = new Subject.Builder(securityManager);
+ Subject currentUser = builder.buildSubject();
+ UsernamePasswordToken token = new UsernamePasswordToken(username,
plainTextPassword);
+ currentUser.login(token);
+ currentUser.logout();
+ }
+
+ @Test
public void testSaltColumnWrongPassword() throws Exception {
String testMethodName = name.getMethodName();
JdbcRealm realm = realmMap.get(testMethodName);
- createSaltColumnSchema(testMethodName);
+ createSaltColumnSchema(testMethodName, false);
realm.setSaltStyle(JdbcRealm.SaltStyle.COLUMN);
+ realm.setSaltIsBase64Encoded(false);
Subject.Builder builder = new Subject.Builder(securityManager);
Subject currentUser = builder.buildSubject();
@@ -168,6 +186,24 @@ public class JDBCRealmTest {
// Expected
}
}
+
+ @Test
+ public void testBase64SaltColumnWrongPassword() throws Exception {
+ String testMethodName = name.getMethodName();
+ JdbcRealm realm = realmMap.get(testMethodName);
+ createSaltColumnSchema(testMethodName, true);
+ realm.setSaltStyle(JdbcRealm.SaltStyle.COLUMN);
+ realm.setSaltIsBase64Encoded(false);
+
+ Subject.Builder builder = new Subject.Builder(securityManager);
+ Subject currentUser = builder.buildSubject();
+ UsernamePasswordToken token = new UsernamePasswordToken(username,
"passwrd");
+ try {
+ currentUser.login(token);
+ } catch (IncorrectCredentialsException ex) {
+ // Expected
+ }
+ }
@Test
public void testExternalSuccess() throws Exception {
@@ -322,8 +358,10 @@ public class JDBCRealmTest {
/**
* Creates a test database with a separate salt column in the users table.
Sets the
* DataSource of the realm associated with the test to a DataSource
connected to the database.
+ * @param The name of the test which is used as the key when saving the
created realm in the realmMap
+ * @param base64EncodeSalt if true, the salt will be base64 encoded before
it's stored in the database
*/
- protected void createSaltColumnSchema(String testName) {
+ protected void createSaltColumnSchema(String testName, boolean
base64EncodeSalt) {
JDBCDataSource ds = new JDBCDataSource();
ds.setDatabase("jdbc:hsqldb:mem:" + name);
ds.setUser("SA");
@@ -337,7 +375,8 @@ public class JDBCRealmTest {
"create table users (username varchar(20), password
varchar(100), password_salt varchar(20))");
Sha256Hash sha256Hash = new Sha256Hash(plainTextPassword, salt);
String password = sha256Hash.toHex();
- sql.executeUpdate("insert into users values ('" + username + "',
'" + password + "', '" + salt + "')");
+ String maybeBase64EncodedSalt = base64EncodeSalt ?
Base64.encodeToString(CodecSupport.toBytes(salt)) : salt;
+ sql.executeUpdate("insert into users values ('" + username + "',
'" + password + "', '" + maybeBase64EncodedSalt + "')");
} catch (SQLException ex) {
Assert.fail("Exception creating test database");
} finally {