User not logged in, even after `LoginSuccessEvent` fired - authentication

It worked a while back, but I'm having issues backtracking where I went wrong.
I'll give you all the details first:
#security.yaml
security:
password_hashers:
Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface: 'auto'
providers:
users:
entity:
class: 'App\Entity\User'
property: 'username'
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
main:
lazy: true
provider: users
form_login:
login_path: app_login
check_path: app_login
enable_csrf: true
logout:
path: app_logout
access_control:
- { path: ^/admin, roles: ROLE_ADMIN }
- { path: ^/profile, roles: ROLE_USER }
role_hierarchy:
ROLE_ADMIN: ROLE_USER
ROLE_SUPER_ADMIN: [ ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH ]
Pretty basic, here's where it gets messy for me:
controllers:
resource: ../src/Controller/
type: annotation
prefix: /{_locale}
requirements:
_locale: '%app.supported_locales%'
defaults:
_locales: '%app.default_locale%'
middleware: 'locale_middleware'
app_default_locale_redirect:
path: /
methods: GET
controller: App\Controller\DefaultController::defaultLocaleRedirect
defaults:
_locale: '%app.default_locale%'
requirements:
_locale: '^(?!%app.supported_locales%).*'
app_login:
path: /{_locale}/login
app_logout:
path: /{_locale}/logout
methods: GET
I want to redirect all URLs that don't have a supported locale in the URL to the default locale. That's what the middleware is for, and thats why app_login and app_logout both have /{_locale} in their paths. It works as far as I can see.
My default controller handles that using method:
/**
* #Route("/default-locale-redirect")
*/
public function defaultLocaleRedirect(Request $request): RedirectResponse
{
$defaultLocale = $request->getLocale();
return new RedirectResponse($request->getBaseUrl() . '/' . $defaultLocale . '/');
}
I'm also subscribed to the LoginSuccessEvent event, and relevant events:
public static function getSubscribedEvents(): array {
return [
LogoutEvent::class => 'onLogout',
LoginSuccessEvent::class => "onLogin",
LoginFailureEvent::class => "onLoginFailure"
];
}
public function onLogout(LogoutEvent $event): void {
$this->flash->add("success", $this->trans->trans("account.auth.logged_off"));
}
public function onLogin(LoginSuccessEvent $event): void {
$token = $this->tokenStorage->getToken();
$user = $token->getUser();
$roles = $token->getRoleNames();
$this->flash->add("success", $this->trans->trans("account.auth.logged_on"));
}
public function onLoginFailure(LoginFailureEvent $event): void {
$this->flash->add("error", $this->trans->trans("account.auth.failed"));
}
When I place a breakpoint in onLogin, the breakpoint gets hit, and $token, $user and $roles are populated perfectly.
After the page reloads, though, I notice the user is not authenticated. Somehow I believe the token is not persisted. The dev toolbar confirms this, and is_granted("IS_AUTHENTICATED_FULLY") also returns false.
I tried clearing all caches. What am I doing wrong?

Related

Symfony 2.8 generate route 404 not found error

I have created new route for debugging.
created /src/BundleName/Resources/config/routes/default.yml
test_index:
path: /testroutes
defaults: { _controller: BundleName:Test:index }
methods: [GET, POST]
courseflow_backbone_testingroute:
resource: "#BundleName/Resources/config/routes/testing_route.yml"
prefix: /testroute
=====================
created /src/BundleName/Resources/config/routes/testing_route.yml
demo_test:
path: /demotestthing
defaults: { _controller: BundleName:Test:demoTestThing }
methods: [GET, POST]
==================
created /src/BundleName/Controller/TestController.php
namespace BundleName\Controller;
use Symfony\Component\HttpFoundation\Request;
class TestController extends Controller
{
public function indexAction(Request $request)
{
echo "1";die;
}
public function demoTestThingAction(){
echo "12";die;
}
}
=====================
And I have tried to access
http://example.com/testroute/demotestthing
but its getting 404 not found error.
Can you please help me on that.enter code here
Thanks in advance.

How to set scope(or role) of nuxt $auth.user?

