Как обойти экран входа в систему в приложении CakePHP (jSlate)?

У меня проблемы с интеграцией приложения CakePHP (jSlate) в индивидуальное веб-приложение, отличное от Cake. Все альтернативные сценарии аутентификации, которые я видел, просто изменяют поведение формы входа в систему, другими словами, форма входа по-прежнему отображается и запрашивает имя пользователя и пароль, но они аутентифицируются по альтернативному источнику, например LDAP.

На самом деле я хочу, чтобы экран входа в систему не отображался. Вместо этого я хочу очень простое поведение:

  1. Определите, вошел ли пользователь в стороннее приложение.
  2. Если да, автоматически авторизуйте их в приложении CakePHP (в данном случае jSlate).
  3. Если нет, перенаправьте на экран входа в стороннее приложение.

Есть ли руководство по аутентификации CakePHP в этом направлении? Или кто-то знает как это сделать? Я разобрался, как выполнить часть 3, но такое поведение бесполезно без частей 1 и 2 ...


person AntonChanning    schedule 06.07.2012    source источник
comment
Как это обнаружение будет работать? Возможен ли обмен данными? Любой токен или файл cookie, которые можно оценить?   -  person deceze♦    schedule 06.07.2012
comment
@deceze Да, это в куки. Я могу написать этот код, мне просто нужно знать, куда его поместить. Например, я создал собственный контроллер аутентификации. Но нужен ли мне настраиваемый пользовательский контроллер? Или кастомный контроллер безопасности? И какой метод переопределить?   -  person AntonChanning    schedule 06.07.2012


Ответы (1)


Вы можете поместить это в свой AppController::beforeFilter:

public function beforeFilter() {
    if (!$this->Auth->user()) {
        // if no user is currently logged in

        if ($this->Cookie->read(...)) {
        // or
        if ($_COOKIE[...]) {
        // or whatever else you want to detect

            $this->redirect('http://some.external/login/service');
        }
    }
}

Затем эта внешняя служба входа в систему предположительно перенаправит пользователя обратно в ваше приложение Cake в какой-то момент с каким-то токеном. Вам просто нужно определить общедоступное действие (авторизация не требуется), на которое оно может перенаправить обратно. В этом действии вы проверяете все токены, которые вам нужны, а затем можете «вручную» аутентифицировать пользователя:

$user = $this->User->find(/* find your Cake user by some id */);
if ($user) {
    $this->Auth->login($user['User']['id']);
}

Поздравляем, теперь пользователь вошел в систему, как если бы он использовал форму входа и имеет действующий сеанс Cake.

person deceze♦    schedule 06.07.2012
comment
Предположительно между if и редиректом есть «else»? Или я что-то недопонимаю? - person AntonChanning; 06.07.2012
comment
Я имею в виду, что вам нужно проверить все, что вам нужно проверить из внешней службы аутентификации, и если вы определите, что пользователь должен быть перенаправлен на внешнюю службу для входа в систему, вы перенаправите его. Иначе ты ничего не делаешь. - person deceze♦; 06.07.2012
comment
Хорошо, но что значит «определить общедоступное действие»? Я немного не понимаю, куда пойдет этот второй фрагмент кода ... - person AntonChanning; 06.07.2012
comment
Как должна работать эта сторонняя аутентификация? Я предполагаю что-то вроде OpenID или Oauth, где пользователь перенаправляется обратно на заранее определенный URL-адрес при успешной аутентификации. Когда пользователя перенаправляют обратно, он все еще не аутентифицирован в отношении Cake. Таким образом, Cake не должен отклонять его, потому что он еще не прошел аутентификацию, а это означает, что вам нужно иметь что-то, что доступно без входа в систему. В терминах Cake: $this->Auth->allow('some_action'). - person deceze♦; 06.07.2012
comment
Нет, это полная интеграция. CakeApp находится во вложенной папке приложения, отличного от Cake, на том же веб-сайте. Таким образом, я должен иметь возможность просто проверить наличие переменной сеанса и автоматического входа в систему или нет. Так могу ли я пропустить этот бит и сделать все в AppController :: beforeFilter? - person AntonChanning; 06.07.2012
comment
Ну да. В этом случае основная идея состоит в том, чтобы проверять по каждому запросу, вошел ли пользователь в систему или нет и есть ли возможность войти в систему, прежде чем продолжить выполнение запроса в обычном режиме. Вы делаете это в AppController::beforeFilter. - person deceze♦; 06.07.2012
comment
Хорошо спасибо. Я пропускаю экран входа в систему. Есть еще ошибки, но если я не могу их решить, думаю, это другой вопрос ... - person AntonChanning; 06.07.2012