Form Authentication doesn’t work with firewall’s pattern property.

huangapple go评论53阅读模式
英文:

Form Authentication doesn't work with firewall's pattern property

问题

I am using symfony 6, and facing some issues while having 2 authentication firewalls.

我正在使用Symfony 6,但在使用两个身份验证防火墙时遇到了一些问题。

I need one to authenticate customer users, and another one for Dashboard users. To do so I setup 2 firewalls with different pattern. But it doesn't seem to work, as when I try to reach a secured page with the 'back_office' firewall, the profiler doesn't designate the right one, and submitting the authentication just reloads the form login.

我需要一个用于验证客户用户,另一个用于仪表板用户。为此,我设置了两个具有不同模式的防火墙。但似乎不起作用,因为当我尝试使用'back_office'防火墙访问受保护的页面时,分析器没有正确指定,提交身份验证只会重新加载表单登录。

Here is my security.yaml file :

这是我的security.yaml文件:

security:
    # https://symfony.com/doc/current/security.html#registering-the-user-hashing-passwords
    password_hashers:
        Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface: 'auto'
    # https://symfony.com/doc/current/security.html#loading-the-user-the-user-provider
    providers:
        users_in_memory: { memory: null }
        app_user_provider: 
            entity:
                class: App\Entity\Client
                property: email
        bo_user_provider:
            entity:
                class: App\Entity\BoUser
                property: email
    firewalls:
        dev:
            pattern: ^/(_(profiler|wdt)|css|images|js)/
            security: false
        back_office:
            pattern: ^/Dashboard
            lazy: true
            context: my_context
            provider: bo_user_provider
            form_login:
                login_path: bo_login
                check_path: bo_login
                enable_csrf: true
            logout:
                path: app_logout
        customer:
            lazy: true
            context: my_context
            pattern: ^/
            provider: app_user_provider
            form_login:
                login_path: app_login
                check_path: app_login
                enable_csrf: true
            logout:
                path: app_logout

When I request a secured route, I am redirected to the correct form login, but in the profiler I see that the firewall name is 'customer' :
Symfony profiler - wrong firewall

当我请求一个受保护的路由时,我被重定向到正确的表单登录页面,但在分析器中,我看到防火墙名称是'customer':
Symfony profiler - wrong firewall

After submitting the login form, the page reloads and I am not authenticated. No authentication errors are shown.

在提交登录表单后,页面重新加载,但我没有通过身份验证。没有显示身份验证错误。

If I disable the customer firewall, I am still redirected to the correct form login, but no firewall is designated in the profiler :
Symfony profiler - no firewall

如果禁用客户防火墙,我仍然被重定向到正确的表单登录页面,但在分析器中没有指定防火墙:
Symfony profiler - no firewall

If I comment the pattern property on the back_office firewall, then I am redirected to the correct form login, the profiler designates the right firewall, and I am able to authenticate correctly:
Symfony profiler - right firewall

如果我在back_office防火墙上注释模式属性,然后我将被重定向到正确的表单登录页面,分析器指定了正确的防火墙,我能够正确进行身份验证:
Symfony profiler - right firewall

What am I doing wrong ?

我做错了什么?

Thanks in advance for your help !

提前感谢您的帮助!

Have a nice day

祝您有一个愉快的一天

//UPDATE
Here is the updated yaml file, as requested by ramsey_lewis

firewalls:
    dev:
        pattern: ^/(_(profiler|wdt)|css|images|js)/
        security: false
    back_office:
        pattern: ^/Dashboard
        lazy: true
        provider: bo_user_provider
        form_login:
            login_path: bo_login
            check_path: bo_login
            enable_csrf: true
        logout:
            path: app_logout
    customer:
        # pattern: ^/Dashboard
        lazy: true
        provider: app_user_provider
        form_login:
            login_path: app_login
            check_path: app_login
            enable_csrf: true
        logout:
            path: app_logout
英文:

I am using symfony 6, and facing some issues while having 2 authentication firewalls.

I need one to authenticate customer users, and another one for Dashboard users. To do so I setup 2 firewalls with different pattern. But it doesn't seem to work, as when I try to reach a secured page with the 'back_office' firewall, the profiler doesn't designate the right one, and submitting the authentication just reloads the form login.

Here is my security.yaml file :