I am using nuxt-auth with google oauth2 config, here is my nuxt.config.js config:
auth: {
scopeKey: 'scope',
strategies: {
google: {
client_id: process.env.GOOGLE_KEY,
codeChallengeMethod: '',
scope: ['profile', 'email'],
responseType: 'token id_token'
}
},
redirect: {
login: '/login',
logout: '/logout',
home: '/',
callback: '/welcome'
}
},
router: {
middleware: ['auth']
},
I use this code to login
this.$auth.loginWith('google')
I want to setup a role for user (visit app database) after successful login, so I added this code to my welcome.vue (oauth2 callback page)
<script>
export default {
mounted () {
const user = this.$auth.user
user['scope'] = 'some_role_from_db'
this.$auth.setUser(user)
}
}
</script>
but this code is never called, because application is immediately redirected to the page that user has selected before visiting login page (welcome.vue html markup is shown for 1 sec).
What is the correct way to set some attributes to this.$auth.user immediately after login? Is there some easy way to set role to user after OAUTH2 authentication?
user roles must came from server and it wrong to define it from client side ,
but if that is importent you can do it like that :
this.$auth.loginWith('google').then(() => {
const user = this.$auth.user
user['scope'] = 'some_role_from_db'
this.$auth.setUser(user)
})
I've added this section to my auth object in nuxt.config.js
rewriteRedirects: false
and so my app always redirects me to home url, and on home page I can access auth object like
<script>
export default {
mounted () {
const user = this.$auth.user
user['scope'] = 'some_role_from_db'
this.$auth.setUser(user)
}
}
</script>

reference cognito user pool created by sst (serverless-stack) in serverless.yml

I have quite a big app built with serverless and now we are trying out serverless-stack. I am trying to reference a user pool created by sst in serverless.yml function. Is it possible? Below are the steps I've tried:
I have created a user pool
import * as cdk from '#aws-cdk/core'
import * as cognito from '#aws-cdk/aws-cognito'
import * as sst from '#serverless-stack/resources'
export default class UserServiceStack extends sst.Stack {
constructor(scope: cdk.Construct, id: string, props: sst.StackProps = {}) {
super(scope, id, props)
const userPool = new cognito.UserPool(this, 'userPool', {
signInAliases: {
email: true,
phone: true,
},
autoVerify: {
email: true,
phone: true,
},
passwordPolicy: {
minLength: 8,
requireDigits: false,
requireLowercase: false,
requireSymbols: false,
requireUppercase: false,
},
signInCaseSensitive: false,
selfSignUpEnabled: true,
})
new cdk.CfnOutput(this, 'UserPoolId', {
value: userPool.userPoolId,
})
const userPoolClient = new cognito.UserPoolClient(this, 'userPoolClient', {
userPool,
authFlows: {
adminUserPassword: true,
userPassword: true,
},
})
new cdk.CfnOutput(this, 'UserPoolClientId', {
value: userPoolClient.userPoolClientId,
})
}
}
and want to update my post confirmation trigger defined in serverless.yml
...
createUser:
handler: createUser.default
events:
- cognitoUserPool:
pool: !ImportValue '${self:custom.sstApp}...' # what to put here?
trigger: PostConfirmation
existing: true
Figured it out.
First How to use cdk output variables in serverless.yml.
Export them into a file
AWS_PROFILE=<profile-name> npx sst deploy --outputs-file ./exports.json
and in serverless.yml you can reference it like so
...
createUser:
handler: createUser.default
events:
- cognitoUserPool:
pool: ${file(../../infrastructure/exports.json):${self:custom.sstApp}-UserServiceStack.userPoolName}
trigger: PostConfirmation
existing: true
Second. serverless is setup such that you have to pass userPoolName, not userPoolId. So I had to generate userpool name and output it
import * as uuid from 'uuid'
...
const userPoolName = uuid.v4()
const userPool = new cognito.UserPool(this, 'userPool', {
userPoolName,
...
})
...
// eslint-disable-next-line no-new
new cdk.CfnOutput(this, 'userPoolName', {
value: userPoolName,
})
Third to avoid AccessDeniedException when calling lambda as a trigger you need to add the following to your resources
- Resources:
OnCognitoSignupPermission:
Type: 'AWS::Lambda::Permission'
Properties:
Action: "lambda:InvokeFunction"
FunctionName:
Fn::GetAtt: [ "CreateUserLambdaFunction", "Arn"] # the name must be uppercased name of your lambda + LambdaFunction at the end
Principal: "cognito-idp.amazonaws.com"
SourceArn: ${file(../../infrastructure/exports.json):${self:custom.sstApp}-UserServiceStack.userPoolArn}

Aurelia - Hiding routes in navmenu ends up displaying nothing

