gpt4 book ai didi

CakePHP 2.3.2 BasicAuthentication 不起作用

转载 作者:行者123 更新时间:2023-12-04 20:47:02 25 4
gpt4 key购买 nike

我试用了位于 http://book.cakephp.org/2.0/en/tutorials-and-examples/simple-acl-controlled-application/simple-acl-controlled-application.html 的“简单 Acl 控制的应用程序 1&2”教程。 .

完成此操作后,我尝试激活 BasicAuth 而不是 FormAuth。

我在我的 UsersController 中重新实现了 login() 函数,如下所示:

public function login() {
if ($this->Auth->login()) {
return $this->redirect($this->Auth->redirect());
} else {
$this->Session->setFlash('Not able to login');
}
}

并将我的 AppController 中的 $components 变量更改为以下内容:
public $components = array(
'Acl',
'Auth' => array(
'authorize' => array(
'Actions' => array('actionPath' => 'controllers')
),
'authenticate' => array('Basic')
),
'DebugKit.Toolbar',
'Session'
);

BasicAuth“弹出窗口”按预期显示,但是当我尝试登录时,它会在无限循环中重新出现。完成本教程后,除了包含 DebugKit 外,我没有进行任何更改。

我错过了什么?我希望有人可以帮助我,因为我想用 CakePHP 编码我的下一个项目!

更新

应用 Controller
public function beforeFilter() {
//Configure AuthComponent
$this->Auth->allow('display');
$this->Auth->loginAction = array('controller' => 'users', 'action' => 'login');
$this->Auth->logoutRedirect = array('controller' => 'users', 'action' => 'login');
$this->Auth->loginRedirect = array('controller' => 'posts', 'action' => 'add');
}

用户 Controller
public function beforeFilter() {
parent::beforeFilter();
}

我正在尝试访问例如 /users/使用教程中描述的 FormAuth 就像一个魅力,所以不会有权限问题。登录数据对于测试(管理员:管理员)非常简单,因此也应该没有问题。

更新 2

在我的 Apache 日志中,我得到以下信息,所以它说我没有被授权:

IP - - [16/Apr/2013:18:08:37 +0200] "GET /users/login HTTP/1.0" 401 5179 "-" "Mozilla/5.0 (Windows NT 6.2; Win64; x64; rv:23.0) Gecko/20130414 Firefox/23.0"



更新 3

出于某种原因,用户和密码似乎要么未发送,要么未保存在 PHP 中。如果我重写 /lif/Cake/Controller/Auth/BasicAuthenticate到以下,它的工作原理!
public function authenticate(CakeRequest $request, CakeResponse $response) {
$_SERVER['PHP_AUTH_USER'] = $_SERVER['PHP_AUTH_PW'] = "admin";
$result = $this->getUser($request);

if (empty($result)) {
$response->header($this->loginHeaders());
$response->statusCode(401);
$response->send();
return false;
}
return $result;
}

更新 4

不知道这是否有帮助,但服务器正在运行 Plesk 11,最新更新,没有特殊修改。

更新 5

