My Synfony2 app can't resolve a service dependency - symfony

I'm trying to integrate FOSUserBundle with HWIBundle, to add the social media connections to my app. The FOSUser is working perfectly, but I get a problem with the integration with HWIOAuthBundle.
Bundles are loaded in AppKernel, perfectly.
This is my config.yml
hwi_oauth:
connect:
account_connector: my_user_provider
firewall_name: name
fosub:
username_iterations: 30
properties:
facebook: facebook_id
google: google_id
resource_owners:
facebook:
type: facebook
client_id: "%facebook_app_id%"
client_secret: "%facebook_app_secret%"
scope: ""
google:
type: google
client_id: "%google_app_id%"
client_secret: "%google_app_secret%"
scope: "https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile"
This is my security.yml:
security:
encoders:
FOS\UserBundle\Model\UserInterface: sha512
role_hierarchy:
ROLE_ADMIN: ROLE_USER
ROLE_SUPER_ADMIN: ROLE_USER
providers:
fos_userbundle:
id: fos_user.user_provider.username_email
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
main:
pattern: ^/
form_login:
provider: fos_userbundle
csrf_provider: form.csrf_provider
login_path: /login
check_path: /login_check
oauth:
resource_owners:
facebook: "/login/check-facebook"
google: "/login/check-google"
login_path: /login
failure_path: /login
oauth_user_provider:
service: my_user_provider
logout: true
anonymous: true
login:
pattern: ^/login$
security: false
remember_me:
key: "%secret%"
lifetime: 31536000 # 365 days in seconds
path: /
domain: ~ # Defaults to the current domain from $_SERVER
access_control:
- { path: ^/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/register, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/resetting, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/backend/, role: ROLE_ADMIN }
This is my Bundle services.yml
parameters:
my_user_provider.class: Main\SiteBundle\Services\FOSUBUserProvider
services:
my_user_provider:
class: "%my_user_provider.class%"
arguments: [#fos_user.user_manager,{facebook: facebook_id, google: google_id}]
And this is the Service:
namespace Main\SiteBundle\Services;
use HWI\Bundle\OAuthBundle\OAuth\Response\UserResponseInterface;
use HWI\Bundle\OAuthBundle\Security\Core\User\FOSUBUserProvider as BaseClass;
use Symfony\Component\Security\Core\User\UserInterface;
class FOSUBUserProvider extends BaseClass
{
/**
* {#inheritDoc}
*/
public function connect(UserInterface $user, UserResponseInterface $response)
{
$property = $this->getProperty($response);
$username = $response->getUsername();
//on connect - get the access token and the user ID
$service = $response->getResourceOwner()->getName();
$setter = 'set'.ucfirst($service);
$setter_id = $setter.'Id';
$setter_token = $setter.'AccessToken';
//we "disconnect" previously connected users
if (null !== $previousUser = $this->userManager->findUserBy(array($property => $username))) {
$previousUser->$setter_id(null);
$previousUser->$setter_token(null);
$this->userManager->updateUser($previousUser);
}
//we connect current user
$user->$setter_id($username);
$user->$setter_token($response->getAccessToken());
$this->userManager->updateUser($user);
}
/**
* {#inheritdoc}
*/
public function loadUserByOAuthUserResponse(UserResponseInterface $response)
{
$username = $response->getUsername();
$user = $this->userManager->findUserBy(array($this->getProperty($response) => $username));
//when the user is registrating
if (null === $user) {
$service = $response->getResourceOwner()->getName();
$setter = 'set'.ucfirst($service);
$setter_id = $setter.'Id';
$setter_token = $setter.'AccessToken';
// create new user here
$user = $this->userManager->createUser();
$user->$setter_id($username);
$user->$setter_token($response->getAccessToken());
//I have set all requested data with the user's username
//modify here with relevant data
$user->setUsername($username);
$user->setEmail($username);
$user->setPassword($username);
$user->setEnabled(true);
$this->userManager->updateUser($user);
return $user;
}
//if user exists - go with the HWIOAuth way
$user = parent::loadUserByOAuthUserResponse($response);
$serviceName = $response->getResourceOwner()->getName();
$setter = 'set' . ucfirst($serviceName) . 'AccessToken';
//update access token
$user->$setter($response->getAccessToken());
return $user;
}
}
Yeah, this is the error I get in the browser:
ServiceNotFoundException in
CheckExceptionOnInvalidReferenceBehaviorPass.php line 58: The service
"hwi_oauth.security.oauth_utils" has a dependency on a non-existent
service "hwi_oauth.resource_ownermap.name".
While doing a "composer update" I get this
[Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException]
The service "hwi_oauth.security.oauth_utils" has a dependency on a
non-existent service "hwi_oauth.resource_ownermap.name".
Script
Sensio\Bundle\DistributionBundle\Composer\ScriptHandler::clearCache
handling the post-update-cmd event terminated with an exception
[RuntimeException] An error occurred when executing the
"'cache:clear --no-warmup'" command.

In config.yml you have configured hwi_oauth with "firewall_name: name".
But in security.yml you have no firewall with that name "name" (but you have a "main" named firewall not mentioned under hwi_oauth in config.yml). This causes the error message you have.

Related

lexik JWT error invalid token while decoding token

I've made an authentication system with LexikJWTBundle, below are my security.yml, my service.yml and my config.yml
security:
encoders:
FOS\UserBundle\Model\UserInterface: bcrypt
providers:
fos_userbundle:
id: fos_user.user_provider.username
role_hierarchy:
ROLE_ADMIN: ROLE_USER
ROLE_SUPER_ADMIN: [ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH]
firewalls:
login:
pattern: ^/api/login
stateless: true
anonymous: true
provider: fos_userbundle
logout: true
form_login:
check_path: /api/login_check
username_parameter: username
password_parameter: password
success_handler: lexik_jwt_authentication.handler.authentication_success
failure_handler: lexik_jwt_authentication.handler.authentication_failure
require_previous_session: false
register:
pattern: ^/api/register
stateless: true
anonymous: true
register-admin:
pattern: ^/api/adminregister
stateless: true
anonymous: true
api:
pattern: ^/api
stateless: true
anonymous: true
provider: fos_userbundle
guard:
authenticators:
- jwt_token_authenticator
admin-api:
pattern: ^/api/admin
provider: fos_userbundle
stateless: true
anonymous: true
guard:
authenticators:
- jwt_token_authenticator
# disables authentication for assets and the profiler, adapt it according to your needs
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
access_control:
- { path: ^/api/login_check, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/api/adminregister, roles: IS_AUTHENTICATED_ANONYMOUSLY, ips: 127.0.0.1, host: localhost }
- { path: ^/api/register, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/api/, roles: [IS_AUTHENTICATED_FULLY, ROLE_USER] }
- { path: ^/api/admin/, roles: [IS_AUTHENTICATED_FULLY, ROLE_ADMIN] }
- { path: ^/api/admin/users, roles: [IS_AUTHENTICATED_FULLY, ROLE_SUPER_ADMIN] }
and the service.yml
service.yml
# Learn more about services, parameters and containers at
# https://symfony.com/doc/current/service_container.html
parameters:
#parameter_name: value
services:
# default configuration for services in *this* file
_defaults:
# automatically injects dependencies in your services
autowire: true
# automatically registers your services as commands, event subscribers, etc.
autoconfigure: true
# this means you cannot fetch services directly from the container via $container->get()
# if you need to do this, you can override this setting on individual services
public: false
# makes classes in src/AppBundle available to be used as services
# this creates a service per class whose id is the fully-qualified class name
AppBundle\:
resource: '../../src/AppBundle/*'
# you can exclude directories or files
# but if a service is unused, it's removed anyway
exclude: '../../src/AppBundle/{Entity,Repository,Tests}'
# controllers are imported separately to make sure they're private
# and have a tag that allows actions to type-hint services
AppBundle\Controller\:
resource: '../../src/AppBundle/Controller'
public: true
tags: ['controller.service_arguments']
# add more services, or override services that need manual wiring
# AppBundle\Service\ExampleService:
# arguments:
# $someArgument: 'some_value'
jwt_token_authenticator:
class: AppBundle\Security\JwtTokenAuthenticator
arguments: ['#lexik_jwt_authentication.encoder.lcobucci', '#doctrine.orm.entity_manager']
#service for cors preflight event
AppBundle\Event\Listener\:
resource: '../../src/AppBundle/Event/Listener/'
tags:
- { name: kernel.event_listener, event: kernel.response }
and the config.yml
config.yml
// I've only put the lexik config
lexik_jwt_authentication:
secret_key: "%kernel.project_dir%/config/jwt/private.pem" # required for token creation
public_key: "%kernel.project_dir%/config/jwt/private.pem" # required for token verification
pass_phrase: "%user_pass%" # required for token creation, usage of an environment variable is recommended
token_ttl: 36000
user_identity_field: username # key under which the user identity will be stored in the token payload
clock_skew: 0
# token encoding/decoding settings
encoder:
# token encoder/decoder service - default implementation based on the lcobucci/jwt library
service: lexik_jwt_authentication.encoder.lcobucci
# encryption algorithm used by the encoder service
signature_algorithm: RS256
# token extraction settings
token_extractors:
# look for a token as Authorization Header
authorization_header:
enabled: true
prefix: Bearer
name: Authorization
# check token in a cookie
cookie:
enabled: false
name: BEARER
# check token in query string parameter
query_parameter:
enabled: false
name: bearer
that's the function for guard authenticator
class JwtTokenAuthenticator extends AbstractGuardAuthenticator
{
private $jwtEncoder;
private $em;
public function __construct(JWTEncoderInterface $jwtEncoder, EntityManager $em)
{
$this->jwtEncoder = $jwtEncoder;
$this->em = $em;
}
public function supports(Request $request)
{
// look for header "Authorization: Bearer <token>"
return $request->headers->has('Authorization')
&& 0 === strpos($request->headers->get('Authorization'), 'Bearer ');
}
public function getCredentials(Request $request)
{
$extractor = new AuthorizationHeaderTokenExtractor(
'Bearer',
'Authorization'
);
$token = $extractor->extract($request);
if (!$token) {
return new JsonResponse([
"errorMessage" => "The token doesn't exist in authorization header please provide it like (Authorization: Bearer token)"
]);
}
return $token;
}
public function getUser($credentials, UserProviderInterface $userProvider)
{
var_dump($credentials);
try {
$data = $this->jwtEncoder->decode($credentials);
} catch (JWTDecodeFailureException $e) {
$reason = $e->getReason();
switch ($reason) {
case 'invalid_token':
// throw new InvalidTokenException();
throw new CustomUserMessageAuthenticationException('The token is invalid');
break;
case 'unverified_token':
throw new CustomUserMessageAuthenticationException('Unverified Token');
break;
case 'expired_token':
// throw new ExpiredTokenException();
throw new CustomUserMessageAuthenticationException('The token is expired');
break;
default:
throw new MissingTokenException();
break;
}
}
$username = $data['username'];
return $this->em
->getRepository('AppBundle:User')
->findOneBy(['username' => $username]);
}
public function checkCredentials($credentials, UserInterface $user)
{
return true;
}
public function onAuthenticationFailure(Request $request, AuthenticationException $exception)
{
return new JsonResponse([
'message' => $exception->getMessageKey()
], 401);
}
public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey)
{
}
public function supportsRememberMe()
{
return false;
}
public function start(Request $request, AuthenticationException $authException = NULL)
{
throw new \Exception('Not used: entry_point from other authentication is used');
}
}
the token exists in header but when I try to decode it I have an error
{"message": "The token is invalid"} even if the token is validated by jwt.io please I need help that's almost 3 weeks that i try to manage this trouble
Try to replace :
username_parameter
password_parameter
to :
username_path
password_path
and don't forget to check in your user entity getUsername() return the right username_path.

