Symfony2 jms/i18n-routing-bundle and security - symfony-2.3

what I'm trying to do :
locale in url except for default locale
whole pages secured except the login page
i18n-routing-bundle
jms_i18n_routing:
default_locale: %locale%
locales: %locales%
#strategy: prefix
strategy: prefix_except_default
Routes
arsf_base_default:
pattern: /
defaults: { _controller: ArsfBaseBundle:Default:index }
arsf_base_homepage:
pattern: /monit/bysector
defaults: { _controller: ArsfMonitBundle:BySector:index }
arsf_base_login:
pattern: /login
defaults: { _controller: ArsfBaseBundle:Default:login }
arsf_base_login_check:
pattern: /login_check
arsf_base_logout:
pattern: /logout
defaults: { _controller: ArsfBaseBundle:Default:logout }
And I tried to configure security.yml as
login:
pattern: ^/|[a-z]+/login$
security: false
anonymous: true
secured_area:
pattern: ^.*$
form_login:
check_path: arsf_base_login_check
login_path: arsf_base_login
default_target_path: arsf_base_homepage
logout:
path: arsf_base_logout
target: arsf_base_login
access_control:
-
path: ^/|[a-z]+/login$
roles: IS_AUTHENTICATED_ANONYMOUSLY
-
path: ^.*$
roles: ROLE_USER
In this case I get error
Unable to find the controller for path "/login_check"
So I tried to remove login firewall and configure secured_area with anonymous: ~
In this case all pages are accessibles without authentication and I've not found better solution than make a test in my layout :
<html>
<head>...</head>
<body>
{% if app.user %}
...
{% else %}
<script>window.location.replace("{{ path('arsf_base_login') }}");</script>
{% endif %}
</body>
</html>
Is there a better way to do ?
What's wrong in my security conf ?

Related

Symfony 4 - authentification 1form 2tables

I would like to know if from the same login form we could connect from two tables: User and Player
Here is my attempt.
security:
encoders:
App\Entity\User:
algorithm: auto
App\Entity\Player:
algorithm: auto
providers:
chain_provider:
chain:
providers: [mon_provider_player, mon_provider_user]
mon_provider_player :
entity:
class: App\Entity\Player
property: email
mon_provider_user :
entity:
class: App\Entity\User
property: email
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
player:
anonymous: lazy
provider: mon_provider_player
form_login:
login_path: login
check_path: login
success_handler: redirect.after.login
logout:
path: logout
target: login
main:
anonymous: lazy
provider: mon_provider_user
form_login:
login_path: login
check_path: login
success_handler: redirect.after.login
logout:
path: logout
target: login
remember_me:
secret: '%kernel.secret%'
lifetime: 604800 # 1 an par défaut
path: /
domain: ~ # Defaults to the current domain from $_SERVER
access_control:
- { path: ^/pol, roles: ["ROLE_POLISTE"] }
- { path: ^/user, roles: ["ROLE_USER"] }
I found the solution. Here to help if needed
Everything happens in the file: loginFormAuthenticator.php which extends AbstractFormLoginAuthenticator in symfony.
There are 5 methods, one of which allows the $user in several tables.
public function getUser($credentials, UserProviderInterface $userProvider)
{
$userFound = $this->userRepository->findOneBy(['email' => $credentials['email']]);
if ($userFound !== NULL) {
return $userFound;
} else {
return $this->playerRepository->findOneBy(['emailJoueur' =>
$credentials['email']]);
}
}

HWIOAuthBundle : No resource owner with name 'check-google'

