mirror of
https://github.com/correl/mage.git
synced 2024-11-28 19:19:55 +00:00
Integrate Shiro.
This commit is contained in:
parent
d0ea7d9c37
commit
32b4675f13
5 changed files with 184 additions and 2 deletions
|
@ -143,7 +143,7 @@ public class ConnectDialog extends MageDialog {
|
||||||
lblUserName = new javax.swing.JLabel();
|
lblUserName = new javax.swing.JLabel();
|
||||||
txtUserName = new javax.swing.JTextField();
|
txtUserName = new javax.swing.JTextField();
|
||||||
lblPassword = new javax.swing.JLabel();
|
lblPassword = new javax.swing.JLabel();
|
||||||
txtPassword = new javax.swing.JTextField();
|
txtPassword = new javax.swing.JPasswordField();
|
||||||
lblFlag = new javax.swing.JLabel();
|
lblFlag = new javax.swing.JLabel();
|
||||||
cbFlag = new mage.client.util.gui.countryBox.CountryComboBox();
|
cbFlag = new mage.client.util.gui.countryBox.CountryComboBox();
|
||||||
chkAutoConnect = new javax.swing.JCheckBox();
|
chkAutoConnect = new javax.swing.JCheckBox();
|
||||||
|
@ -180,9 +180,21 @@ public class ConnectDialog extends MageDialog {
|
||||||
lblUserName.setLabelFor(txtUserName);
|
lblUserName.setLabelFor(txtUserName);
|
||||||
lblUserName.setText("User name:");
|
lblUserName.setText("User name:");
|
||||||
|
|
||||||
|
txtUserName.addActionListener(new java.awt.event.ActionListener() {
|
||||||
|
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||||
|
txtUserNameActionPerformed(evt);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
lblPassword.setLabelFor(txtPassword);
|
lblPassword.setLabelFor(txtPassword);
|
||||||
lblPassword.setText("Password:");
|
lblPassword.setText("Password:");
|
||||||
|
|
||||||
|
txtPassword.addActionListener(new java.awt.event.ActionListener() {
|
||||||
|
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||||
|
txtPasswordActionPerformed(evt);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
lblFlag.setLabelFor(txtUserName);
|
lblFlag.setLabelFor(txtUserName);
|
||||||
lblFlag.setText("User flag:");
|
lblFlag.setText("User flag:");
|
||||||
|
|
||||||
|
@ -564,6 +576,10 @@ public class ConnectDialog extends MageDialog {
|
||||||
// TODO add your handling code here:
|
// TODO add your handling code here:
|
||||||
}//GEN-LAST:event_txtUserNameActionPerformed
|
}//GEN-LAST:event_txtUserNameActionPerformed
|
||||||
|
|
||||||
|
private void txtPasswordActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_txtPasswordActionPerformed
|
||||||
|
// TODO add your handling code here:
|
||||||
|
}//GEN-LAST:event_txtPasswordActionPerformed
|
||||||
|
|
||||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||||
private javax.swing.JButton btnCancel;
|
private javax.swing.JButton btnCancel;
|
||||||
private javax.swing.JButton btnConnect;
|
private javax.swing.JButton btnConnect;
|
||||||
|
@ -578,7 +594,7 @@ public class ConnectDialog extends MageDialog {
|
||||||
private javax.swing.JLabel lblServer;
|
private javax.swing.JLabel lblServer;
|
||||||
private javax.swing.JLabel lblStatus;
|
private javax.swing.JLabel lblStatus;
|
||||||
private javax.swing.JLabel lblUserName;
|
private javax.swing.JLabel lblUserName;
|
||||||
private javax.swing.JTextField txtPassword;
|
private javax.swing.JPasswordField txtPassword;
|
||||||
private javax.swing.JTextField txtPort;
|
private javax.swing.JTextField txtPort;
|
||||||
private javax.swing.JTextField txtServer;
|
private javax.swing.JTextField txtServer;
|
||||||
private javax.swing.JTextField txtUserName;
|
private javax.swing.JTextField txtUserName;
|
||||||
|
|
|
@ -148,6 +148,12 @@
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
<scope>runtime</scope>
|
<scope>runtime</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.shiro</groupId>
|
||||||
|
<artifactId>shiro-core</artifactId>
|
||||||
|
<version>1.2.4</version>
|
||||||
|
<type>jar</type>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
|
52
Mage.Server/src/main/java/mage/server/AuthorizedUser.java
Normal file
52
Mage.Server/src/main/java/mage/server/AuthorizedUser.java
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
package mage.server;
|
||||||
|
|
||||||
|
import com.j256.ormlite.field.DatabaseField;
|
||||||
|
import com.j256.ormlite.table.DatabaseTable;
|
||||||
|
import org.apache.shiro.authc.AuthenticationInfo;
|
||||||
|
import org.apache.shiro.authc.AuthenticationToken;
|
||||||
|
import org.apache.shiro.authc.SimpleAuthenticationInfo;
|
||||||
|
import org.apache.shiro.authc.UsernamePasswordToken;
|
||||||
|
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
|
||||||
|
import org.apache.shiro.util.ByteSource;
|
||||||
|
import org.apache.shiro.codec.Base64;
|
||||||
|
import org.apache.shiro.crypto.hash.Hash;
|
||||||
|
|
||||||
|
@DatabaseTable(tableName = "authorized_user")
|
||||||
|
public class AuthorizedUser {
|
||||||
|
|
||||||
|
@DatabaseField(indexName = "name_index")
|
||||||
|
protected String name;
|
||||||
|
|
||||||
|
@DatabaseField
|
||||||
|
protected String password;
|
||||||
|
|
||||||
|
@DatabaseField
|
||||||
|
protected String salt;
|
||||||
|
|
||||||
|
@DatabaseField
|
||||||
|
protected String hashAlgorithm;
|
||||||
|
|
||||||
|
@DatabaseField
|
||||||
|
protected int hashIterations;
|
||||||
|
|
||||||
|
public AuthorizedUser() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public AuthorizedUser(String name, Hash hash) {
|
||||||
|
this.name = name;
|
||||||
|
this.password = hash.toBase64();
|
||||||
|
this.salt = hash.getSalt().toBase64();
|
||||||
|
this.hashAlgorithm = hash.getAlgorithmName();
|
||||||
|
this.hashIterations = hash.getIterations();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean doCredentialsMatch(String name, String password) {
|
||||||
|
HashedCredentialsMatcher matcher = new HashedCredentialsMatcher(this.hashAlgorithm);
|
||||||
|
matcher.setHashIterations(this.hashIterations);
|
||||||
|
AuthenticationToken token = new UsernamePasswordToken(name, password);
|
||||||
|
AuthenticationInfo info = new SimpleAuthenticationInfo(this.name,
|
||||||
|
ByteSource.Util.bytes(Base64.decode(this.password)),
|
||||||
|
ByteSource.Util.bytes(Base64.decode(this.salt)), "");
|
||||||
|
return matcher.doCredentialsMatch(token, info);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,97 @@
|
||||||
|
package mage.server;
|
||||||
|
|
||||||
|
import com.j256.ormlite.dao.Dao;
|
||||||
|
import com.j256.ormlite.dao.DaoManager;
|
||||||
|
import com.j256.ormlite.jdbc.JdbcConnectionSource;
|
||||||
|
import com.j256.ormlite.stmt.QueryBuilder;
|
||||||
|
import com.j256.ormlite.stmt.SelectArg;
|
||||||
|
import com.j256.ormlite.support.ConnectionSource;
|
||||||
|
import com.j256.ormlite.support.DatabaseConnection;
|
||||||
|
import com.j256.ormlite.table.TableUtils;
|
||||||
|
import java.io.File;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
|
import mage.cards.repository.RepositoryUtil;
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
import org.apache.shiro.crypto.RandomNumberGenerator;
|
||||||
|
import org.apache.shiro.crypto.SecureRandomNumberGenerator;
|
||||||
|
import org.apache.shiro.crypto.hash.Hash;
|
||||||
|
import org.apache.shiro.crypto.hash.Sha256Hash;
|
||||||
|
import org.apache.shiro.crypto.hash.SimpleHash;
|
||||||
|
|
||||||
|
public enum AuthorizedUserRepository {
|
||||||
|
|
||||||
|
instance;
|
||||||
|
|
||||||
|
private static final String JDBC_URL = "jdbc:h2:file:./db/authorized_user.h2;AUTO_SERVER=TRUE";
|
||||||
|
private static final String VERSION_ENTITY_NAME = "authorized_user";
|
||||||
|
// raise this if db structure was changed
|
||||||
|
private static final long DB_VERSION = 0;
|
||||||
|
private static final RandomNumberGenerator rng = new SecureRandomNumberGenerator();
|
||||||
|
|
||||||
|
private Dao<AuthorizedUser, Object> dao;
|
||||||
|
|
||||||
|
private AuthorizedUserRepository() {
|
||||||
|
File file = new File("db");
|
||||||
|
if (!file.exists()) {
|
||||||
|
file.mkdirs();
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
ConnectionSource connectionSource = new JdbcConnectionSource(JDBC_URL);
|
||||||
|
boolean obsolete = RepositoryUtil.isDatabaseObsolete(connectionSource, VERSION_ENTITY_NAME, DB_VERSION);
|
||||||
|
|
||||||
|
if (obsolete) {
|
||||||
|
TableUtils.dropTable(connectionSource, AuthorizedUser.class, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
TableUtils.createTableIfNotExists(connectionSource, AuthorizedUser.class);
|
||||||
|
dao = DaoManager.createDao(connectionSource, AuthorizedUser.class);
|
||||||
|
} catch (SQLException ex) {
|
||||||
|
Logger.getLogger(AuthorizedUserRepository.class).error("Error creating authorized_user repository - ", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void add(final String userName, final String password) {
|
||||||
|
try {
|
||||||
|
dao.callBatchTasks(new Callable<Object>() {
|
||||||
|
@Override
|
||||||
|
public Object call() throws Exception {
|
||||||
|
try {
|
||||||
|
Hash hash = new SimpleHash(Sha256Hash.ALGORITHM_NAME, password, rng.nextBytes(), 1024);
|
||||||
|
AuthorizedUser user = new AuthorizedUser(userName, hash);
|
||||||
|
dao.create(user);
|
||||||
|
} catch (SQLException ex) {
|
||||||
|
Logger.getLogger(AuthorizedUserRepository.class).error("Error adding a user to DB - ", ex);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (Exception ex) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public AuthorizedUser get(String userName) {
|
||||||
|
try {
|
||||||
|
QueryBuilder<AuthorizedUser, Object> qb = dao.queryBuilder();
|
||||||
|
qb.where().eq("name", new SelectArg(userName));
|
||||||
|
List<AuthorizedUser> results = dao.query(qb.prepare());
|
||||||
|
if (results.size() == 1) {
|
||||||
|
return results.get(0);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
} catch (SQLException ex) {
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void closeDB() {
|
||||||
|
try {
|
||||||
|
if (dao != null && dao.getConnectionSource() != null) {
|
||||||
|
DatabaseConnection conn = dao.getConnectionSource().getReadWriteConnection();
|
||||||
|
conn.executeStatement("shutdown compact", 0);
|
||||||
|
}
|
||||||
|
} catch (SQLException ex) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -102,6 +102,17 @@ public class Session {
|
||||||
if (m.find()) {
|
if (m.find()) {
|
||||||
return "User name '" + userName + "' includes not allowed characters: use a-z, A-Z and 0-9";
|
return "User name '" + userName + "' includes not allowed characters: use a-z, A-Z and 0-9";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AuthorizedUser authorizedUser = AuthorizedUserRepository.instance.get(userName);
|
||||||
|
if (authorizedUser == null) {
|
||||||
|
// Do this in an explicit sign-up flow.
|
||||||
|
AuthorizedUserRepository.instance.add(userName, password);
|
||||||
|
} else {
|
||||||
|
if (!authorizedUser.doCredentialsMatch(userName, password)) {
|
||||||
|
return "Wrong username or password";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: Do an authentication with userName and password.
|
// TODO: Do an authentication with userName and password.
|
||||||
User user = UserManager.getInstance().createUser(userName, host);
|
User user = UserManager.getInstance().createUser(userName, host);
|
||||||
boolean reconnect = false;
|
boolean reconnect = false;
|
||||||
|
|
Loading…
Reference in a new issue