knpuniversity / oauth2-client-bundle

Easily talk to an OAuth2 server for social functionality in Symfony
https://symfonycasts.com
MIT License
787 stars 145 forks source link

Redirection to login page if not authenticated not working #419

Closed AnaSofiaDomingos closed 1 year ago

AnaSofiaDomingos commented 1 year ago

Hello,

On a project with Symfony 6.3, I am using oauth2-client-bundle to login with google. Everything works if I navigate to /connect/google manually but it's supposed to be automatically called when needed with the AuthenticationEntryPointInterface right ? What am I missing ?

Thanks in advance for your time.

Here is my GoogleAuthenticator :

class GoogleAuthenticator extends OAuth2Authenticator implements AuthenticationEntryPointInterface
{
    private $clientRegistry;

    public function __construct(ClientRegistry $clientRegistry) {
        $this->clientRegistry = $clientRegistry;
    }
    public function supports(Request $request): ?bool
    {
        return $request->attributes->get('_route') === 'connect_auth_check';
    }

    public function authenticate(Request $request): Passport
    {
        # google_oauth key used in knpu_oauth2_client
        $client = $this->clientRegistry->getClient('google_oauth');
        $accessToken = $this->fetchAccessToken($client);

        return new SelfValidatingPassport(
            new UserBadge($accessToken->getToken(), function () use ($accessToken, $client) {
                // rest of the code...
            })
        );
    }

    public function onAuthenticationSuccess(Request $request, TokenInterface $token, string $firewallName): ?Response
    {
        return new RedirectResponse($this->router->generate('dashboard'));
    }

    public function onAuthenticationFailure(Request $request, AuthenticationException $exception): ?Response
    {

        $message = strtr($exception->getMessageKey(), $exception->getMessageData());

        return new Response($message, Response::HTTP_FORBIDDEN);
    }

    public function start(Request $request, AuthenticationException $authException = null): Response
    {

        return new RedirectResponse(
            '/connect/google/',
            Response::HTTP_TEMPORARY_REDIRECT
        );
    }
}

my knpu_oauth2_client.yml file :

knpu_oauth2_client:
    clients:
        google_oauth:
            type: google
            client_id: '%env(google_client_id)%'
            client_secret: '%env(google_client_secret)%'
            redirect_route: connect_auth_check
            redirect_params: {}
            use_state: true

my AuthController :

class AuthController extends AbstractController
{
  /**
   * Link to this controller to start the "connect" process
   * @param ClientRegistry $clientRegistry
   *
   * @return RedirectResponse
   */
  #[Route("/connect/google", name: "connect_google_start")]
  public function connectAction(ClientRegistry $clientRegistry)
  {
    return $clientRegistry->getClient('google_oauth')
      ->redirect([
        'profile', 'email' // the scopes you want to access
      ]);
  }

  /**
   * After going to Google, you're redirected back here
   * because this is the "redirect_route" you configured
   * in config/packages/knpu_oauth2_client.yaml
   *
   * @param Request $request
   * @param ClientRegistry $clientRegistry
   *
   * @return RedirectResponse
   */
  #[Route("/oauth2/callback", schemes: ["https"], name: "connect_auth_check")]
  public function connectCheckAction(Request $request, ClientRegistry $clientRegistry)
  {
    // ** if you want to *authenticate* the user, then
    // leave this method blank and create a Guard authenticator
  }
}

my security.yml file :

security:
  enable_authenticator_manager: true
  providers:
    oauth_user_provider:
      id: App\Security\User\OAuthGoogleUserProvider
  firewalls:
    main:
      custom_authenticator: App\Security\GoogleAuthenticator
weaverryan commented 1 year ago

Hey! Yes, it should. Entrypoints are tricky because multiple "authentication mechanisms" can each provider their own... but your firewall can only have one. But because you're using the new security system (enable_authenticator_manager), you should get an exception if there are multiple (asking you to clarify which ONE entrypoint you want).

To help: what DOES happen when an anonymous user tries to go to a secure page? Is it redirected somewhere else? Do you get an exception from Symfony?

You could also try setting the entrypoint explicitly by setting entry_point to App\Security\GoogleAuthenticator - https://symfony.com/doc/current/security/entry_point.html

AnaSofiaDomingos commented 1 year ago

Hi, thanks for your answer.

I only have on authentication mechanism so it shouldn't be a problem.

When a anonymous user tries to go to a secure page, it's goes to infini redirection to /connect/google.

bocharsky-bw commented 1 year ago

I think you need to debug that in your specific case. Please, turn on the intercept_redirects feature: https://symfony.com/doc/current/reference/configuration/web_profiler.html#intercept-redirects and try to follow the workflow again. Notice from what pages you're redirecting to that /connect/google. It sounds like you need to exclude some paths from requiring the full authentication and allow anon users for them

AnaSofiaDomingos commented 1 year ago

It was exactly that I had some issues with my paths, thanks a lot for the help.

closing this issue.