好的,“thaJeztah”的答案很有用,但现在我遇到了更多可以分割的问题。
  • 将模式从 fcgid 更改为 apache 模块

    1.1。结果可以登录,但注销不起作用!重定向后, session 似乎被清除,但我仍然可以访问每个受限页面,直到我清除浏览器中的“事件登录”,因为它在 Firefox 中被调用。

  • var_dump($this->Session->read('Auth.User'));

    NULL


    当我访问/users/login 时,我会自动登录并重定向,而无需输入登录凭据。

    print "<pre>";
    print_r($this->Session->read('Auth.User'));
    print "</pre>";

    Array
    (
    [id] => 1
    [username] => admin
    [group_id] => 1
    [created] => 2013-04-12 12:54:26
    [modified] => 2013-04-16 14:27:24
    [is_active] => 1
    [Group] => Array
    (
    [id] => 1
    [name] => Admin
    [created] => 2013-04-12 12:46:42
    [modified] => 2013-04-12 12:46:42
    )

    )

  • 使用基于 .htaccess 的解决方案也可以,它甚至看起来好像这是唯一需要的更改(我删除了 list() 代码,因为我从未进入它并且它也可以正常工作)。

    2.1。与上述相同的问题,无法真正注销。

  • 更新 6

    可能是我最后一次或最后一次更新。 :-)
    现在,我正在尝试通过将用户登录为我创建的只能访问 /users/login 的访客用户来进行“假注销”。和 /pages/home : http://guest:guest@my.domain/users/login
    访问 /users/logout也可以工作,因为我在那里使用这段代码:
    public function logout() {
    $user = $this->User->find('first', array('conditions' => array('username' => 'guest')));
    $this->Auth->login($user['User']['id']);
    }

    我简直不相信,这将是一致的,因为我相信 session 数据将在一段时间内被删除,并且浏览器仍然获得事件的管理员登录并使用这些进行身份验证 - 我是对的吗?

    之后,我可以使用 http://admin:admin@my.domain/users/login 再次登录不同的用户。 .不完美,但至少适用于 Firefox。

    所以基本上最后一个问题:关于如何在访问 /users/login 时强制使用 BasicAuth 的任何建议?这样我就可以随时使用任何客户端轻松切换用户。

    更新 7

    我找到了一种方法来完全按照我接受的答案中的想法做到这一点。我希望我捕获了所有边缘情况,如果没有,请随时纠正我!

    (附注:当使用 ACL 和/或基本身份验证时,至少 AppController 中的 isAuthorized() 似乎被忽略了(它已被识别,但没有效果 - 当我在不更改 $components 的情况下删除该方法时,出现错误)导致对我来说,在不使用 isAuthorized() 的情况下实现这一点。)

    应用 Controller .php
    public function beforeFilter($redirectlogin = true) {
    //Configure AuthComponent
    $this->Auth->allow('display', '/users/login');
    $this->Auth->loginAction = array('controller' => 'users', 'action' => 'login');
    $this->Auth->logoutRedirect = array('controller' => 'pages', 'action' => 'home');
    $this->Auth->loginRedirect = array('controller' => 'pages', 'action' => 'home');
    $this->Auth->unauthorizedRedirect = array('controller' => 'HTTPCODE', 'action' => 'c403');

    if($redirectlogin && $this->Session->read('Auth.needs_reauthenticate')) {
    if(!($this->request->params['controller'] == $this->Auth->loginRedirect['controller'] && $this->request->params['pass'][0] == $this->Auth->loginRedirect['action'])) {
    $this->redirect('/users/login');
    }
    }
    }

    用户 Controller .php
    public function beforeFilter() {
    parent::beforeFilter(false);
    }

    public function login() {
    $this->autoRender = false;
    $this->Session->write('Auth.needs_reauthenticate', true);
    if(!$this->Session->check('Auth.count')) {
    $count = 1;
    } else {
    $count = $this->Session->read('Auth.count') + 1;
    }
    $this->Session->write('Auth.count', $count);

    if($this->Session->read('Auth.needs_reauthenticate')) {
    if((isset($_SERVER['HTTP_AUTHORIZATION']) && $this->Session->read('Auth.count') == 1) || (!isset($_SERVER['HTTP_AUTHORIZATION']) || empty($_SERVER['HTTP_AUTHORIZATION']) || !$this->Session->check('Auth.sent_header_step') || $this->Session->read('Auth.sent_header_step') < 1)) {
    unset($_SERVER['HTTP_AUTHORIZATION']);
    $this->Session->write('Auth.redirectTo', $this->Auth->redirect());

    $this->response->header(sprintf('WWW-Authenticate: Basic realm="%s"', env('SERVER_NAME')));
    $this->response->statusCode(401);
    $this->response->send();

    $this->Session->write('Auth.sent_header_step', 1);
    }

    if(isset($_SERVER['HTTP_AUTHORIZATION'])) {
    $this->Session->write('Auth.sent_header_step', 0);
    $base64string = base64_decode(substr($_SERVER['HTTP_AUTHORIZATION'], 6));
    if(!(strlen($base64string) > 1 && substr($base64string, -1, 1) != ":")) {
    $_SERVER['PHP_AUTH_USER'] = "";
    $_SERVER['PHP_AUTH_PW'] = "";
    }

    $data = true;
    }

    $this->Auth->logout();

    if(isset($data) && $this->Session->read('Auth.count') > 1) {
    if($this->Auth->login()) {
    $this->Session->write('Auth.needs_reauthenticate', false);
    if($this->Session->check('Auth.redirectTo')) {
    $redirectTo = $this->Session->read('Auth.redirectTo');
    $this->Session->delete('Auth.redirectTo');
    $this->Session->delete('Auth.count');

    return $this->redirect($redirectTo);
    } else {
    return $this->redirect($this->Auth->redirect());
    }
    } else {
    $this->response->statusCode(403);
    // my 403 message
    }
    } else {

    if(!isset($_SERVER['HTTP_AUTHORIZATION']) && $this->Session->read('Auth.count') > 1 && isset($_SERVER['PHP_AUTH_USER']) && isset($_SERVER['PHP_AUTH_PW']) && trim($_SERVER['PHP_AUTH_USER']) != "" && trim($_SERVER['PHP_AUTH_PW']) != "") {
    if($this->Auth->login()) {
    $this->Session->write('Auth.needs_reauthenticate', false);
    if($this->Session->check('Auth.redirectTo')) {
    $redirectTo = $this->Session->read('Auth.redirectTo');
    $this->Session->delete('Auth.redirectTo');
    $this->Session->delete('Auth.count');

    unset($_SERVER['HTTP_AUTHORIZATION']);
    unset($_SERVER['PHP_AUTH_USER']);
    unset($_SERVER['PHP_AUTH_PW']);
    return $this->redirect($redirectTo);
    } else {
    return $this->redirect($this->Auth->redirect());
    }
    } else {
    $this->response->statusCode(403);
    // my 403 message
    }
    }

    $this->response->statusCode(403);
    // my 403 message
    }
    }
    }

    提前致谢

    阿德里安

    最佳答案

    将 PHP 作为(快速)CGI 运行时使用基本身份验证

    您的网站可能配置为将 PHP 作为(快速)CGI 运行,在这种情况下 PHP_AUTH_USERPHP_AUTH_PWD $_SERVER 中不存在 key 多变的。 BasicAuthenticate AuthComponent 依赖于这些键。

    更改 Plesk 中的域/webhosting 设置以将 php 作为此网站/域的“apache 模块”运行,或者扩展 BasicAuthenticate 组件以通过其他方式获取这些变量。

    关于这个主题的更多信息可以在这个问题中找到:

    PHP_AUTH_USER not set?

    对于 Symfony 框架,似乎有人编写了一个解决方法,在这种情况下也可能有用;

    https://github.com/symfony/symfony/issues/1813

    更新:使用基本身份验证时注销

    使用 basic authentication 时注销是不可能的。基本身份验证是一种“无状态”身份验证机制,这基本上意味着浏览器会随每个请求发送用户凭据。换句话说;服务器不保持“状态”,浏览器 做。使用基本身份验证,您需要浏览器发送用户凭据,并且只要浏览器发送有效凭据,您就允许浏览器访问 protected 页面。

    注销的唯一方法是关闭浏览器,或告诉浏览器关闭事件 session /登录。

    在此处阅读更多信息:

    http://en.wikipedia.org/wiki/Basic_access_authentication

    http basic authentication "log out"

    笔记

    Base Authentication 不是一种安全的身份验证机制;用户名 和密码随每个请求发送到服务器。密码发送未加密 (仅 base64 编码以防止特殊字符出现问题)。

    虽然表单例份验证也发送未加密的密码,但它(更安全一点)因为它只会在登录时发送用户名/密码。后续请求只会发送 Session-id,它可以设置为过期并限制为特定的 IP 和/或浏览器类型。

    在所有情况下,通过 SSL 保护连接显然很重要。

    在登录页面强制重新认证

    这只是“大声思考”,未经测试且高度实验性:)

    试试这个;

  • 如果没有 session 处于事件状态,请按正常方式进行。在基本身份验证中,无法区分“已登录”用户和“新用户”——它是无状态的
  • 如果 session 处于事件状态,则用户显然正在进行事件 session 。不要破坏 session ,而是改变规则;
  • 如果发送的凭据与 session 中的用户名相同(或者,更好:$this->Auth->user('username');?,则使 session 无效(不破坏)并通过发送登录 header 强制用户重新验证;
  • 您可以从 BasicAuthenticate 行为中复制 header ;在此处查看来源 BasicAuthenticate::authenticate()
  • 关于“复制标题”;也许扩展 BasicAuthenticate 是一种更清洁的方法;处理自定义版本中的所有自定义代码。

  • 此外,检查 AppController::isAuthorized() 内的 session 是否仍然“有效”。 (见 Using ControllerAuthorize)

    像这样的东西(样机代码):

    登录页面/操作:
    if ("usercredentials sent by browser" === "current logged in user in session") {
    // Mark session as 'needs-to-reauthenticate'
    $this->Session->write('Auth.needs_reauthenticate', true);

    // Need to find a clean approach to get the BasicAuth loginHeaders()
    // *including* the right settings (realm)
    $this->response->header(/*BasicAuth::loginHeaders()*/);

    // Access denied status
    $this->response->statusCode(401);
    return $this->response->send();
    }

    AppController::isAuthorized()
    if ($this->Session->read('Auth.needs_reauthenticate')) {
    return false;
    } else {
    // Normal 'isAuthorized()' checks here
    }

    笔记:
    一旦浏览器在事件 session 期间访问了“登录”页面,用户要么必须使用不同的凭据登录,要么关闭浏览器以再次登录。

    如果在关闭并重新打开浏览器后 session cookie 仍然存在,这可能会出现问题。尝试强制 session cookie 成为“真正的” session cookie,并通过设置 Session.cookieTimeout 在浏览器关闭时将其删除至 0 (见 Session Configuration

    关于CakePHP 2.3.2 BasicAuthentication 不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16039263/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com