mirror of
https://github.com/lkddi/nexusphp.git
synced 2026-04-23 19:37:23 +08:00
Challenge-Response Authentication
This commit is contained in:
@@ -46,9 +46,11 @@ class NexusWebGuard implements StatefulGuard
|
||||
}
|
||||
$credentials = $this->request->cookie();
|
||||
if ($this->validate($credentials)) {
|
||||
$user = $this->user;
|
||||
$user = $this->provider->retrieveByCredentials($credentials);
|
||||
if ($this->provider->validateCredentials($user, $credentials)) {
|
||||
return $user;
|
||||
if ($user->checkIsNormal()) {
|
||||
return $this->user = $user;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -62,29 +64,13 @@ class NexusWebGuard implements StatefulGuard
|
||||
*/
|
||||
public function validate(array $credentials = [])
|
||||
{
|
||||
$required = ['c_secure_pass', 'c_secure_uid', 'c_secure_login'];
|
||||
$required = ['c_secure_pass'];
|
||||
foreach ($required as $value) {
|
||||
if (empty($credentials[$value])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
$b_id = base64($credentials["c_secure_uid"],false);
|
||||
$id = intval($b_id ?? 0);
|
||||
if (!$id || !is_valid_id($id) || strlen($credentials["c_secure_pass"]) != 32) {
|
||||
return false;
|
||||
}
|
||||
$user = $this->provider->retrieveById($id);
|
||||
if (!$user) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
$user->checkIsNormal();
|
||||
$this->user = $user;
|
||||
return true;
|
||||
} catch (\Throwable $e) {
|
||||
do_log($e->getMessage());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function logout()
|
||||
|
||||
@@ -61,10 +61,15 @@ class NexusWebUserProvider implements UserProvider
|
||||
*/
|
||||
public function retrieveByCredentials(array $credentials)
|
||||
{
|
||||
if (!empty($credentials['c_secure_uid'])) {
|
||||
$b_id = base64($credentials["c_secure_uid"],false);
|
||||
return $this->query->find($b_id);
|
||||
list($tokenJson, $signature) = explode('.', base64_decode($credentials["c_secure_pass"]));
|
||||
if (empty($tokenJson) || empty($signature)) {
|
||||
return null;
|
||||
}
|
||||
$tokenData = json_decode($tokenJson, true);
|
||||
if (!isset($tokenData['user_id'])) {
|
||||
return null;
|
||||
}
|
||||
return $this->retrieveById($tokenData['user_id']);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -76,20 +81,9 @@ class NexusWebUserProvider implements UserProvider
|
||||
*/
|
||||
public function validateCredentials(Authenticatable $user, array $credentials)
|
||||
{
|
||||
if ($credentials["c_secure_login"] == base64("yeah")) {
|
||||
/**
|
||||
* Not IP related
|
||||
* @since 1.8.0
|
||||
*/
|
||||
if ($credentials["c_secure_pass"] != md5($user->passhash)) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if ($credentials["c_secure_pass"] !== md5($user->passhash)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
list($tokenJson, $signature) = explode('.', base64_decode($credentials["c_secure_pass"]));
|
||||
$expectedSignature = hash_hmac('sha256', $tokenJson, $user->auth_key);
|
||||
return hash_equals($expectedSignature, $signature);
|
||||
}
|
||||
|
||||
public function rehashPasswordIfRequired(Authenticatable $user, #[\SensitiveParameter] array $credentials, bool $force = false)
|
||||
|
||||
@@ -49,9 +49,8 @@ class Test extends Command
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$r = config('nexus.ammds_secret');
|
||||
// $r = SearchBox::query()->find(4)->ss()->orWhere("mode", 0)->get();
|
||||
dd($r);
|
||||
$result = getLogFile();
|
||||
dd($result);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ use Illuminate\Http\Resources\Json\JsonResource;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Cookie;
|
||||
use Illuminate\Validation\Rule;
|
||||
use Nexus\Database\NexusDB;
|
||||
|
||||
class AuthenticateController extends Controller
|
||||
{
|
||||
@@ -53,7 +54,7 @@ class AuthenticateController extends Controller
|
||||
{
|
||||
$deadline = Setting::get('security.login_secret_deadline');
|
||||
if ($deadline && $deadline > now()->toDateTimeString()) {
|
||||
$user = User::query()->where('passkey', $passkey)->first(['id', 'passhash']);
|
||||
$user = User::query()->where('passkey', $passkey)->first(['id', 'passhash', 'secret', 'auth_key']);
|
||||
if ($user) {
|
||||
$ip = getip();
|
||||
/**
|
||||
@@ -61,9 +62,10 @@ class AuthenticateController extends Controller
|
||||
* @since 1.8.0
|
||||
*/
|
||||
// $passhash = md5($user->passhash . $ip);
|
||||
$passhash = md5($user->passhash);
|
||||
do_log(sprintf('passhash: %s, ip: %s, md5: %s', $user->passhash, $ip, $passhash));
|
||||
logincookie($user->id, $passhash,false, get_setting('system.cookie_valid_days', 365) * 86400, true, true, true);
|
||||
// $passhash = md5($user->passhash);
|
||||
// do_log(sprintf('passhash: %s, ip: %s, md5: %s', $user->passhash, $ip, $passhash));
|
||||
// logincookie($user->id, $passhash,false, get_setting('system.cookie_valid_days', 365) * 86400, true, true, true);
|
||||
logincookie($user->id, $user->auth_key);
|
||||
$user->last_login = now();
|
||||
$user->save();
|
||||
$userRep = new UserRepository();
|
||||
@@ -126,6 +128,29 @@ class AuthenticateController extends Controller
|
||||
}
|
||||
}
|
||||
|
||||
public function challenge(Request $request)
|
||||
{
|
||||
try {
|
||||
$request->validate([
|
||||
'username' => 'required|string',
|
||||
]);
|
||||
$username = $request->username;
|
||||
$challenge = mksecret();
|
||||
NexusDB::cache_put(get_challenge_key($username), $challenge,300);
|
||||
$user = User::query()->where("username", $username)->first(['secret']);
|
||||
return $this->success([
|
||||
"challenge" => $challenge,
|
||||
'secret' => $user->secret ?? mksecret(),
|
||||
]);
|
||||
} catch (\Exception $exception) {
|
||||
$msg = $exception->getMessage();
|
||||
$params = $request->all();
|
||||
do_log(sprintf("challenge fail: %s, params: %s", $msg, nexus_json_encode($params)));
|
||||
return $this->fail($params, $msg);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -105,4 +105,9 @@ class Setting extends NexusModel
|
||||
return self::get("main.defaultlang");
|
||||
}
|
||||
|
||||
public static function getIsUseChallengeResponseAuthentication(): bool
|
||||
{
|
||||
return self::get("security.use_challenge_response_authentication") == "yes";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+1
-1
@@ -194,7 +194,7 @@ class User extends Authenticatable implements FilamentUser, HasName
|
||||
* @var array
|
||||
*/
|
||||
protected $hidden = [
|
||||
'secret', 'passhash', 'passkey'
|
||||
'secret', 'passhash', 'passkey', 'auth_key'
|
||||
];
|
||||
|
||||
/**
|
||||
|
||||
@@ -53,8 +53,9 @@ class AuthServiceProvider extends ServiceProvider
|
||||
*/
|
||||
public function boot()
|
||||
{
|
||||
//some plugin use this guard
|
||||
Auth::viaRequest('nexus-cookie', function (Request $request) {
|
||||
return $this->getUserByCookie($request->cookie());
|
||||
return get_user_from_cookie($request->cookie(), false);
|
||||
});
|
||||
|
||||
Auth::extend('nexus-web', function ($app, $name, array $config) {
|
||||
@@ -72,33 +73,4 @@ class AuthServiceProvider extends ServiceProvider
|
||||
|
||||
}
|
||||
|
||||
private function getUserByCookie($cookie)
|
||||
{
|
||||
if (empty($cookie["c_secure_pass"]) || empty($cookie["c_secure_uid"]) || empty($cookie["c_secure_login"])) {
|
||||
return null;
|
||||
}
|
||||
$b_id = base64($cookie["c_secure_uid"],false);
|
||||
$id = intval($b_id ?? 0);
|
||||
if (!$id || !is_valid_id($id) || strlen($cookie["c_secure_pass"]) != 32) {
|
||||
return null;
|
||||
}
|
||||
$user = User::query()->find($id);
|
||||
if (!$user) {
|
||||
return null;
|
||||
}
|
||||
if ($cookie["c_secure_login"] == base64("yeah")) {
|
||||
/**
|
||||
* Not IP related
|
||||
* @since 1.8.0
|
||||
*/
|
||||
if ($cookie["c_secure_pass"] != md5($user->passhash)) {
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
if ($cookie["c_secure_pass"] !== md5($user->passhash)) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return $user;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user