5

http://book.cakephp.org/2.0/en/tutorials-and-examples/simple-acl-managed-application/simple-acl-managed-applicationにある「シンプルな ACL 制御アプリケーション 1&2」チュートリアルを試しました。 html .

これを行った後、FormAuth の代わりに BasicAuth を有効にしようとしました。

次のように、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 のコーディングを行いたいので、誰かが私を助けてくれることを願っています!

アップデート

AppController

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

ユーザーコントローラー

public function beforeFilter() {
    parent::beforeFilter();
}

たとえば、チュートリアルで説明されている FormAuth を使用して魅力的に機能するアクセスを試みている/users/ため、アクセス許可の問題は発生しません。Logindata はテスト用 (admin:admin) としては非常に単純なので、問題はないはずです。

更新 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」のその答えは役に立ちましたが、今は細分化できる問題が増えています。

  1. モードを fcgid から apache モジュールに変更しました

    1.1。ログインは機能しますが、ログアウトは機能しません。リダイレクト後、セッションはクリアされたように見えますが、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
        )

)
  1. .htaccess ベースのソリューションを使用しても同様に機能し、必要な変更はそれだけのようにさえ見えます (list() のコードを削除したのは、私がそれを使用したことがなく、同様に機能したためです)。

    2.1. 上記と同じ問題で、実際のログアウトはできません。

アップデート 6

おそらく最後の更新か、最後の更新の 1 つです。:-) 現在、作成したゲストユーザーとしてユーザーをログインさせることで、「偽のログアウト」を試みてい/users/loginます/pages/homehttp://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']);
}

セッションデータはしばらく削除され、ブラウザはまだアクティブな管理者ログインを取得し、これらを使用して認証するため、これが一貫しているとは信じていません-私は正しいですか?

その後、を使用して別のユーザーに再度ログインできますhttp://admin:admin@my.domain/users/login。完全ではありませんが、少なくとも Firefox では機能します。

基本的に最後の質問: アクセス時に BasicAuth を強制する方法について何か提案はあります/users/loginか? このようにして、任意のクライアントを使用していつでも簡単にユーザーを切り替えることができました。

更新 7

受け入れられた回答のアイデアを使用して、これを正確に行う方法を見つけました。これですべてのエッジケースをキャッチできれば幸いです。そうでない場合は、お気軽に修正してください!

(PS:ACLまたは基本認証を使用する場合、少なくともAppControllerのisAuthorized()は無視されるようです(認識されましたが、効果はありませんでした-$コンポーネントを変更せずにメソッドを削除すると、エラーが発生しました) isAuthorized()を使用せずにこれを実装する私に)

AppController.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');
        }
    }
 }

ユーザーコントローラー.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
            }
        }
    }

前もって感謝します

エイドリアン

4

1 に答える 1