HWIOAuthBundle custom user provider will not login user

I'm using HWIOAuthBundle with Symfony 4.1.
My custom user provider gets called and returns a valid user, however the user is not logged in after the redirect. The web profiler shows: logged in as anon; anonymous token; firewall main
I've simplified the provider class below for brevity and it's only considering twitter right now. The conditions around $source are so I can add more later.
I have used xdebug to make sure loadUserByOauthuserResponse() is being called and that users are both being created in the case of a new user, or the existing user is being returned when it exists.
Question: If loadUserbyOauthUserResponse() IS returning a valid user entity, then what could be preventing it from creating a valid session with this user?
<?php
namespace App\Security;
...
class OAuthProvider extends OAuthUserProvider
{
...
public function loadUserByOAuthUserResponse(UserResponseInterface $response): User
{
/** #var EntityManager $em */
$em = $this->container->get('doctrine.orm.entity_manager');
$repo = $em->getRepository('App:User');
$source = $response->getResourceOwner()->getName();
$email = null;
$data = [];
$newUser = false;
// Set email and socialUser.
if ($source === 'twitter') {
$data = $response->getData();
$email = $data['email'];
}
// Check if this user already exists in our app.
$user = $repo->findOneBy(['email' => $email]);
if ($user === null) {
$newUser = true;
$user = new User();
$user->setPassword($this->strand(32));
}
// Set session and user data based on source.
if ($source === 'twitter') {
$name = $data['name'];
if ($newUser) {
$user->setNickName($name);
$user->setEmail($email);
$em->persist($user);
$em->flush();
}
}
return $user;
}
}
hwi_oauth.yaml
hwi_oauth:
# list of names of the firewalls in which this bundle is active, this setting MUST be set
firewall_names: [main]
# https://github.com/hwi/HWIOAuthBundle/blob/master/Resources/doc/2-configuring_resource_owners.md
resource_owners:
twitter:
type: twitter
client_id: '%env(TWITTER_ID)%'
client_secret: '%env(TWITTER_SECRET)%'
options:
include_email: true
services.yaml:
app.oauth_aware.user_provider.service:
class: App\Security\OAuthProvider
arguments: ['#service_container']
security.yaml:
security:
# https://symfony.com/doc/current/book/security.html#where-do-users-come-from-user-providers
encoders:
App\Entity\User: bcrypt
role_hierarchy:
ROLE_ADMIN: ROLE_USER
ROLE_SUPER_ADMIN: ROLE_ADMIN
providers:
app_users:
entity: { class: App\Entity\User, property: email }
hwi:
id: app.oauth_aware.user_provider.service
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
main:
provider: app_users
anonymous: ~
remember_me:
secret: "%env(APP_SECRET)%"
lifetime: 2592000
path: /
guard:
authenticators:
- App\Security\LoginFormAuthenticator
entry_point: App\Security\LoginFormAuthenticator
logout:
path: /logout
target: /
oauth:
resource_owners:
twitter: "/login/check-twitter"
default_target_path: /
login_path: /
failure_path: /user-login
oauth_user_provider:
service: app.oauth_aware.user_provider.service
switch_user: ~
access_control:
- { path: ^/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/register, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/recover, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/admin/, role: ROLE_ADMIN }
I had the same problem until I found in logs "Token was deauthenticated after trying to refresh it."
And after that I found this solution.
Token was deauthenticated after trying to refresh it
I added isEqualTo and did not logged me out.

