From 80ffba545ae67a2e537fc8e22290bb000a98d21eb089ee2d98d60be02acd7a42 Mon Sep 17 00:00:00 2001 From: AidarKC Date: Thu, 11 Dec 2025 16:22:12 +0300 Subject: [PATCH] =?UTF-8?q?11=2012=2025=20=D0=94=D0=BE=D0=B1=D0=B0=D0=B2?= =?UTF-8?q?=D0=B8=D0=BB=20=D0=BF=D0=BE=D0=BB=D0=B5=20authNonce(=D0=92?= =?UTF-8?q?=D0=BC=D0=B5=D1=81=D1=82=D0=BE=20SessionPWD)=20=D0=BF=D1=80?= =?UTF-8?q?=D0=B8=20=D0=B7=D0=B0=D0=BF=D1=80=D0=BE=D1=81=D0=B5=20=D0=B0?= =?UTF-8?q?=D0=B2=D1=82=D0=BE=D1=80=D0=B8=D0=B7=D0=B0=D1=86=D0=B8=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ws_protocol/JSON/ConnectionContext.java | 20 +++++++++-- .../Auth/Net_AuthChallenge_Request.java | 8 ++--- .../auth/Net_AuthChallenge_Handler.java | 4 +-- .../auth/Net_CreateAuthSession__Handler.java | 36 +++++++------------ 4 files changed, 37 insertions(+), 31 deletions(-) diff --git a/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/ConnectionContext.java b/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/ConnectionContext.java index d655969..d8cc255 100644 --- a/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/ConnectionContext.java +++ b/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/ConnectionContext.java @@ -27,11 +27,16 @@ public class ConnectionContext { private String sessionId; /** - * Временный секрет шага 1, который используется на шаге 2 и хранится в БД, - * а после успешной авторизации — настоящий секрет сессии. + * Секрет сессии (то, что хранится в active_sessions.session_pwd). */ private String sessionPwd; + /** + * Одноразовый nonce, выданный на шаге 1 (AuthChallenge), + * используется на шаге 2 для проверки подписи. + */ + private String authNonce; + /** * Текущий статус аутентификации. * См. константы AUTH_STATUS_* @@ -100,6 +105,16 @@ public class ConnectionContext { this.sessionPwd = sessionPwd; } + // --- authNonce --- + + public String getAuthNonce() { + return authNonce; + } + + public void setAuthNonce(String authNonce) { + this.authNonce = authNonce; + } + // --- auth status --- public int getAuthenticationStatus() { @@ -124,6 +139,7 @@ public class ConnectionContext { sessionId = null; sessionPwd = null; + authNonce = null; authenticationStatus = AUTH_STATUS_NONE; wsSession = null; diff --git a/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/entyties/Auth/Net_AuthChallenge_Request.java b/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/entyties/Auth/Net_AuthChallenge_Request.java index 26598b8..76845d2 100644 --- a/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/entyties/Auth/Net_AuthChallenge_Request.java +++ b/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/entyties/Auth/Net_AuthChallenge_Request.java @@ -3,9 +3,9 @@ package server.logic.ws_protocol.JSON.entyties.Auth; import server.logic.ws_protocol.JSON.entyties.Net_Request; /** - * Шаг 1 авторизации: запрос выдачи временного пароля сессии (sessionPwd). + * Шаг 1 авторизации: запрос выдачи одноразового nonce (authNonce). * - * Клиент по логину просит сервер сгенерировать случайный секрет sessionPwd, + * Клиент по логину просит сервер сгенерировать случайный authNonce, * который будет использован на втором шаге при подписи. * * Формат входящего JSON: @@ -23,7 +23,7 @@ import server.logic.ws_protocol.JSON.entyties.Net_Request; * "requestId": "...", * "status": 200, * "payload": { - * "sessionPwd": "base64-строка-от-32-байт" + * "authNonce": "base64-строка-от-32-байт" * } * } */ @@ -40,4 +40,4 @@ public class Net_AuthChallenge_Request extends Net_Request { public void setLogin(String login) { this.login = login; } -} +} \ No newline at end of file diff --git a/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/auth/Net_AuthChallenge_Handler.java b/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/auth/Net_AuthChallenge_Handler.java index 4486a0b..1312f69 100644 --- a/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/auth/Net_AuthChallenge_Handler.java +++ b/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/auth/Net_AuthChallenge_Handler.java @@ -71,8 +71,8 @@ public class Net_AuthChallenge_Handler implements JsonMessageHandler { RANDOM.nextBytes(buf); String authNonce = Base64.getUrlEncoder().withoutPadding().encodeToString(buf); - // Используем поле sessionPwd в контексте как хранилище challenge (authNonce) до шага 2 - ctx.setSessionPwd(authNonce); + // Сохраняем challenge в отдельном поле authNonce + ctx.setAuthNonce(authNonce); // 5) Формируем ответ Net_AuthChallenge_Response resp = new Net_AuthChallenge_Response(); diff --git a/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/auth/Net_CreateAuthSession__Handler.java b/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/auth/Net_CreateAuthSession__Handler.java index 08eecc4..916a099 100644 --- a/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/auth/Net_CreateAuthSession__Handler.java +++ b/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/auth/Net_CreateAuthSession__Handler.java @@ -35,7 +35,8 @@ import java.util.Base64; * "AUTHORIFICATED:" + timeMs + authNonce) * - clientInfo (опционально, до 50 символов) * - * authNonce клиент получил на шаге 1 (AuthChallenge). + * authNonce клиент получил на шаге 1 (AuthChallenge) и сервер + * сохранил его в ctx.authNonce. * * При успехе: * - создаётся запись ActiveSession в БД; @@ -59,27 +60,19 @@ public class Net_CreateAuthSession__Handler implements JsonMessageHandler { public Net_Response handle(Net_Request baseReq, ConnectionContext ctx) throws Exception { Net_CreateAuthSession_Request req = (Net_CreateAuthSession_Request) baseReq; - // --- базовые проверки контекста --- - if (ctx == null || ctx.getSolanaUser() == null || ctx.getSessionPwd() == null) { + // --- базовые проверки контекста шага 1 --- + if (ctx == null + || ctx.getSolanaUser() == null + || ctx.getAuthNonce() == null + || ctx.getAuthenticationStatus() != ConnectionContext.AUTH_STATUS_AUTH_IN_PROGRESS) { + Net_Response err = NetExceptionResponseFactory.error( req, WireCodes.Status.BAD_REQUEST, "NO_STEP1_CONTEXT", "Шаг 1 авторизации не был корректно выполнен для данного соединения" ); - WsConnectionUtils.closeConnection(ctx, 4001, "Auth failed: no step1 context"); - return err; - } - - // Ожидаем, что перед этим был AuthChallenge и статус = AUTH_IN_PROGRESS - if (ctx.getAuthenticationStatus() != ConnectionContext.AUTH_STATUS_AUTH_IN_PROGRESS) { - Net_Response err = NetExceptionResponseFactory.error( - req, - WireCodes.Status.BAD_REQUEST, - "BAD_AUTH_FLOW_STATE", - "Неожиданное состояние авторификации для данного соединения" - ); - WsConnectionUtils.closeConnection(ctx, 4001, "Auth failed: bad auth flow state"); + WsConnectionUtils.closeConnection(ctx, 4001, "Auth failed: no step1 context or bad auth state"); return err; } @@ -170,8 +163,8 @@ public class Net_CreateAuthSession__Handler implements JsonMessageHandler { return err; } - // --- authNonce (challenge) мы сохранили в ctx.sessionPwd на шаге 1 --- - String authNonce = ctx.getSessionPwd(); + // --- authNonce (challenge) мы сохранили в ctx.authNonce на шаге 1 --- + String authNonce = ctx.getAuthNonce(); // --- собираем строку для подписи: "AUTHORIFICATED:" + timeMs + authNonce --- String preimageStr = "AUTHORIFICATED:" + timeMs + authNonce; @@ -201,16 +194,12 @@ public class Net_CreateAuthSession__Handler implements JsonMessageHandler { String clientIp = null; if (wsSession != null) { - // стандартный метод получения IP clientIp = ClientInfoService.extractClientIp(wsSession); - // Дёргаем запрос геолокации (ничего не сохраняем в сессию), - // нужно лишь для того, чтобы данные попали в кэш сервера. if (clientIp != null && !clientIp.isBlank()) { try { GeoLookupService.resolveCountryCityOrIpWithCache(clientIp); } catch (Exception e) { - // геолокация не критична, можно тихо залогировать на debug log.debug("Geo lookup failed for ip={}", clientIp, e); } } @@ -257,7 +246,8 @@ public class Net_CreateAuthSession__Handler implements JsonMessageHandler { // --- обновляем контекст --- ctx.setActiveSession(activeSession); ctx.setSessionId(sessionId); - ctx.setSessionPwd(newSessionPwd); // теперь в контексте хранится секрет сессии, а не authNonce + ctx.setSessionPwd(newSessionPwd); // теперь в контексте хранится секрет сессии + ctx.setAuthNonce(null); // одноразовый nonce больше не нужен ctx.setAuthenticationStatus(ConnectionContext.AUTH_STATUS_USER); ActiveConnectionsRegistry.getInstance().register(ctx);