Integrate Shiro.

This commit is contained in:
Me Car 2016-01-05 03:48:43 +09:00
parent d0ea7d9c37
commit 32b4675f13
5 changed files with 184 additions and 2 deletions

View 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);
}
}

View file

@ -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) {
}
}
}

View file

@ -102,6 +102,17 @@ public class Session {
if (m.find()) {
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.
User user = UserManager.getInstance().createUser(userName, host);
boolean reconnect = false;