I installed HWIOAuthBundle.
But I have this error when I try to login with Google Account :
No ressource owner with name 'check-google'.
And I have the same kind of errror with the others API (Facebook, twitter...)
This is my security.yml :
firewalls:
main:
pattern: ^/login$
security: true
anonymous: true
provider: user_provider
form_login:
login_path: fos_user_security_login
check_path: fos_user_security_check
logout:
path: fos_user_security_logout
target: /
oauth:
resource_owners:
facebook: "/login/check-facebook"
google: "/login/check-google"
twitter: "/login/check-twitter"
linkedin: "/login/check-linkedin"
login_path: /login
check_path: /login
failure_path: /login
oauth_user_provider:
#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.)
service: my_user_provider
My routing.yml :
#HWIOAuthBundle routes
hwi_oauth_security:
resource: "#HWIOAuthBundle/Resources/config/routing/login.xml"
prefix: /connect/by
hwi_oauth_connect:
resource: "#HWIOAuthBundle/Resources/config/routing/connect.xml"
prefix: /connect/by
hwi_oauth_redirect:
resource: "#HWIOAuthBundle/Resources/config/routing/redirect.xml"
prefix: /login
facebook_login:
pattern: /login/check-facebook
options: { i18n: false }
google_login:
pattern: /login/check-google
options: { i18n: false }
twitter_login:
pattern: /login/check-twitter
linkedin_login:
pattern: /login/check-linkedin
and my config.yml :
# HWIOAuthBundle
hwi_oauth:
connect:
account_connector: my_user_provider
firewall_name: main
fosub:
username_iterations: 30
properties:
# these properties will be used/redefined later in the custom FOSUBUserProvider service.
facebook: facebook_id
google: google_id
twitter: twitter_id
linkedin: linkedin_id
resource_owners:
facebook:
type: facebook
client_id: xxxxx
client_secret: xxxxx
scope: ""
options:
display: popup
google:
type: google
client_id: xxxx
client_secret: xxxx
scope: "https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile"
twitter:
type: twitter
client_id: xxxx
client_secret: xxxx
scope: ""
linkedin:
type: linkedin
client_id: xxxx
client_secret: xxxx
scope: "r_basicprofile"
services:
hwi_oauth.user.provider.entity:
class: HWI\Bundle\OAuthBundle\Security\Core\User\OAuthUserProvider
cmf_create.persistence.orm.object_mapper:
class: Midgard\CreatePHP\Mapper\DoctrineOrmMapper
arguments:
- "%cmf_create.map%"
- "#doctrine"
My problem is same than No resource owner with name 'google' (HWIOAuthBundle & FOSUserBundle integration). How can i fix this ?
my best bet is that your firewall is not active on "login with *" URLs
try change:
pattern: ^/login$
I personaly use firewall to all URLs:
pattern: ^/
and explicitly set public urls:
access_control:
- { path: ^/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/register, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/resetting, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/admin/, role: ROLE_ADMIN }
- { path: ^/add, role: ROLE_USER }
I have been running into the same issue:
No ressource owner with name 'check-google'.
For me it was solved by changing the routing.yml to this:
google_login:
pattern: /api/login/check/google
I resolved this issue. I found this link helpfull :
http://m2mdas.github.io/blog/2013/11/21/integrate-hwioauthbundle-with-fosuserbundle/
In the above link, After I added cacert.pem to the path, it resolved the issue.
HWIOAuthBundle uses Buzz curl client to communicate with web services. Buzz by default enables SSL certificate check. On some server CA certificate information may not exist. To add CA certificate info download cacert.pem from this page and set curl.cainfo php ini variable to the location of cacert.pem e.g
curl.cainfo = /path/to/cacert.pem
and I missed the above step.
Regards,
Mk6ix

Symfony 2.2 - bad redirect after login in dev environment

After setting up Symfony2.2, I have the following code in my login form:
<input type="hidden" name="_target_path" value="{{path('rok_admin_default_index')}}"/>
Where rok_admin_default_index is pointing to "/" so it's basically the homepage of the application. During the development I'm using app_dev.php (which I obviously), but after successful login in dev environment Symfony redirects me to domain.com/app_dev.php/app_dev.php/ instead of domain.com/app_dev.php/
My security.yml:
jms_security_extra:
secure_all_services: false
expressions: true
security:
encoders:
ROK\AdminBundle\Entity\User: sha512
role_hierarchy:
ROLE_MOD: ROLE_USER
ROLE_ADMIN: [ROLE_MOD, ROLE_USER]
ROLE_SUPER_ADMIN: [ROLE_USER, ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH]
providers:
main:
entity: { class: ROK\AdminBundle\Entity\User, property: email }
in_memory:
memory:
users:
user: { password: userpass, roles: [ 'ROLE_USER' ] }
mod: {password: modpass, roles: ['ROLE_MOD']}
admin: { password: adminpass, roles: [ 'ROLE_ADMIN' ] }
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
login:
pattern: ^/login$
security: false
secured_area:
pattern: ^/admin/
form_login:
check_path: login_check
login_path: login
logout: ~
#anonymous: ~
#http_basic:
# realm: "Secured Demo Area"
access_control:
- { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/admin, roles: ROLE_ADMIN}
The symfony2 documentation says
The value attribute can be a relative path, absolute URL, or a route
name.
So we can try the second and third options
Use absolute path
<input type="hidden" name="_target_path" value="{{url('rok_admin_default_index')}}"/>
Or Use route name
<input type="hidden" name="_target_path" value="rok_admin_default_index"/>

Service not triggered : The controller must return a response (null given)

