I have a Symfony4 app that is basically done and now am writing some tests for it. I'm trying to see if I can get a success http 200 from this controller route using this command vendor/bin/phpunit --debug tests/SampleTest.php
The page is protected by the default login form auth that symfony uses (debug below)
/**
* @IsGranted("ROLE_BRAND")
* @Route("/user/dashboard", methods={"GET"}, name="user_index", condition="context.getHost() in ['mysite.test', 'www.mysite.test']")
*
*/
public function dashboard(Request $request ): Response {
...clipped....
}
[2020-03-04 18:48:09] request.INFO: Matched route "user_index". {"route":"user_index","route_parameters":{"_route":"user_index","_controller":"App\\Controller\\Backend\\DashboardController::dashboard"},"request_uri":"https://mysite.test/user/dashboard","method":"GET"} []
[2020-03-04 18:48:10] security.DEBUG: Read existing security token from the session. {"key":"_security_main","token_class":"Symfony\\Component\\Security\\Core\\Authentication\\Token\\UsernamePasswordToken"} []
[2020-03-04 18:48:10] security.DEBUG: Checking for guard authentication credentials. {"firewall_key":"main","authenticators":1} []
[2020-03-04 18:48:10] security.DEBUG: Checking support on guard authenticator. {"firewall_key":"main","authenticator":"App\\Security\\LoginFormAuthenticator"} []
[2020-03-04 18:48:10] security.DEBUG: Guard authenticator does not support the request. {"firewall_key":"main","authenticator":"App\\Security\\LoginFormAuthenticator"} []
[2020-03-04 18:48:10] security.DEBUG: Access denied, the user is neither anonymous, nor remember-me. {"exception":"[object] (Symfony\\Component\\Security\\Core\\Exception\\AccessDeniedException(code: 403): Access Denied. at C:\\xampp\\htdocs\\mysite\\vendor\\symfony\\security-http\\Firewall\\AccessListener.php:99)"} []
[2020-03-04 18:48:10] request.ERROR: Uncaught PHP Exception Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException: "Access Denied." at C:\xampp\htdocs\mysite\vendor\symfony\security-http\Firewall\ExceptionListener.php line 137 {"exception":"[object] (Symfony\\Component\\HttpKernel\\Exception\\AccessDeniedHttpException(code: 0): Access Denied. at C:\\xampp\\htdocs\\mysite\\vendor\\symfony\\security-http\\Firewall\\ExceptionListener.php:137, Symfony\\Component\\Security\\Core\\Exception\\AccessDeniedException(code: 403): Access Denied. at C:\\xampp\\htdocs\\mysite\\vendor\\symfony\\security-http\\Firewall\\AccessListener.php:99)"} []
This is the test code from https://symfony.com/doc/4.4/testing/http_authentication.html
namespace App\Tests\Controller;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
use Symfony\Component\BrowserKit\Cookie;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
class SampleTest extends WebTestCase {
private $client = null;
public function setUp(): void {
$this->client = static::createClient();
}
public function testSecuredHello() {
$this->logIn();
$crawler = $this->client->request('GET', 'https://mysite.test/user/dashboard');
$this->assertSame(Response::HTTP_OK, $this->client->getResponse()->getStatusCode());
}
private function logIn() {
$session = self::$container->get('session');
$firewallName = 'main';
// if you don't define multiple connected firewalls, the context defaults to the firewall name
// See https://symfony.com/doc/current/reference/configuration/security.html#firewall-context
$firewallContext = 'main';
// you may need to use a different token class depending on your application.
// for example, when using Guard authentication you must instantiate PostAuthenticationGuardToken
$token = new UsernamePasswordToken('user@good.com', null, $firewallName, ['ROLE_ADMIN', 'ROLE_BRAND']);
$session->set('_security_' . $firewallContext, serialize($token));
$session->save();
$cookie = new Cookie($session->getName(), $session->getId());
$this->client->getCookieJar()->set($cookie);
}
}
bin/console debug:config security
Current configuration for extension with alias "security"
=========================================================
security:
providers:
app_user_provider:
entity:
class: App\Entity\User
property: email
manager_name: null
encoders:
App\Entity\User:
algorithm: auto
migrate_from: { }
hash_algorithm: sha512
key_length: 40
ignore_case: false
encode_as_base64: true
iterations: 5000
cost: null
memory_cost: null
time_cost: null
threads: null
role_hierarchy:
ROLE_ADMIN:
- ROLE_ALLOWED_TO_SWITCH
- ROLE_BRAND
- ROLE_ADVOCATES_VISIBLE
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
methods: { }
user_checker: security.user_checker
stateless: false
logout_on_user_change: true
main:
anonymous:
lazy: false
secret: null
switch_user:
parameter: _switch_to_brand_login
role: ROLE_ALLOWED_TO_SWITCH
stateless: false
guard:
authenticators:
- App\Security\LoginFormAuthenticator
entry_point: null
logout:
path: app_logout
csrf_parameter: _csrf_token
csrf_token_id: logout
target: /
invalidate_session: true
delete_cookies: { }
handlers: { }
remember_me:
remember_me_parameter: _remember_me
secret: '%env(APP_SECRET)%'
lifetime: 604800
path: /
user_providers: { }
catch_exceptions: true
name: REMEMBERME
domain: null
secure: null
httponly: true
samesite: lax
always_remember_me: false
methods: { }
security: true
user_checker: security.user_checker
stateless: false
logout_on_user_change: true
access_control:
-
path: ^/user/account
roles:
- IS_AUTHENTICATED_FULLY
requires_channel: null
host: null
port: null
ips: { }
methods: { }
allow_if: null
-
path: ^/user
roles:
- ROLE_USER
requires_channel: null
host: null
port: null
ips: { }
methods: { }
allow_if: null
-
path: ^/admin
roles:
- ROLE_ADMIN
requires_channel: null
host: null
port: null
ips: { }
methods: { }
allow_if: null
access_decision_manager:
strategy: affirmative
allow_if_all_abstain: false
allow_if_equal_granted_denied: true
access_denied_url: null
session_fixation_strategy: migrate
hide_user_not_found: true
always_authenticate_before_granting: false
erase_credentials: true
Using a PostAuthenticationGuardToken didn't work either. I'm all out of ideas