首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >安全/会话保存,但未使用

安全/会话保存,但未使用
EN

Stack Overflow用户
提问于 2021-07-08 12:27:30
回答 1查看 610关注 0票数 1

完整的配置文件如下所示。

我的网站在不同的条目上使用2保护

  • lexik_jwt_authentication.jwt_token_authenticator访问^/api routes
  • App\Security\LoginAuthenticator以访问^/secured路由

JWT自动化运行良好,允许用户调用API平台路由(如localhost/api/types )。

问题在于如何使用LoginAuthenticator会话。这是基本的symfony配置(使用php bin/console make:auth自动生成文件)

使用正确的用户/密码登录时,保护程序将会话保存到app/var/sessions/dev/sess_ras4up86e1c8a1bs9khr5t7scg

在保存和设置会话时,LoginAuthenticator触发onAuthenticationSuccess函数将用户重定向到路由名称“`test”。

但是testController无法工作,将用户重定向到登录页面(302 HTTP code)。它还在var/log/dev/dev.log中引发以下错误:

代码语言:javascript
复制
[2021-07-08 13:07:40] request.INFO: Matched route "app_login". {"route":"app_login","route_parameters":{"_route":"app_login","_controller":"App\\Controller\\SecurityController::login"},"request_uri":"https://krang.local/login","method":"POST"} []
[2021-07-08 13:07:40] security.DEBUG: Checking for guard authentication credentials. {"firewall_key":"login","authenticators":1} []
[2021-07-08 13:07:40] security.DEBUG: Checking support on guard authenticator. {"firewall_key":"login","authenticator":"App\\Security\\LoginAuthenticator"} []
[2021-07-08 13:07:40] security.DEBUG: Calling getCredentials() on guard authenticator. {"firewall_key":"login","authenticator":"App\\Security\\LoginAuthenticator"} []
[2021-07-08 13:07:40] security.DEBUG: Passing guard token information to the GuardAuthenticationProvider {"firewall_key":"login","authenticator":"App\\Security\\LoginAuthenticator"} []
[2021-07-08 13:07:40] doctrine.DEBUG: SELECT t0.id AS id_1, t0.username AS username_2, t0.password AS password_3, t0.is_active AS is_active_4, t0.roles AS roles_5, t0.customer_id AS customer_id_6 FROM users t0 WHERE t0.username = ? LIMIT 1 ["matthieu"] []
[2021-07-08 13:07:40] security.INFO: Guard authentication successful! {"token":"[object] (Symfony\\Component\\Security\\Guard\\Token\\PostAuthenticationGuardToken: PostAuthenticationGuardToken(user=\"matthieu\", authenticated=true, roles=\"ROLE_USER, ROLE_ADMIN\"))","authenticator":"App\\Security\\LoginAuthenticator"} []
[2021-07-08 13:07:40] security.DEBUG: Guard authenticator set success response. {"response":"[object] (Symfony\\Component\\HttpFoundation\\RedirectResponse: HTTP/1.0 302 Found\r\nCache-Control: no-cache, private\r\nDate:          Thu, 08 Jul 2021 11:07:40 GMT\r\nLocation:      /secured/backmarketProducts\r\n\r\n<!DOCTYPE html>\n<html>\n    <head>\n        <meta charset=\"UTF-8\" />\n        <meta http-equiv=\"refresh\" content=\"0;url='/secured/backmarketProducts'\" />\n\n        <title>Redirecting to /secured/backmarketProducts</title>\n    </head>\n    <body>\n        Redirecting to <a href=\"/secured/backmarketProducts\">/secured/backmarketProducts</a>.\n    </body>\n</html>)","authenticator":"App\\Security\\LoginAuthenticator"} []
[2021-07-08 13:07:40] security.DEBUG: Remember me skipped: it is not configured for the firewall. {"authenticator":"App\\Security\\LoginAuthenticator"} []
[2021-07-08 13:07:40] security.DEBUG: The "App\Security\LoginAuthenticator" authenticator set the response. Any later authenticator will not be called {"authenticator":"App\\Security\\LoginAuthenticator"} []
[2021-07-08 13:07:40] request.INFO: Matched route "test". {"route":"test","route_parameters":{"_route":"test","_controller":"App\\Controller\\BackMarketController::productsList"},"request_uri":"https://krang.local/secured/backmarketProducts","method":"GET"} []
[2021-07-08 13:07:40] security.DEBUG: Checking for guard authentication credentials. {"firewall_key":"secured","authenticators":1} []
[2021-07-08 13:07:40] security.DEBUG: Checking support on guard authenticator. {"firewall_key":"secured","authenticator":"App\\Security\\LoginAuthenticator"} []
[2021-07-08 13:07:40] security.DEBUG: Guard authenticator does not support the request. {"firewall_key":"secured","authenticator":"App\\Security\\LoginAuthenticator"} []
[2021-07-08 13:07:40] security.INFO: An AuthenticationException was thrown; redirecting to authentication entry point. {"exception":"[object] (Symfony\\Component\\Security\\Core\\Exception\\AuthenticationCredentialsNotFoundException(code: 0): A Token was not found in the TokenStorage. at /home/matthieu/krang/webservice/vendor/symfony/security-http/Firewall/AccessListener.php:69)"} []
[2021-07-08 13:07:40] security.DEBUG: Calling Authentication entry point. [] []
[2021-07-08 13:07:40] request.INFO: Matched route "app_login". {"route":"app_login","route_parameters":{"_route":"app_login","_controller":"App\\Controller\\SecurityController::login"},"request_uri":"https://krang.local/login","method":"GET"} []
[2021-07-08 13:07:40] security.DEBUG: Checking for guard authentication credentials. {"firewall_key":"login","authenticators":1} []
[2021-07-08 13:07:40] security.DEBUG: Checking support on guard authenticator. {"firewall_key":"login","authenticator":"App\\Security\\LoginAuthenticator"} []
[2021-07-08 13:07:40] security.DEBUG: Guard authenticator does not support the request. {"firewall_key":"login","authenticator":"App\\Security\\LoginAuthenticator"} []
[2021-07-08 13:07:40] security.INFO: Populated the TokenStorage with an anonymous Token. [] []
[2021-07-08 13:07:40] request.INFO: Matched route "_wdt". {"route":"_wdt","route_parameters":{"_route":"_wdt","_controller":"web_profiler.controller.profiler::toolbarAction","token":"ad25b7"},"request_uri":"https://krang.local/_wdt/ad25b7","method":"GET"} []

我们可以看到这个错误:

代码语言:javascript
复制
[2021-07-08 13:07:40] security.DEBUG: Guard authenticator does not support the request. {"firewall_key":"secured","authenticator":"App\\Security\\LoginAuthenticator"} []
[2021-07-08 13:07:40] security.INFO: An AuthenticationException was thrown; redirecting to authentication entry point. {"exception":"[object] (Symfony\\Component\\Security\\Core\\Exception\\AuthenticationCredentialsNotFoundException(code: 0): A Token was not found in the TokenStorage. at /home/matthieu/krang/webservice/vendor/symfony/security-http/Firewall/AccessListener.php:69)"} []

保护身份验证器不支持请求。

这是什么意思?我给您一些有用的代码来结帐:

security.yaml : (完整文件)

代码语言:javascript
复制
security:
    encoders:
        App\Entity\User:
            algorithm: auto

    role_hierarchy:
        ROLE_USER : "ROLE_USER"
        ROLE_ADMIN : "ROLE_ADMIN"
        ROLE_SUPERADMIN : "ROLE_SUPERADMIN"

    providers:
        entity_provider:
            entity:
                class: App\Entity\User
                property: username

    firewalls:
        dev:
            pattern: ^/(_(profiler|wdt)|css|images|js)/
            security: false
        login:
            pattern:  ^/login
            stateless: true
            anonymous: true
            json_login:
                check_path: /login_check
                success_handler: lexik_jwt_authentication.handler.authentication_success
                failure_handler: lexik_jwt_authentication.handler.authentication_failure
            guard:
                authenticators:
                    - App\Security\LoginAuthenticator
            logout:
                path: app_logout
                # where to redirect after logout
                # target: app_any_route

        docs:
            pattern:  ^/docs
            stateless: true
            anonymous: true

        secured:
            pattern: ^/secured
            stateless: true
            provider: entity_provider
            guard:
                authenticators:
                    - App\Security\LoginAuthenticator

        api:
            pattern:  ^/api
            stateless: true
            anonymous: false
            provider: entity_provider
            guard:
                authenticators:
                    - lexik_jwt_authentication.jwt_token_authenticator

    access_control:
        - { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/register, roles: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/api, roles: IS_AUTHENTICATED_FULLY  }
        - { path: ^/docs, roles: IS_AUTHENTICATED_ANONYMOUSLY  }
        - { path: ^/secured, roles: IS_AUTHENTICATED_FULLY  }

SecurityController: (默认不变)

代码语言:javascript
复制
class SecurityController extends AbstractController
{
    /**
     * @Route("/login", name="app_login")
     */
    public function login(AuthenticationUtils $authenticationUtils): Response
    {
        if ($this->getUser()) {
            die();
        }

        // get the login error if there is one
        $error = $authenticationUtils->getLastAuthenticationError();
        // last username entered by the user
        $lastUsername = $authenticationUtils->getLastUsername();

        return $this->render('security/login.html.twig', ['last_username' => $lastUsername, 'error' => $error]);
    }

    /**
     * @Route("/logout", name="app_logout")
     */
    public function logout()
    {
        throw new \LogicException('This method can be blank - it will be intercepted by the logout key on your firewall.');
    }
}

LoginAuthenticator: (src/Security/LoginAuthenticator.php)

代码语言:javascript
复制
class LoginAuthenticator extends AbstractFormLoginAuthenticator implements PasswordAuthenticatedInterface
{
    use TargetPathTrait;

    public const LOGIN_ROUTE = 'app_login';

    private $entityManager;
    private $urlGenerator;
    private $csrfTokenManager;
    private $passwordEncoder;

    public function __construct(EntityManagerInterface $entityManager, UrlGeneratorInterface $urlGenerator, CsrfTokenManagerInterface $csrfTokenManager, UserPasswordEncoderInterface $passwordEncoder)
    {
        $this->entityManager = $entityManager;
        $this->urlGenerator = $urlGenerator;
        $this->csrfTokenManager = $csrfTokenManager;
        $this->passwordEncoder = $passwordEncoder;
    }

    public function supports(Request $request)
    {
        return self::LOGIN_ROUTE === $request->attributes->get('_route')
            && $request->isMethod('POST');
    }

    public function getCredentials(Request $request)
    {
        $credentials = [
            'username' => $request->request->get('username'),
            'password' => $request->request->get('password'),
            'csrf_token' => $request->request->get('_csrf_token'),
        ];
        $request->getSession()->set(
            Security::LAST_USERNAME,
            $credentials['username']
        );

        return $credentials;
    }

    public function getUser($credentials, UserProviderInterface $userProvider)
    {
        $token = new CsrfToken('authenticate', $credentials['csrf_token']);
        if (!$this->csrfTokenManager->isTokenValid($token)) {
            throw new InvalidCsrfTokenException();
        }

        $user = $this->entityManager->getRepository(User::class)->findOneBy(['username' => $credentials['username']]);

        if (!$user) {
            throw new UsernameNotFoundException('Username could not be found.');
        }

        return $user;
    }

    public function checkCredentials($credentials, UserInterface $user)
    {
        return $this->passwordEncoder->isPasswordValid($user, $credentials['password']);
    }

    /**
     * Used to upgrade (rehash) the user's password automatically over time.
     */
    public function getPassword($credentials): ?string
    {
        return $credentials['password'];
    }

    public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey)
    {

        if ($targetPath = $this->getTargetPath($request->getSession(), $providerKey)) {
            return new RedirectResponse($targetPath);
        }
       return new RedirectResponse($this->urlGenerator->generate('test'));
    }

    protected function getLoginUrl()
    {
        return $this->urlGenerator->generate(self::LOGIN_ROUTE);
    }
}

BackMarketController (只是一个函数)函数在认证成功时调用

代码语言:javascript
复制
    /**
     * @return JsonResponse
     * @Route("/secured/backmarketProducts", name="test")
     */
    public function productsList(Request $request)
    {
        return $this->render('back_market/backmarketProducts.html.twig');
    }

关于网络服务器:

  • Apache2
  • Debian 8
  • 使用HTTPS
  • Symfony 4.4

当然,我可以给你更多的信息,只要问一下就行了。

我通过查看其他类似的主题尝试了什么:

更新1 (3天后)

我找到了一种允许jwt令牌和安全认证器协同工作的方法。

有一个security.yaml:

代码语言:javascript
复制
security:
    encoders:
        App\Entity\User:
            algorithm: auto

    role_hierarchy:
        ROLE_USER : "ROLE_USER"
        ROLE_ADMIN : "ROLE_ADMIN"
        ROLE_SUPERADMIN : "ROLE_SUPERADMIN"

    providers:
        entity_provider:
            entity:
                class: App\Entity\User
                property: username

    firewalls:
        dev:
            pattern: ^/(_(profiler|wdt)|css|images|js)/
            security: false
        main:
            anonymous: true
            guard:
                entry_point: lexik_jwt_authentication.jwt_token_authenticator
                authenticators:
                    - App\Security\SecurityAuthenticator
                    - lexik_jwt_authentication.jwt_token_authenticator
            logout:
                path: app_logout
            json_login:
                check_path: /login_check
                success_handler: lexik_jwt_authentication.handler.authentication_success
                failure_handler: lexik_jwt_authentication.handler.authentication_failure
        login:
            pattern:  ^/login
            stateless: true
            anonymous: true
            json_login:
                check_path: /login_check
                success_handler: lexik_jwt_authentication.handler.authentication_success
                failure_handler: lexik_jwt_authentication.handler.authentication_failure

        docs:
            pattern:  ^/docs
            stateless: true
            anonymous: true

        api:
            pattern:  ^/api
            stateless: true
            anonymous: false
            provider: entity_provider
            guard:
                authenticators:
                    - lexik_jwt_authentication.jwt_token_authenticator

        secured:
            pattern: ^/secured
            anonymous: false
            guard:
                authenticators:
                    - App\Security\SecurityAuthenticator
            logout:
                path: app_logout

    access_control:
        - { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/register, roles: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/api, roles: IS_AUTHENTICATED_FULLY  }
        - { path: ^/docs, roles: IS_AUTHENTICATED_ANONYMOUSLY  }
        - { path: ^/secured, roles: IS_AUTHENTICATED_FULLY  }

我认为这个块解决了这个问题,symfony安全委员会默认使用jwt在防火墙上声明了两个守卫。

为了使用基本的symfony auth系统(securityAuthentificator),我刚刚添加了一个提供SecurityAuthenticator的安全的防火墙

有什么好办法和保安一起工作吗?这个把戏看起来合法吗?我不确定我能提供一个好的解决方案。

EN

回答 1

Stack Overflow用户

发布于 2021-07-15 10:24:13

似乎没人能帮我。无论如何,我自己解决了这个问题。

这是我的完整功能security.yaml

此配置正在工作,从而使symfony能够与JWT令牌一起使用API PLATEFORM,并在一个简单的后台应用程序上记录用户。

代码语言:javascript
复制
security:
    encoders:
        App\Entity\User:
            algorithm: auto

    role_hierarchy:
        ROLE_USER : "ROLE_USER"
        ROLE_ADMIN : "ROLE_ADMIN"
        ROLE_SUPERADMIN : "ROLE_SUPERADMIN"

    providers:
        entity_provider:
            entity:
                class: App\Entity\User
                property: username

    firewalls:
        dev:
            pattern: ^/(_(profiler|wdt)|css|images|js)/
            security: false
        main:
            anonymous: true
            guard:
                entry_point: lexik_jwt_authentication.jwt_token_authenticator
                authenticators:
                    - App\Security\SecurityAuthenticator
                    - lexik_jwt_authentication.jwt_token_authenticator
            logout:
                path: app_logout
            json_login:
                check_path: /login_check
                success_handler: lexik_jwt_authentication.handler.authentication_success
                failure_handler: lexik_jwt_authentication.handler.authentication_failure
        login:
            pattern:  ^/login
            stateless: true
            anonymous: true
            json_login:
                check_path: /login_check
                success_handler: lexik_jwt_authentication.handler.authentication_success
                failure_handler: lexik_jwt_authentication.handler.authentication_failure

        docs:
            pattern:  ^/docs
            stateless: true
            anonymous: true

        api:
            pattern:  ^/api
            stateless: true
            anonymous: false
            provider: entity_provider
            guard:
                authenticators:
                    - lexik_jwt_authentication.jwt_token_authenticator

        secured:
            pattern: ^/secured
            anonymous: false
            guard:
                authenticators:
                    - App\Security\SecurityAuthenticator
            logout:
                path: app_logout

    access_control:
        - { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/register, roles: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/api, roles: IS_AUTHENTICATED_FULLY  }
        - { path: ^/docs, roles: IS_AUTHENTICATED_ANONYMOUSLY  }
        - { path: ^/secured, roles: IS_AUTHENTICATED_FULLY  }
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68301633

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档