Hi everyone and huge thanks for the help,
I am trying to get FOSFacebook work, but it seems to be impossible until now.
I tried a lot of configuration, and a lot of fix but nothing worked for me.
Here is my configuration :
security.yml
chain_provider:
chain:
providers: [fos_userbundle, fos_facebook_provider]
fos_userbundle:
id: fos_user.user_provider.username
fos_facebook_provider:
id: fos.facebook.custom_provider
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
main:
pattern: ^/
form_login:
login_path: fos_user_security_login
check_path: fos_user_security_check
provider: fos_userbundle
csrf_provider: form.csrf_provider
logout: true
anonymous: true
public:
pattern: ^/
fos_facebook:
app_url: "http://apps.facebook.com/myApp/"
server_url: "http://www.mywebsite.com"
login_path: /facebook/login
check_path: /facebook/check
default_target_path: /
provider: fos_facebook_provider
anonymous: false
logout:
handlers: ["fos_facebook.logout_handler"]
config.yml
fos.facebook.custom_provider:
class: Bundles\UserBundle\Security\User\Provider\FacebookProvider
arguments:
facebook: "#fos_facebook.api"
userManager: "#fos_user.user_manager"
validator: "#validator"
container: "#service_container"
fos_facebook:
file: %kernel.root_dir%/../vendor/facebook/php-sdk/src/base_facebook.php
alias: facebook
app_id: myid
secret: mysecret
cookie: true
permissions: [email]
routing.yml
_security_check:
pattern: /facebook/check
_security_logout:
pattern: /logout
Twig Template
<script type="text/javascript">
function goLogIn(){
window.location.href = "{{ path('_security_check') }}";
}
function onFbInit() {
if (typeof(FB) != 'undefined' && FB != null ) {
FB.Event.subscribe('auth.statusChange', function(response) {
if (response.session || response.authResponse) {
setTimeout(goLogIn, 500);
} else {
window.location.href = "{{ path('_security_logout') }}";
}
});
}
}
</script>
{{ facebook_initialize({'xfbml': true, 'fbAsyncInit': 'onFbInit();'}) }}
UserController.php
* #Route("/facebook/check")
*/
public function loginCheckFacebookAction(){
}
And the provider and the modification to User class (as in the Readme).
But the problem is that the service not seemed to be called. Indeed, the method in the UserController must be a dummy method, and it is not like that here.
The method is called and of course I get this error :
LogicException: The controller must return a response (null given). Did you forget to add a return statement somewhere in your controller? (uncaught exception).
What is my error here ?
Remove your UserController route/action loginCheckFacebookAction

FOSFacebookBundle works, but FOSUserBundle does not seem to work

I can login with FOSFacebookBundle and everything works. But, FOSUserBundle does not seem to work because profiler shows Username: anon and Roles: {}. And, there is no user data about logged in user in database. Maybe, I didn't understand how it works. Please, help.
This is my config.yml
fos_user:
db_driver: orm # other valid values are 'mongodb', 'couchdb' and 'propel'
firewall_name: public
user_class: Trade\TradeBundle\Entity\User
fos_facebook:
file: %kernel.root_dir%/../vendor/facebook/src/base_facebook.php
alias: facebook
app_id: my_app_id
secret: app_secret_key
cookie: true
permissions: [user_about_me]
services:
fos_facebook.auth:
class: Trade\TradeBundle\Security\User\Provider\FacebookProvider
arguments:
facebook: "#fos_facebook.api"
userManager: "#fos_user.user_manager"
validator: "#validator"
container: "#service_container"
This is my security.yml
security:
factories:
- "%kernel.root_dir%/../vendor/bundles/FOS/FacebookBundle/Resources/config/security_factories.xml"
role_hierarchy:
ROLE_ADMIN: ROLE_FACEBOOK
ROLE_SUPER_ADMIN: ROLE_ADMIN
providers:
my_fos_facebook:
id: fos_facebook.auth
firewalls:
public:
pattern: ^/.*
fos_facebook:
app_url: "app_url"
server_url: "server_url"
login_path: /user/login
check_path: /user/login_check
default_target_path: /
provider: my_fos_facebook
anonymous: true
logout:
handlers: ["fos_facebook.logout_handler"]
The code below does not seem to work because when I log in with facebook setTimeout(goLogIn, 500) function inside if is not called.
function goLogIn(){
window.location.href = "{{ path('user_login_check') }}";
}
function onFbInit() {
if (typeof(FB) != 'undefined' && FB != null ) {
FB.Event.subscribe('auth.statusChange', function(response) {
if (response.session || response.authResponse) {
setTimeout(goLogIn, 500);
} else {
window.location.href = "{{ path('_security_logout') }}";
}
});
}
}
These are my controller actions:
/**
* #Route("/user/login", name = "user_login")
*/
public function loginAction()
{
}
/**
* #Route("/user/login_check", name = "user_login_check")
*/
public function loginCheckAction()
{
}
In order for FOSUserBundle to work together with FOSFacebookBundle, you need to specify a specific login route just for the facebook login at security.yml:
public:
fos_facebook:
check_path: /loginFacebook
Of course you are going to need to point that route correctly at routing.yml:
_security_check:
pattern: /loginFacebook
Then you need to change the check URL on the facebook javascript:
function goLogIn(){
window.location.href = "{{ path('_security_check') }}";
}
The last thing is to create the controller and the action for the new route (this is very important, otherwise it's not going to work) and leave it empty:
public function loginFacebookAction()
{
return array();
}
Of course you are going to need to adapt this to your needs, like where I use the DefaultController, you, apperantly, use the UserController.
Hope it helps.
I would guess you are storing empty data because of your permissions request:
permissions: [user_about_me]
I suggest changing to the tutorial recommended:
permissions: [email, user_birthday, user_location]