I wanted to hide routes that were the user roles and I found THIS question on SO that is similar. I tried to implement it in my typescript project but its returning nothing and I am not sure why.
This is my implementation as it stands.
import { autoinject, bindable, bindingMode } from "aurelia-framework";
import { Router } from 'aurelia-router'
#autoinject
export class Navmenu {
public userName: string = 'anonymous';
private userRole = localStorage.getItem("user_role");
constructor(public authService: AuthService, public router: Router) {
this.userName = authService.getUserName();
console.log("userRole: ", this.userRole);
}
get routes() {
return this.router.navigation.filter(r => r.settings.roles === this.userRole );
}
}
My console.log shows "Admin" in the console but my filter doesnt filter it.
Here is how I have structured a route:
{
route: ["", "scheduler"],
name: "scheduler",
settings: {
icon: "scheduler",
auth: true,
roles: ["Employee", "Admin"], //These are my roles for this route.
pos: "left"
},
moduleId: PLATFORM.moduleName("../components/scheduler/scheduler"),
nav: true,
title: "scheduler"
},
Roles is an array.
How do I structure my filter so that it matches any userRole and thus returns a subset of filtered routes?
Look at this line in your router config:
roles: ["Employee", "Admin"]
Then at this in your getter:
r.settings.roles === this.userRole
roles is an array whereas this.userRole is a string, so the === operator will always return with false. Use indexOf or some instead:
return this.router.navigation.filter(r => r.settings.roles.indexOf(this.userRole) > -1);
or
return this.router.navigation.filter(r => r.settings.roles.some(t => t === this.userRole));

Symfony 3 probleme with authentication

Hi guys i have a probleme with the guard authentication I use symfony 3.1 in my project the guard authentication work fine in my local machine but when i deploy to the server if the authentication succeed i am redirecting to the home page but i loose the authentication and become anonymous again.
Event when i want to register a new user in the deployement it doesnt work the error is bad csrf.
seems like in the deployement the navigator dont send cookies or dont accept them.
I am really confus cause all this work fine in my local server
Really need help.
Thx
security.yml :
security:
encoders:
UserBundle\Entity\User: bcrypt
providers:
database_users:
entity: {class: UserBundle:User, property: mail}
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
main:
anonymous: ~
guard:
authenticators:
- form_login_authenticator
confing.yml :
imports:
- { resource: parameters.yml }
- { resource: security.yml }
- { resource: services.yml }
- { resource: "#VendeurBundle/Resources/config/services.yml" }
- { resource: "#UserBundle/Resources/config/services.yml" }
# Put parameters here that don't need to change on each machine where the app is deployed
# http://symfony.com/doc/current/best_practices/configuration.html#application-related-configuration
parameters:
locale: fr
framework:
#esi: ~
translator: { fallbacks: ["%locale%"] }
secret: "%secret%"
router:
resource: "%kernel.root_dir%/config/routing.yml"
strict_requirements: ~
form: ~
csrf_protection: ~
validation: { enable_annotations: true }
#serializer: { enable_annotations: true }
templating:
engines: ['twig']
default_locale: "%locale%"
trusted_hosts: ~
trusted_proxies: ~
session:
# http://symfony.com/doc/current/reference/configuration/framework.html#handler-id
handler_id: session.handler.native_file
save_path: "%kernel.root_dir%/../var/sessions/%kernel.environment%"
cookie_lifetime: 1000
fragments: ~
http_method_override: true
assets: ~
# Twig Configuration
twig:
debug: "%kernel.debug%"
strict_variables: "%kernel.debug%"
form_themes:
- 'bootstrap_3_horizontal_layout.html.twig'
# Doctrine Configuration
doctrine:
dbal:
driver: pdo_mysql
host: "%database_host%"
port: "%database_port%"
dbname: "%database_name%"
user: "%database_user%"
password: "%database_password%"
charset: UTF8
# if using pdo_sqlite as your database driver:
# 1. add the path in parameters.yml
# e.g. database_path: "%kernel.root_dir%/data/data.db3"
# 2. Uncomment database_path in parameters.yml.dist
# 3. Uncomment next line:
# path: "%database_path%"
orm:
auto_generate_proxy_classes: "%kernel.debug%"
naming_strategy: doctrine.orm.naming_strategy.underscore
auto_mapping: true
# Swiftmailer Configuration
swiftmailer:
transport: "%mailer_transport%"
host: "%mailer_host%"
username: "%mailer_user%"
password: "%mailer_password%"
spool: { type: memory }
stof_doctrine_extensions:
orm:
default:
timestampable: true
white_october_pagerfanta:
exceptions_strategy:
out_of_range_page: ~
not_valid_current_page: ~
Controller :
/**
* #Route("/connexion", name="security_login")
*/
public function loginAction()
{
if ($this->isAuthenticated()) {
return $this->redirectToRoute('homepage');
}
$helper = $this->get('security.authentication_utils');
return $this->render(':connexion:login.html.twig', array(
// last username entered by the user (if any)
'last_username' => $helper->getLastUsername(),
// last authentication error (if any)
'error' => $helper->getLastAuthenticationError(),
));
}
/**
* #Route("/logout", name="logout")
* #Security("is_authenticated()")
*/
public function logoutAction()
{
$this->container->get('security.token_storage')->setToken(null);
return $this->redirectToRoute("homepage");
}
/**
* #Route("/login_check", name="security_login_check")
*/
public function loginCheckAction()
{
// will never be executed
}
Update : I found the probleme the server destroy the session for every request but i dont know how to solve it.