[FEATURE] Возможность использования кастомных параметров в AuthProvider(OAuth, 2FA и пр)

This commit is contained in:
Gravit 2019-09-27 07:23:16 +07:00
parent de144d90e0
commit 1b5fb36b0a
No known key found for this signature in database
GPG key ID: 061981E1E85D3216
17 changed files with 112 additions and 43 deletions

View file

@ -1,11 +1,12 @@
package pro.gravit.launchserver.auth.provider;
import pro.gravit.launcher.request.auth.AuthRequest;
import pro.gravit.utils.helper.SecurityHelper;
public final class AcceptAuthProvider extends AuthProvider {
@Override
public AuthProviderResult auth(String login, String password, String ip) {
public AuthProviderResult auth(String login, AuthRequest.AuthPasswordInterface password, String ip) {
return new AuthProviderResult(login, SecurityHelper.randomStringToken(), srv); // Same as login
}

View file

@ -2,6 +2,7 @@
import java.io.IOException;
import pro.gravit.launcher.request.auth.AuthRequest;
import pro.gravit.launchserver.LaunchServer;
import pro.gravit.launchserver.auth.AuthException;
import pro.gravit.utils.ProviderMap;
@ -39,9 +40,9 @@ public static void registerProviders() {
* Throws an exception {@link AuthException} {@link pro.gravit.utils.HookException} if the verification script returned a meaningful error
* In other cases, throwing an exception indicates a serious error
*/
public abstract AuthProviderResult auth(String login, String password, String ip) throws Exception;
public abstract AuthProviderResult auth(String login, AuthRequest.AuthPasswordInterface password, String ip) throws Exception;
public void preAuth(String login, String password, String customText, String ip) {
public void preAuth(String login, AuthRequest.AuthPasswordInterface password, String customText, String ip) {
}
@Override

View file

@ -2,6 +2,8 @@
import java.io.IOException;
import pro.gravit.launcher.request.auth.AuthRequest;
import pro.gravit.launcher.request.auth.password.AuthPlainPassword;
import pro.gravit.launchserver.auth.AuthException;
import pro.gravit.launchserver.dao.User;
import pro.gravit.launchserver.manangers.hook.AuthHookManager;
@ -10,21 +12,22 @@
public class HibernateAuthProvider extends AuthProvider {
public boolean autoReg;
@Override
public AuthProviderResult auth(String login, String password, String ip) throws Exception {
public AuthProviderResult auth(String login, AuthRequest.AuthPasswordInterface password, String ip) throws Exception {
if(!(password instanceof AuthPlainPassword)) throw new AuthException("This password type not supported");
User user = srv.config.dao.userService.findUserByUsername(login);
if(user == null && autoReg)
{
AuthHookManager.RegContext context = new AuthHookManager.RegContext(login, password, ip, false);
AuthHookManager.RegContext context = new AuthHookManager.RegContext(login, ((AuthPlainPassword) password).password, ip, false);
if(srv.authHookManager.registraion.hook(context))
{
user = srv.config.dao.userService.registerNewUser(login, password);
user = srv.config.dao.userService.registerNewUser(login, ((AuthPlainPassword) password).password);
}
else
{
throw new AuthException("Registration canceled. Try again later");
}
}
if(user == null || !user.verifyPassword(password))
if(user == null || !user.verifyPassword(((AuthPlainPassword) password).password))
{
if(user ==null) throw new AuthException("Username incorrect");
else throw new AuthException("Username or password incorrect");

View file

@ -7,6 +7,9 @@
import com.google.gson.JsonElement;
import pro.gravit.launcher.ClientPermissions;
import pro.gravit.launcher.request.auth.AuthRequest;
import pro.gravit.launcher.request.auth.password.AuthPlainPassword;
import pro.gravit.launchserver.auth.AuthException;
import pro.gravit.utils.HTTPRequest;
import pro.gravit.utils.helper.SecurityHelper;
@ -42,8 +45,9 @@ public authRequest(String username, String password, String ip, String apiKey) {
}
@Override
public AuthProviderResult auth(String login, String password, String ip) throws IOException {
authRequest authRequest = new authRequest(login, password, ip, apiKey);
public AuthProviderResult auth(String login, AuthRequest.AuthPasswordInterface password, String ip) throws IOException {
if(!(password instanceof AuthPlainPassword)) throw new AuthException("This password type not supported");
authRequest authRequest = new authRequest(login, ((AuthPlainPassword) password).password, ip, apiKey);
JsonElement request = gson.toJsonTree(authRequest);
JsonElement content = HTTPRequest.jsonRequest(request, url);
if (!content.isJsonObject())

View file

@ -6,6 +6,8 @@
import java.sql.SQLException;
import pro.gravit.launcher.ClientPermissions;
import pro.gravit.launcher.request.auth.AuthRequest;
import pro.gravit.launcher.request.auth.password.AuthPlainPassword;
import pro.gravit.launchserver.LaunchServer;
import pro.gravit.launchserver.auth.AuthException;
import pro.gravit.launchserver.auth.MySQLSourceConfig;
@ -29,10 +31,11 @@ public void init(LaunchServer srv) {
}
@Override
public AuthProviderResult auth(String login, String password, String ip) throws SQLException, AuthException {
public AuthProviderResult auth(String login, AuthRequest.AuthPasswordInterface password, String ip) throws SQLException, AuthException {
if(!(password instanceof AuthPlainPassword)) throw new AuthException("This password type not supported");
try (Connection c = mySQLHolder.getConnection()) {
PreparedStatement s = c.prepareStatement(query);
String[] replaceParams = {"login", login, "password", password, "ip", ip};
String[] replaceParams = {"login", login, "password", ((AuthPlainPassword) password).password, "ip", ip};
for (int i = 0; i < queryParams.length; i++)
s.setString(i + 1, CommonHelper.replace(queryParams[i], replaceParams));

View file

@ -3,13 +3,16 @@
import java.io.IOException;
import java.util.Objects;
import pro.gravit.launcher.request.auth.AuthRequest;
import pro.gravit.launcher.request.auth.password.AuthPlainPassword;
import pro.gravit.launchserver.auth.AuthException;
import pro.gravit.utils.helper.VerifyHelper;
public final class NullAuthProvider extends AuthProvider {
private volatile AuthProvider provider;
@Override
public AuthProviderResult auth(String login, String password, String ip) throws Exception {
public AuthProviderResult auth(String login, AuthRequest.AuthPasswordInterface password, String ip) throws Exception {
return getProvider().auth(login, password, ip);
}

View file

@ -7,6 +7,8 @@
import java.sql.SQLException;
import pro.gravit.launcher.ClientPermissions;
import pro.gravit.launcher.request.auth.AuthRequest;
import pro.gravit.launcher.request.auth.password.AuthPlainPassword;
import pro.gravit.launchserver.auth.AuthException;
import pro.gravit.launchserver.auth.PostgreSQLSourceConfig;
import pro.gravit.utils.helper.CommonHelper;
@ -20,9 +22,10 @@ public final class PostgreSQLAuthProvider extends AuthProvider {
private boolean usePermission;
@Override
public AuthProviderResult auth(String login, String password, String ip) throws SQLException, AuthException {
public AuthProviderResult auth(String login, AuthRequest.AuthPasswordInterface password, String ip) throws SQLException, AuthException {
if(!(password instanceof AuthPlainPassword)) throw new AuthException("This password type not supported");
try (Connection c = postgreSQLHolder.getConnection(); PreparedStatement s = c.prepareStatement(query)) {
String[] replaceParams = {"login", login, "password", password, "ip", ip};
String[] replaceParams = {"login", login, "password", ((AuthPlainPassword) password).password, "ip", ip};
for (int i = 0; i < queryParams.length; i++) {
s.setString(i + 1, CommonHelper.replace(queryParams[i], replaceParams));
}

View file

@ -4,6 +4,7 @@
import java.util.HashMap;
import java.util.Map;
import pro.gravit.launcher.request.auth.AuthRequest;
import pro.gravit.launchserver.Reconfigurable;
import pro.gravit.launchserver.auth.AuthException;
import pro.gravit.utils.command.Command;
@ -23,7 +24,7 @@ public RejectAuthProvider(String message) {
private ArrayList<String> whitelist;
@Override
public AuthProviderResult auth(String login, String password, String ip) throws AuthException {
public AuthProviderResult auth(String login, AuthRequest.AuthPasswordInterface password, String ip) throws AuthException {
if (whitelist != null) {
for (String username : whitelist) {
if (login.equals(username)) {

View file

@ -6,7 +6,10 @@
import java.util.regex.Pattern;
import pro.gravit.launcher.ClientPermissions;
import pro.gravit.launcher.request.auth.AuthRequest;
import pro.gravit.launcher.request.auth.password.AuthPlainPassword;
import pro.gravit.launchserver.LaunchServer;
import pro.gravit.launchserver.auth.AuthException;
import pro.gravit.utils.helper.CommonHelper;
import pro.gravit.utils.helper.IOHelper;
import pro.gravit.utils.helper.LogHelper;
@ -27,8 +30,9 @@ public void init(LaunchServer srv) {
}
@Override
public AuthProviderResult auth(String login, String password, String ip) throws IOException {
String currentResponse = IOHelper.request(new URL(getFormattedURL(login, password, ip)));
public AuthProviderResult auth(String login, AuthRequest.AuthPasswordInterface password, String ip) throws IOException {
if(!(password instanceof AuthPlainPassword)) throw new AuthException("This password type not supported");
String currentResponse = IOHelper.request(new URL(getFormattedURL(login, ((AuthPlainPassword) password).password, ip)));
// Match username
Matcher matcher = pattern.matcher(currentResponse);

View file

@ -2,6 +2,7 @@
import java.util.UUID;
import pro.gravit.launcher.request.auth.password.AuthPlainPassword;
import pro.gravit.launchserver.LaunchServer;
import pro.gravit.launchserver.auth.AuthProviderPair;
import pro.gravit.launchserver.auth.provider.AuthProvider;
@ -37,7 +38,7 @@ public void invoke(String... args) throws Exception {
// Authenticate
AuthProvider provider = pair.provider;
AuthProviderResult result = provider.auth(login, password, "127.0.0.1");
AuthProviderResult result = provider.auth(login, new AuthPlainPassword(password), "127.0.0.1");
UUID uuid = pair.handler.auth(result);
// Print auth successful message

View file

@ -13,6 +13,9 @@
import pro.gravit.launcher.hwid.HWID;
import pro.gravit.launcher.hwid.OshiHWID;
import pro.gravit.launcher.profiles.ClientProfile;
import pro.gravit.launcher.request.auth.AuthRequest;
import pro.gravit.launcher.request.auth.password.AuthPlainPassword;
import pro.gravit.launcher.request.auth.password.AuthRSAPassword;
import pro.gravit.launchserver.auth.AuthException;
import pro.gravit.launchserver.auth.AuthProviderPair;
import pro.gravit.launchserver.auth.hwid.HWIDException;
@ -34,15 +37,7 @@ public class AuthResponse extends SimpleResponse {
public String customText;
public boolean getSession;
public String password;
public byte[] encryptedPassword;
public AuthResponse(String login, String password, String auth_id, OshiHWID hwid) {
this.login = login;
this.password = password;
this.auth_id = auth_id;
this.hwid = hwid;
}
public AuthRequest.AuthPasswordInterface password;
public String auth_id;
public ConnectTypes authType;
@ -65,10 +60,11 @@ public void execute(ChannelHandlerContext ctx, Client clientData) throws Excepti
AuthProvider.authError("Don't skip Launcher Update");
return;
}
if (password == null) {
if(password instanceof AuthRSAPassword)
{
try {
password = IOHelper.decode(SecurityHelper.newRSADecryptCipher(server.privateKey).
doFinal(encryptedPassword));
password = new AuthPlainPassword(IOHelper.decode(SecurityHelper.newRSADecryptCipher(server.privateKey).
doFinal(((AuthRSAPassword) password).password)));
} catch (IllegalBlockSizeException | BadPaddingException ignored) {
throw new AuthException("Password decryption error");
}
@ -76,7 +72,7 @@ public void execute(ChannelHandlerContext ctx, Client clientData) throws Excepti
AuthProviderPair pair;
if (auth_id.isEmpty()) pair = server.config.getAuthProviderPair();
else pair = server.config.getAuthProviderPair(auth_id);
AuthContext context = new AuthContext(0, login, password.length(), customText, client, null, ip, authType);
AuthContext context = new AuthContext(0, login, customText, client, null, ip, authType);
AuthProvider provider = pair.provider;
server.authHookManager.preHook.hook(context, clientData);
provider.preAuth(login, password, customText, ip);
@ -135,10 +131,9 @@ public void execute(ChannelHandlerContext ctx, Client clientData) throws Excepti
}
public static class AuthContext {
public AuthContext(long session, String login, int password_length, String customText, String client, String hwid, String ip, ConnectTypes authType) {
public AuthContext(long session, String login, String customText, String client, String hwid, String ip, ConnectTypes authType) {
this.session = session;
this.login = login;
this.password_length = password_length;
this.customText = customText;
this.client = client;
this.hwid = hwid;
@ -148,6 +143,7 @@ public AuthContext(long session, String login, int password_length, String custo
public long session;
public String login;
@Deprecated
public int password_length; //Use AuthProvider for get password
public String client;
public String hwid;

View file

@ -5,14 +5,22 @@
import pro.gravit.launcher.events.request.AuthRequestEvent;
import pro.gravit.launcher.hwid.HWID;
import pro.gravit.launcher.request.Request;
import pro.gravit.launcher.request.auth.password.AuthPlainPassword;
import pro.gravit.launcher.request.auth.password.AuthRSAPassword;
import pro.gravit.launcher.request.websockets.WebSocketRequest;
import pro.gravit.utils.ProviderMap;
import pro.gravit.utils.helper.VerifyHelper;
public final class AuthRequest extends Request<AuthRequestEvent> implements WebSocketRequest {
public static ProviderMap<AuthPasswordInterface> providers = new ProviderMap<>();
public interface AuthPasswordInterface
{
boolean check();
}
@LauncherNetworkAPI
private final String login;
@LauncherNetworkAPI
private final byte[] encryptedPassword;
private final AuthPasswordInterface password;
@LauncherNetworkAPI
private final String auth_id;
@LauncherNetworkAPI
@ -25,8 +33,6 @@ public final class AuthRequest extends Request<AuthRequestEvent> implements WebS
private final ConnectTypes authType;
@LauncherNetworkAPI
public boolean initProxy;
@LauncherNetworkAPI
public String password;
public enum ConnectTypes {
@LauncherNetworkAPI
@ -42,7 +48,7 @@ public enum ConnectTypes {
@LauncherAPI
public AuthRequest(String login, byte[] password, HWID hwid) {
this.login = VerifyHelper.verify(login, VerifyHelper.NOT_EMPTY, "Login can't be empty");
this.encryptedPassword = password.clone();
this.password = new AuthRSAPassword(password.clone());
this.hwid = hwid;
customText = "";
auth_id = "";
@ -53,7 +59,7 @@ public AuthRequest(String login, byte[] password, HWID hwid) {
@LauncherAPI
public AuthRequest(String login, byte[] password, HWID hwid, String auth_id) {
this.login = VerifyHelper.verify(login, VerifyHelper.NOT_EMPTY, "Login can't be empty");
this.encryptedPassword = password.clone();
this.password = new AuthRSAPassword(password.clone());
this.hwid = hwid;
this.auth_id = auth_id;
customText = "";
@ -64,7 +70,7 @@ public AuthRequest(String login, byte[] password, HWID hwid, String auth_id) {
@LauncherAPI
public AuthRequest(String login, byte[] password, HWID hwid, String customText, String auth_id) {
this.login = VerifyHelper.verify(login, VerifyHelper.NOT_EMPTY, "Login can't be empty");
this.encryptedPassword = password.clone();
this.password = new AuthRSAPassword(password.clone());
this.hwid = hwid;
this.auth_id = auth_id;
this.customText = customText;
@ -74,7 +80,7 @@ public AuthRequest(String login, byte[] password, HWID hwid, String customText,
public AuthRequest(String login, byte[] encryptedPassword, String auth_id, ConnectTypes authType) {
this.login = login;
this.encryptedPassword = encryptedPassword;
this.password = new AuthRSAPassword(encryptedPassword.clone());
this.auth_id = auth_id;
this.authType = authType;
this.hwid = null;
@ -84,8 +90,7 @@ public AuthRequest(String login, byte[] encryptedPassword, String auth_id, Conne
public AuthRequest(String login, String password, String auth_id, ConnectTypes authType) {
this.login = login;
this.password = password;
this.encryptedPassword = null;
this.password = new AuthPlainPassword(password);
this.auth_id = auth_id;
this.authType = authType;
this.hwid = null;
@ -97,4 +102,12 @@ public AuthRequest(String login, String password, String auth_id, ConnectTypes a
public String getType() {
return "auth";
}
private static boolean registerProviders = false;
public static void registerProviders() {
if(!registerProviders) {
providers.register("plain", AuthPlainPassword.class);
providers.register("rsa", AuthRSAPassword.class);
registerProviders = true;
}
}
}

View file

@ -0,0 +1,16 @@
package pro.gravit.launcher.request.auth.password;
import pro.gravit.launcher.request.auth.AuthRequest;
public class AuthPlainPassword implements AuthRequest.AuthPasswordInterface {
public final String password;
public AuthPlainPassword(String password) {
this.password = password;
}
@Override
public boolean check() {
return true;
}
}

View file

@ -0,0 +1,16 @@
package pro.gravit.launcher.request.auth.password;
import pro.gravit.launcher.request.auth.AuthRequest;
public class AuthRSAPassword implements AuthRequest.AuthPasswordInterface {
public final byte[] password;
public AuthRSAPassword(byte[] password) {
this.password = password;
}
@Override
public boolean check() {
return true;
}
}

View file

@ -16,6 +16,7 @@
import pro.gravit.launcher.hasher.HashedEntry;
import pro.gravit.launcher.hasher.HashedEntryAdapter;
import pro.gravit.launcher.request.WebSocketEvent;
import pro.gravit.launcher.request.auth.AuthRequest;
import pro.gravit.utils.ProviderMap;
import pro.gravit.utils.UniversalJsonAdapter;
import pro.gravit.utils.helper.LogHelper;
@ -41,6 +42,7 @@ public static void appendTypeAdapters(GsonBuilder builder)
builder.registerTypeAdapter(HashedEntry.class, new HashedEntryAdapter());
builder.registerTypeAdapter(WebSocketEvent.class, new UniversalJsonAdapter<>(ClientWebSocketService.results));
builder.registerTypeAdapter(WebSocketRequest.class, new UniversalJsonAdapter<>(ClientWebSocketService.requests));
builder.registerTypeAdapter(AuthRequest.AuthPasswordInterface.class, new UniversalJsonAdapter<>(AuthRequest.providers));
}
private static URI createURL(String address) {

View file

@ -12,6 +12,7 @@
import pro.gravit.launcher.request.Request;
import pro.gravit.launcher.request.RequestException;
import pro.gravit.launcher.request.WebSocketEvent;
import pro.gravit.launcher.request.auth.AuthRequest;
import pro.gravit.utils.helper.JVMHelper;
import pro.gravit.utils.helper.LogHelper;
@ -20,6 +21,7 @@ public class StandartClientWebSocketService extends ClientWebSocketService {
public StandartClientWebSocketService(String address) throws SSLException {
super(address);
AuthRequest.registerProviders();
}
public class RequestFuture implements Future<WebSocketEvent> {

@ -1 +1 @@
Subproject commit 8d7a95d0707539ab18fba83bef6ef9f09b70c0ad
Subproject commit 3e485e5ae681cd1c136fc25a49d5dd339bc4d30a