0

Symfony2 プロジェクトにシンプルな認証済みエリアを実装しています。

それについて難しいことは何もありません.FOSUserBundleを使用できたとしても使用しませんが、とにかくこれは問題ではありません.私の質問は本当にセキュリティスキームとファイアウォールを指しています.

基本的なプロセス:

  • 十分な役割を持つ認証済みユーザー プロファイルを必要とするファイアウォールを定義する
  • ユーザーが認証できるログイン フォーム ページを作成する
  • エラーを管理し、ファイアウォール内の認証済みユーザーをリダイレクトします

SF2なら簡単にできます。

しかし、このプロジェクトでは少し違うものが必要です:

ファイアウォールは、認証されたプロファイルを必要としません。

認証されたプロファイルが見つかった場合にのみ追加情報が表示されますが、匿名でアクセスできる必要があります。

したがって、特定のページをログインフォームページと従来のファイアウォールページにする

詳細はこちら:

  • 公開情報を表示するホームページがあります
  • ログイン フォームはこのホームページの一部です。ちなみにグラフィックが必要な場合 (ドロップダウン)
  • ユーザーがフォームでログインした場合、定義されたファイアウォール ページにリダイレクトしたくありませんが、認証されたユーザーがこのホームページにとどまり、追加情報を表示できるようにします。

実際、ログイン フォーム ページ === ファイアウォールのホームページ === パブリック ホームページ ;

問題は、このページでは、ユーザーがフォームでログインした後でも認証済みとは見なされず、すべてのプライベート ^/メンバー ページにアクセスできることです。

# Security.yml
    firewalls:
        home:
            pattern: ^/$
            anonymous: ~

        members_area:
            pattern: ^/
            provider: <any_working_entity-based_provider>
            form_login:
                login_path: /
                check_path: /login_check
                post_only: true
                default_target_path: /
                use_referer: false
            logout:
                path: /logout
                target: /
                invalidate_session: false

    access_control:
        - { path: ^/, roles: IS_AUTHENTICATED_ANONYMOUSLY } # Public page, login page AND firewall page
        - { path: ^/members, roles: ROLE_USER } # Other firewall pages

# My/Super/Bundle/Resources/views/home.html.twig
    # [...]
    {% if app.user %}
        // This part is never displayed, even when the user is successfully authenticated
        <h3>Welcome home {{ app.user.username }}</h3>
    {% else %}
        // This part is always shown...
        <form action='{{ path('MySuperBundle_members_login_check') }}' method='post'>
            <div>
                <label for='_username'>Username</label>
                <input type='text' id='_username' name='_username' value='{{ last_username }}' />
            </div>
            <div>
                <label for='_password'>Password</label>
                <input type='text' id='_password' name='_password' value='{{ last_username }}' />
            </div>
            [... CSRF ...]
            <div>
                <input type='submit' name='submit' value='Submit' />
            </div>
        </form>
    {% endif %}

最後に:

  • ホームページ (/) は匿名で利用できます: OK
  • メンバーエリア (^/members) には、認証されたプロファイルが必要です: OK
  • ユーザーがすでにログインしている場合でも、ホームページには常にログインフォームが表示されます (小枝テスト {% if app.user %} は常にホームページでのみ false を返します)。
4

1 に答える 1

0

ようやく修正しました。ファイアウォールとアクセス制御リストを混同していました。

質問に示されているように、ホームページに 2 つのファイアウォールを作成しましたが、symfony2 では、2 つの異なるファイアウォールにログインすることはできません。

この場合、任意のファイアウォール ページ内にログイン フォームを配置したい場合は、ファイアウォールではなく、アクセス コントロール リストで管理します。

# Security.yml
firewalls:
    members_area:
        pattern: ^/
        provider: <any_working_entity-based_provider>
        anonymous: ~ # To allow unauthenticated users to access the firewall --> The login form
        form_login:
            login_path: /
            check_path: /login_check
            post_only: true
            default_target_path: /
            use_referer: false
        logout:
            path: /logout
            target: /
            invalidate_session: false

access_control:
    - { path: ^/, roles: IS_AUTHENTICATED_ANONYMOUSLY } # Public page, login page AND firewall page
    - { path: ^/members/suscribe, roles: IS_AUTHENTICATED_ANONYMOUSLY } # Suscribe is a public activity
    - { path: ^/members/retrieve_password, roles: IS_AUTHENTICATED_ANONYMOUSLY } # As well as forgotten password
    - { path: ^/members/reset_password, roles: IS_AUTHENTICATED_ANONYMOUSLY } # Or reset password features with the token protected page...
    - { path: ^/members, roles: ROLE_USER } # BUT, you set up the access control to require any role of the authenticated users, for the different firewall pages
于 2013-08-24T21:05:19.923 に答える