security:
# https://symfony.com/doc/current/security.html#registering-the-user-hashing-passwords
password_hashers:
    Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface: 'auto'
# https://symfony.com/doc/current/security.html#loading-the-user-the-user-provider
providers:
    users_in_memory: { memory: null }
    app_user_provider: 
        entity:
            class: App\Entity\Client
            property: email
    bo_user_provider:
        entity:
            class: App\Entity\BoUser
            property: email
firewalls:
    dev:
        pattern: ^/(_(profiler|wdt)|css|images|js)/
        security: false
    back_office:
        pattern: ^/Dashboard
        lazy: true
        context: my_context
        provider: bo_user_provider
        form_login:
            login_path: bo_login
            check_path: bo_login
            enable_csrf: true
        logout:
            path: app_logout
    customer:
        lazy: true
        context: my_context
        pattern: ^/
        provider: app_user_provider
        form_login:
            login_path: app_login
            check_path: app_login
            enable_csrf: true
        logout:
            path: app_logout

When I request a secured route, I am redirected to the correct form login, but in the profiler I see that the firewall name is 'customer' :
Symfony profiler - wrong firewall

After submitting the login form, the page reloads and I am not authenticated. No authentication errors are shown.

If I disable the customer firewall, I am still redirected to the correct form login, but no firewall is designated in the profiler :
Symfony profiler - no firewall

If I comment the pattern property on the back_office firewall, then I am redirected to the correct form login, the profiler designates the right firewall, and I am able to authenticate correctly:
Symfony profiler - right firewall

What am I doing wrong ?

Thanks in advance for your help !

Have a nice day

//UPDATE
Here is the updated yaml file, as requested by ramsey_lewis

    firewalls:
        dev:
            pattern: ^/(_(profiler|wdt)|css|images|js)/
            security: false
        back_office:
            pattern: ^/Dashboard
            lazy: true
            provider: bo_user_provider
            form_login:
                login_path: bo_login
                check_path: bo_login
                enable_csrf: true
            logout:
                path: app_logout
        customer:
            # pattern: ^/Dashboard
            lazy: true
            provider: app_user_provider
            form_login:
                login_path: app_login
                check_path: app_login
                enable_csrf: true
            logout:
                path: app_logout

答案1

得分: 1

我找到了一个解决方法,经过这些天的尝试,我不知道这是否是最佳做法,但它有效。

这与“pattern”属性有关。我使用了与您相同类型的模式 ^/login-admin^/login-user。问题是防火墙只能捕获这两个路由,但当我重定向后(离开登录表单后),防火墙不知道调用了哪个路由。

最终,我只为我的第二个登录表单创建了一个模式,因为所有 user 路由都会在类似 /user/profile/user/item-123 等路由之后。

而对于我的主登录表单(用于管理员防火墙),我没有设置任何模式属性。我只是将这个特定防火墙的配置放在了用户防火墙之后。这样,如果路由匹配类似 /user/* 的内容,将调用 user 防火墙,如果与 /user/* 无关的内容,将调用 admin 防火墙。如果防火墙无法捕获任何内容,它将让其他防火墙尝试捕获它。

firewalls:
    user:
        pattern: ^/(user\/.*)|/login-user|/logout-user
       ...
    admin:
        <--- 没有模式属性
        ...   

希望这对您有所帮助。

英文:

I found a workaround after all those days, I don't know if it's the best thing to do but it work.

It's all related to the pattern property. I was using the same kind of pattern as you ^/login-admin and ^/login-user. The problem was the firewalls could only catch these 2 routes, but when I was redirected (after leaving the login form) the firewalls didnt know which one was called.

I ended up creating a pattern only for my second login form, because all the user routes will be behind something like /user/profile, /user/item-123...

And for my main login form (for admin firewall), I didn't set any pattern property. I just put the configuration for this specific firewall after the user firewall. With that, if the routes match something like /user/*, the user firewall it will be called, if it's something else not related to /user/*, the admin will be called. If the firewall can't catch anything, it will let other firewalls try to catch it

firewalls:
    user:
        pattern: ^/(user\/.*)|/login-user|/logout-user
       ...
    admin:
        <--- no pattern property
        ...   

hope this helps

huangapple
  • 本文由 发表于 2023年4月16日 23:26:17
  • 转载请务必保留本文链接:https://go.coder-hub.com/76028637.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定