Custom FOSUBUserProvider not working properly

I've been following the instruction here: https://gist.github.com/danvbe/4476697, I have read the entire thread more than once, but I'm not getting a solution for my problem.
I want to use the oauth bundle just for account linking, persisting the user data from oauth provider. My users will not be authenticated using oauth.
Nevertheless, I have implemented the whole thing to see if it works with github as provider, but nothing. I'm able to go to the authorization page, but when I click on Allow Access, I'm inevitable redirected to the login page with this error No oauth code in the request.
If stop using the custom FOSUBUserProvider and change to the default HWI one, then I get the app registered in Github but cannot persist the data.
Important: I tried replicating exactly the FOSUBUserProvider from HWI and the same problem remained, so probably is not related it's implementation but maybe with the service definition or the config.
Any help is greatly appreciated.
These are the relevant files:
FOSUBUserProvider.php
class FOSUBUserProvider extends BaseClass
{
/**
* {#inheritDoc}
*/
public function connect(UserInterface $user, UserResponseInterface $response)
{
$property = $this->getProperty($response);
$username = $response->getUsername();
//on connect - get the access token and the user ID
$service = $response->getResourceOwner()->getName();
$setter = 'set'.ucfirst($service);
$setter_id = $setter.'Id';
$setter_token = $setter.'AccessToken';
//we "disconnect" previously connected users
if (null !== $previousUser = $this->userManager->findUserBy(array($property => $username))) {
$previousUser->$setter_id(null);
$previousUser->$setter_token(null);
$this->userManager->updateUser($previousUser);
}
//we connect current user
$user->$setter_id($username);
$user->$setter_token($response->getAccessToken());
$this->userManager->updateUser($user);
}
/**
* {#inheritdoc}
*/
public function loadUserByOAuthUserResponse(UserResponseInterface $response)
{
$username = $response->getUsername();
$user = $this->userManager->findUserBy(array($this->getProperty($response) => $username));
//when the user is registrating
if (null === $user) {
$service = $response->getResourceOwner()->getName();
$setter = 'set'.ucfirst($service);
$setter_id = $setter.'Id';
$setter_token = $setter.'AccessToken';
// create new user here
$user = $this->userManager->createUser();
$user->$setter_id($username);
$user->$setter_token($response->getAccessToken());
//I have set all requested data with the user's username
//modify here with relevant data
$user->setUsername($username);
$user->setEmail($username);
$user->setPassword($username);
$user->setEnabled(true);
$this->userManager->updateUser($user);
return $user;
}
//if user exists - go with the HWIOAuth way
$user = parent::loadUserByOAuthUserResponse($response);
$serviceName = $response->getResourceOwner()->getName();
$setter = 'set' . ucfirst($serviceName) . 'AccessToken';
//update access token
$user->$setter($response->getAccessToken());
return $user;
}
}
config.yml
hwi_oauth:
#this is my custom user provider, created from FOSUBUserProvider - will manage the
#automatic user registration on your site, with data from the provider (facebook. google, etc.)
#and also, the connecting part (get the token and the user_id)
connect:
account_connector: custom.user.provider
# name of the firewall in which this bundle is active, this setting MUST be set
firewall_name: main
# optional FOSUserBundle integration
fosub:
# try 30 times to check if a username is available (foo, foo1, foo2 etc)
username_iterations: 30
# mapping between resource owners (see below) and properties
properties:
github: githubId
# optional HTTP Client configuration
http_client:
verify_peer: false
resource_owners:
github:
type: github
client_id: xxxxxxxxxxxxxxxxxxxxxx
client_secret: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
scope: "repo, delete_repo, notifications, gist"
options:
csrf: true
security.yml
providers:
fos_userbundle:
id: fos_user.user_provider.username_email
firewalls: #CAUTION! The order of the firewalls IS ON PURPOSE! DON'T CHANGE!
# Disabling the security for the web debug toolbar, the profiler and Assetic.
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
# -> custom firewall for the admin area of the URL
admin:
pattern: /admin(.*)
context: user
form_login:
provider: fos_userbundle
login_path: /admin/login
use_forward: false
check_path: /admin/login_check
failure_path: null
logout:
path: /admin/logout
anonymous: true
# -> end custom configuration
# defaut login area for standard users
# This firewall is used to handle the public login area
# This part is handled by the FOS User Bundle
main:
pattern: .*
context: user
form_login:
provider: fos_userbundle
login_path: /login
use_forward: false
check_path: /login_check
failure_path: null
logout: true
anonymous: true
# Login path for OAuth providers
oauth:
resource_owners:
github: "/login/check-github"
trello: "/login/check-trello"
login_path: /login
failure_path: /login
# FOSUB integration
# oauth_user_provider:
# service: hwi_oauth.user.provider.fosub_bridge
oauth_user_provider:
#this is my custom user provider, created from FOSUBUserProvider - will manage the
#automatic user registration on website, with data from the provider (github. trello, etc.)
service: custom.user.provider
access_control:
# URL of FOSUserBundle which need to be available to anonymous users
- { path: ^/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/register, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/resetting, role: IS_AUTHENTICATED_ANONYMOUSLY }
# Admin login page needs to be access without credential
- { path: ^/admin/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/admin/logout$, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/admin/login_check$, role: IS_AUTHENTICATED_ANONYMOUSLY }
# Secured part of the site
# This config requires being logged for the whole site and having the admin role for the admin part.
# Change these rules to adapt them to your needs
- { path: ^/admin/, role: [ROLE_ADMIN, ROLE_SONATA_ADMIN] }
- { path: ^/.*, role: ROLE_USER } #This is on purpose.
routing.yml
hwi_oauth_security:
resource: "#HWIOAuthBundle/Resources/config/routing/login.xml"
prefix: /connect
hwi_oauth_connect:
resource: "#HWIOAuthBundle/Resources/config/routing/connect.xml"
prefix: /connect
hwi_oauth_redirect:
resource: "#HWIOAuthBundle/Resources/config/routing/redirect.xml"
prefix: /connect
services.yml
parameters:
custom.user.provider.class: My\Bundle\Path\Security\Core\User\FOSUBUserProvider
services:
sonata.admin.user:
class: My\Bundle\Path\Admin\Model\UserAdmin
tags:
# - { name: sonata.admin, manager_type: orm, group: users, label: users, label_translator_strategy: sonata.admin.label.strategy.underscore }
arguments:
- ~
- My\Bundle\Path\Entity\User
- SonataAdminBundle:CRUD
calls:
- [setTranslationDomain, [SonataUserBundle]]
- [setUserManager, [#fos_user.user_manager]]
- [setSecurityContext, [#security.context]]
custom.user.provider:
class: "%custom.user.provider.class%"
#this is the place where the properties are passed to the UserProvider - see config.yml
arguments: [#fos_user.user_manager,{github: github_id, trello: trello_id}]
Well, after a lot of try and error, I found the problem:
The callback URL in Github was: http://mywebsite/login/check-github but that was wrong. The truth is that I never found what this value had to be set up to, so I was guessing. By accident I discovered the right URL: http://mywebsite/connect/service/github applicable in my case, with my configuration.
I found it in one of the times in wich I tried the default HWI Provider, inspecting the redirects with the browser console.

my website /home for authenticated users and anonymous

I don't understand my problem. I just want :
/ redirected /home
/home is not secured but logged user is able to navigate into
the whole website.
Non authenticated user is only able to see the homepage
People can register an account to access the whole website
So it's my security.yml config :
security:
encoders:
Siriru\AntBundle\Entity\User: sha512
role_hierarchy:
ROLE_ADMIN: ROLE_USER
ROLE_SUPER_ADMIN: [ROLE_USER, ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH]
providers:
main:
entity: { class: Siriru\AntBundle\Entity\User, property: username }
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
root:
pattern: ^/$
security: false
home:
pattern: ^/home$
security: false
login:
pattern: ^/login$
security: false
register:
pattern: ^/account/
security: false
secured_area:
pattern: ^/
form_login:
check_path: /login_check
login_path: /login
username_parameter: username
password_parameter: password
logout:
path: /logout
target: /home
Registration is ok, login too. But after the redirection to the homepage, user is not authenticated (in the symfony profiler "You are not authenticated."). If I reach the secured area, i'm logged but not authenticated.
<?php
namespace Siriru\AntBundle\Controller;
use Siriru\AntBundle\Form\Model\Registration;
use Siriru\AntBundle\Form\Type\RegistrationType;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\Security\Core\SecurityContext;
use Symfony\Component\HttpFoundation\Response;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
use JMS\SecurityExtraBundle\Annotation\Secure;
class AccountController extends Controller
{
/**
* #Route("/login", name="login")
* #Template()
*/
public function loginAction()
{
if ($this->get('request')->attributes->has(SecurityContext::AUTHENTICATION_ERROR)) {
$error = $this->get('request')->attributes->get(SecurityContext::AUTHENTICATION_ERROR);
} else {
$error = $this->get('request')->getSession()->get(SecurityContext::AUTHENTICATION_ERROR);
}
return array(
'last_username' => $this->get('request')->getSession()->get(SecurityContext::LAST_USERNAME),
'error' => $error,
);
}
/**
* #Route("/login_check", name="login_check")
*/
public function securityCheckAction()
{
// The security layer will intercept this request
}
/**
* #Route("/logout", name="logout")
*/
public function logoutAction()
{
// The security layer will intercept this request
}
/**
* #Route("/account/register", name="account_register")
* #Template()
*/
public function registerAction()
{
$form = $this->createForm(new RegistrationType(), new Registration());
return array('form' => $form->createView());
}
/**
* #Route("/account/create", name="account_create")
* #Template()
*/
public function createAction()
{
$em = $this->getDoctrine()->getEntityManager();
$form = $this->createForm(new RegistrationType(), new Registration());
$form->bind($this->getRequest());
if ($form->isValid()) {
$registration = $form->getData();
$user = $registration->getUser();
$factory = $this->get('security.encoder_factory');
$encoder = $factory->getEncoder($user);
$password = $encoder->encodePassword($user->getPassword(), $user->getSalt());
$user->setPassword($password);
$em->persist($user);
$em->flush();
return $this->redirect($this->generateUrl('homepage'));
}
return $this->render('SiriruAntBundle:Account:register.html.twig', array('form' => $form->createView()));
}
}
I need some help =) Thank you.
Try to change your firewall configuration to catch all the urls, then set anonymous: ~ and use access_control to restrict all the urls to ROLE_USER.
The problem is that the security session is not shared by default between different firewalls.
Something like this should work:
security:
encoders:
Siriru\AntBundle\Entity\User: sha512
role_hierarchy:
ROLE_ADMIN: ROLE_USER
ROLE_SUPER_ADMIN: [ROLE_USER, ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH]
providers:
main:
entity: { class: Siriru\AntBundle\Entity\User, property: username }
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
main:
pattern: ^/
anonymous: ~
form_login:
check_path: /login_check
login_path: /login
username_parameter: username
password_parameter: password
logout:
path: /logout
target: /home
access_control:
- { path: ^/$, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/home$, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/register, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/login$, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/, roles: ROLE_USER }

Manual authenticate user

I try to authenticate user:
<?php
/**
* #Route("/testLogin", name="testLogin")
*/
public function testLoginAction()
{
$em = $this->getDoctrine()->getEntityManager();
$user = $em->getRepository('ApplicationDefaultBundle:User')->findOneBy(array('id' => 126));
$providerKey = 'main';
$token = new UsernamePasswordToken($user, null, $providerKey, $user->getRoles());
$this->container->get('security.context')->setToken($token);
return $this->redirect($this->generateUrl('testCheck'));
}
/**
* #Route("/testCheck", name="testCheck")
*/
public function testCheckAction()
{
if (false === $this->get('security.context')->isGranted(
'IS_AUTHENTICATED_REMEMBERED'
)) {
return new Response('Not logged');
}
$user = $this->container->get('security.context')->getToken()->getUser();
return new Response($user->getUsername.' is logged');
}
But I get permanent 302 redirect to /login page.
security:
encoders:
Application\Bundle\DefaultBundle\Entity\User:
algorithm: sha512
iterations: 24
encode_as_base64: true
role_hierarchy:
ROLE_ADMIN: ROLE_USER
ROLE_SPECIALIST: ROLE_USER
ROLE_EMPLOYER: ROLE_USER
ROLE_SUPER_ADMIN: [ROLE_USER, ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH]
providers:
main:
entity: { class: Application\Bundle\DefaultBundle\Entity\User, property: username }
firewalls:
secured_area:
remember_me:
key: MySecretKeyBlablabla
lifetime: 36000000
path: /
domain: ~
pattern: ^/
form_login:
check_path: /login_check
login_path: /login
provider: main
logout:
path: /logout
target: /
anonymous: true
access_control:
- { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
Code for authenticate I take from https://github.com/FriendsOfSymfony/FOSUserBundle/blob/master/Controller/RegistrationController.php
Error in app/logs/dev.log:
redirecting to authentication entry point (No Authentication Provider found for token of class "Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken".) [] []
I can't access to site until I clean cookies.
Try code from this answer. In your case firewall name is secured_area:
// your controller action
public function myAction()
{
// Authenticating user
$token = new UsernamePasswordToken($user, null, 'secured_area', $user->getRoles());
$this->get('security.token_storage')->setToken($token);
//For Symfony <= 2.3
//$this->get('security.context')->setToken($token);
$this->get('session')->set('_security_secured_area', serialize($token));
}
Verify that you have configured encoders section in security.yml, as configuration there has changed not very long time ago and it affects your problem.

Resources