2017-11-13 16 views
0

Silex에서 symofny/security 패키지를 사용하여 간단한 로그인을 구축하려고하지만 인증 확인에 약간의 문제가 있습니다.사용자가 보안되지 않은 경로에서 인증되는지 확인하십시오.

구조 : 사용자가 필요로하는 /admin 경로에 도착하기 위해

/ 
/login 
/admin 
    /login_check 
    /logout 

가 인증을

그가 아니라면, 그가 권장하는대로 다음, 인증 admin/login_check을 요구하고있다 /login 형태로 리디렉션됩니다 (모두 symofny의 보안 방화벽이 제공합니다).

방화벽 구성 :

'security.firewalls' => array(
    'login' => array(
     'pattern' => '^/login$', 
    ), 
    'admin' => array(
     'pattern' => '^/admin', 
     'http' => true, 
     'form' => array(
      'login_path' => '/login', 
      'check_path' => '/admin/login' 
     ), 
     'logout' => array(
      'logout_path' => '/admin/logout', 
      'invalidate_session' => true 
     ), 
     'users' => ... 
    ), 
) 

모든 것이 잘 작동하지만 사용자는 해당 나쁘지 않다 그가 이미 인증에도-불구하고 /login 경로를 입력 할 수 있습니다,하지만 난 그것을하지 않도록하고 싶습니다. 나는 사용자 인증 상태를 확인하는데 지쳤으나 웹 사이트의 "보안 된"영역에없는 /login 컨트롤러에서 확인하면 작동하지 않는다고 생각합니다. (모든 워크 어라운드없이) The token storage contains no authentication token. One possible reason may be that there is no firewall configured for this URL. 그래서, 질문, 기본적으로 symfony/security를 사용하여이 작업을 수행 할 수있는 방법이있다 : 오류가 발생합니다

public function index(Request $request, Application $app) 
{ 
    if ($app['security.authorization_checker']->isGranted('ROLE_ADMIN')) { 
     return $app->redirect($app['url_generator']->generate('admin')); 
    } 
    return $app['twig']->render('login/index.twig', array(
     'error'   => $app['security.last_error']($request), 
     'last_username' => $app['session']->get('_security.last_username'), 
    )); 
} 

: 여기

코드인가? 또는 보안 영역에 /login 경로를 만들 수 있습니다 (예 : GET 요청에 예외가 있음). 사용자가 로그인하지 않아도 문제를 해결할 수 있지만 액세스 할 수 있습니다.

UPDATE

은 또한 아직, 나는이 /admin 노선에 로그인하고있을 때, 더 이상 오류를 던지고하지 결과 옵션 anonymous: true으로 /login 페이지의 방화벽 구성을 추가했지만 한 방법 isGranted('ROLE_ADMIN')의 결과는 true 인 반면, /login 경로의 결과는 false입니다 (아직 로그인되어 있습니다).

답변

1

현재 토큰을 덤프하여 보안 구성 요소의 동작을 쉽게 이해할 수 있습니다. 당신이 로그인 페이지 anonymous 옵션을 설정하지 않는 경우

public function index(Request $request, Application $app) 
{ 
    var_dump($application['security.token_storage']->getToken()); 
} 

(기본적으로는 false입니다) :

object(Symfony\Component\Security\Core\Authentication\Token\AnonymousToken) 
    private 'secret' => string 'login' (length=5) 
    private 'user' (Symfony\Component\Security\Core\Authentication\Token\AbstractToken) => string 'anon.' (length=5) 
    private 'roles' (Symfony\Component\Security\Core\Authentication\Token\AbstractToken) => 
     array (size=0) 
      empty 
    private 'authenticated' (Symfony\Component\Security\Core\Authentication\Token\AbstractToken) => boolean true 
    private 'attributes' (Symfony\Component\Security\Core\Authentication\Token\AbstractToken) => 
     array (size=0) 
      empty 
: 당신이 true에 로그인 페이지 anonymous 옵션을 설정

null 

다음 예제는 초기 코드 예제에서 오류가 발생하는 이유를 설명합니다.

보안 토큰을 공유하는 방법은 무엇입니까?

여러 방화벽간에 보안 토큰을 공유하려면 동일한 Firewall Context을 설정해야합니다.

SecurityServiceProvider 방화벽에 대한 컨텍스트 수신기는 security.context_listener.<name> 패턴으로 선언했습니다. 귀하의 예에서는 security.context_listener.admin으로 등록됩니다. 따라서 사용하려는 컨텍스트의 이름은 admin입니다.

또한 방화벽 컨텍스트 키가 세션에 저장되므로 방화벽을 사용하는 모든 방화벽은 stateless 옵션을 false으로 설정해야합니다. 당신은 관리자 패널 및 로그인 페이지에서 로그인 한 경우

은 무엇보다, 로그인 페이지에서 인증을 호출 할 anonymous 옵션을 사용하면 인스턴스를 얻을 것이다, 변경 후 true

'security.firewalls' => array(
    'login' => array(
     'context' => 'admin', 
     'stateless' => false, 
     'anonymous' => true, 
     'pattern' => '^/login$', 
    ), 
    'admin' => array(
     'context' => 'admin', 
     'stateless' => false, 
     'pattern' => '^/admin', 
     'http' => true, 
     'form' => array(
      'login_path' => '/login', 
      'check_path' => '/admin/login' 
     ), 
     'logout' => array(
      'logout_path' => '/admin/logout', 
      'invalidate_session' => true 
     ), 
     'users' => ... 
    ), 
) 

로 설정해야합니다 표시로 Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordTokenSymfony\Component\Security\Core\Authentication\Token\AnonymousToken 당신은 로그인하지 않은 경우. 그 때문에의

, 안전하게 $app['security.authorization_checker']->isGranted('ROLE_ADMIN')를 사용 권한을 확인하고 모두 방화벽에서 동일한 결과를 얻을 수 있습니다.

+0

끝내 주셔서 감사합니다. 마침내 누군가 설명 할 시간을 가졌다. 다시 한번 읽은 후 방화벽이있는 부분을 이해했지만 Silex symfony/security docs에서 컨텍스트에 대한 정보는 찾지 못했습니다. 나는 symfony의 것을 읽을 수 있었을 것입니다. 다시 한번 감사합니다. –

+0

이 문제에 관해서는 문서가 형편 없습니다. https://github.com/silexphp/Silex-Providers/blob/master/SecurityServiceProvider.php –

+0

질문에 답한 직후 silex 문서에 기고했지만 승인을 기다리는 중입니다. , 그래서 우리는 볼 것이다. –