symfony LexikJWTAuthenticationBundle bad credential - api

I want to integrate LexikJWTAuthenticationBundle of symfony with fosUserBundle , I've follow the instructions here but always I receive 401 bad credentials error .
here is my config.yml file :
imports:
- { resource: parameters.yml }
- { resource: security.yml }
- { resource: services.yml }
# Put parameters here that don't need to change on each machine where the app is deployed
# https://symfony.com/doc/current/best_practices/configuration.html#application-related-configuration
parameters:
locale: en
framework:
#esi: ~
#translator: { fallbacks: ['%locale%'] }
translator: ~
secret: '%secret%'
router:
resource: '%kernel.project_dir%/app/config/routing.yml'
strict_requirements: ~
form: ~
csrf_protection: ~
validation: { enable_annotations: true }
#serializer: { enable_annotations: true }
templating:
engines: ['twig']
default_locale: '%locale%'
trusted_hosts: ~
session:
# https://symfony.com/doc/current/reference/configuration/framework.html#handler-id
handler_id: session.handler.native_file
save_path: '%kernel.project_dir%/var/sessions/%kernel.environment%'
fragments: ~
http_method_override: true
assets: ~
php_errors:
log: true
serializer:
enabled: true
# Twig Configuration
twig:
debug: '%kernel.debug%'
strict_variables: '%kernel.debug%'
# Doctrine Configuration
doctrine:
dbal:
driver: pdo_mysql
host: '%database_host%'
port: '%database_port%'
dbname: '%database_name%'
user: '%database_user%'
password: '%database_password%'
charset: UTF8
mapping_types:
enum: string
# if using pdo_sqlite as your database driver:
# 1. add the path in parameters.yml
# e.g. database_path: "%kernel.project_dir%/var/data/data.sqlite"
# 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 }
fos_user:
db_driver: orm # other valid values are 'mongodb', 'couchdb' and 'propel'
firewall_name: main
user_class: AppBundle\Entity\Collaborator
from_email:
address: sahnoun.mabrouk#gmail.com
sender_name: sahnoun MABROUK
# Nelmio CORS Configuration
nelmio_cors:
defaults:
allow_credentials: false
allow_origin: ['*']
allow_headers: ['*']
allow_methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS']
max_age: 3600
hosts: []
origin_regex: false
fos_rest:
serializer:
serialize_null: true
routing_loader:
include_format: false
view:
view_response_listener: true
format_listener:
rules:
- { path: '^/', priorities: ['json'], fallback_format: 'json' }
- { path: '^/login', priorities: ['html'], fallback_format: 'html' }
- { path: '^/register', priorities: ['html'], fallback_format: 'html' }
- { path: '^/resetting', priorities: ['html'], fallback_format: 'html' }
lexik_jwt_authentication:
private_key_path: '%jwt_private_key_path%'
public_key_path: '%jwt_public_key_path%'
pass_phrase: '%jwt_key_pass_phrase%'
token_ttl: '%jwt_token_ttl%'
security.yml :
# To get started with security, check out the documentation:
# https://symfony.com/doc/current/security.html
security:
# https://symfony.com/doc/current/security.html#b-configuring-how-users-are-loaded
providers:
in_memory:
memory: ~
fos_userbundle:
id: fos_user.user_provider.username
encoders:
FOS\UserBundle\Model\UserInterface: bcrypt
role_hierarchy:
ROLE_ADMIN: ROLE_USER
ROLE_SUPER_ADMIN: ROLE_ADMIN
firewalls:
login:
pattern: ^/api/login
stateless: true
anonymous: true
form_login:
check_path: /api/login_check
success_handler: lexik_jwt_authentication.handler.authentication_success
failure_handler: lexik_jwt_authentication.handler.authentication_failure
require_previous_session: false
api:
pattern: ^/api
stateless: true
guard:
authenticators:
- lexik_jwt_authentication.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
main:
anonymous: ~
pattern: ^/
logout: true
form_login:
provider: fos_userbundle
csrf_token_generator: security.csrf.token_manager
logout: true
anonymous: true
# activate different ways to authenticate
# https://symfony.com/doc/current/security.html#a-configuring-how-your-users-will-authenticate
#http_basic: ~
# https://symfony.com/doc/current/security/form_login_setup.html
#form_login: ~
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: ^/api/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/api, roles: IS_AUTHENTICATED_FULLY }
and i've added api_login_check:
path: /api/login_check to the route file.
I've read all issues related to this error but nothing work for me.
can any one help me please

You are missing the respective providers for each route, take a look here.
security:
firewalls:
login:
...
provider: in_memory
...
api:
...
provider: jwt
...

problem solved ! just make fos_userbundle as first provider to check credentials from database
security:
providers:
fos_userbundle:
id: fos_user.user_provider.username
in_memory:
memory: ~
...

Related

Istio virtual service header rules are not applied

So I have a very unique situation.
Problem
Virtual services route rules are not applied. We have a buzzfeed sso setup in our cluster. We wand to modify response headers to i.e Add header. to each request that matches the uri sign_in.
Buzzfeed sso has its own namespace.
Now To accomplish this I have created a virtual service.
Steps to Reproduce:
We used this virtual service spec to create the route rules.
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: sso-auth-injector
spec:
hosts:
- sso-auth
http:
- match:
- uri:
prefix: /sign_in
ignoreUriCase: true
route:
- destination:
host: sso-auth
headers:
response:
add:
foo: bar
request:
add:
hello: world
Analysis
Istioctk x describe has output
Pod: sso-auth-58744b56cd-lwqrh.sso
Pod Ports: 4180 (sso-auth), 15090 (istio-proxy)
Suggestion: add ‘app’ label to pod for Istio telemetry.
Suggestion: add ‘version’ label to pod for Istio telemetry.
Service: sso-auth.sso
Port: http 80/HTTP targets pod port 4180
Pod is PERMISSIVE (enforces HTTP/mTLS) and clients speak HTTP
VirtualService: sso-auth-injector.sso
/sign_in uncased
2) Istioctl . Not attaching all the rules but for outbound|80|
"routes": [
{
"match": {
"prefix": "/sign_in",
"caseSensitive": false
},
"route": {
"cluster": "outbound|80||sso-auth.sso.svc.cluster.local",
"timeout": "0s",
"retryPolicy": {
"retryOn": "connect-failure,refused-stream,unavailable,cancelled,resource-exhausted,retriable-status-codes",
"numRetries": 2,
"retryHostPredicate": [
{
"name": "envoy.retry_host_predicates.previous_hosts"
}
],
"hostSelectionRetryMaxAttempts": "5",
"retriableStatusCodes": [
503
]
},
"maxGrpcTimeout": "0s"
},
"metadata": {
"filterMetadata": {
"istio": {
"config": "/apis/networking/v1alpha3/namespaces/sso/virtual-service/sso-auth-injector"
}
}
},
"decorator": {
"operation": "sso-auth.sso.svc.cluster.local:80/sign_in*"
},
"typedPerFilterConfig": {
"mixer": {
"#type": "type.googleapis.com/istio.mixer.v1.config.client.ServiceConfig",
"disableCheckCalls": true,
"mixerAttributes": {
"attributes": {
"destination.service.host": {
"stringValue": "sso-auth.sso.svc.cluster.local"
},
"destination.service.name": {
"stringValue": "sso-auth"
},
"destination.service.namespace": {
"stringValue": "sso"
},
"destination.service.uid": {
"stringValue": "istio://sso/services/sso-auth"
}
}
},
"forwardAttributes": {
"attributes": {
"destination.service.host": {
"stringValue": "sso-auth.sso.svc.cluster.local"
},
"destination.service.name": {
"stringValue": "sso-auth"
},
"destination.service.namespace": {
"stringValue": "sso"
},
"destination.service.uid": {
"stringValue": "istio://sso/services/sso-auth"
}
}
}
}
},
"requestHeadersToAdd": [
{
"header": {
"key": "hello",
"value": "world"
},
"append": true
}
],
"responseHeadersToAdd": [
{
"header": {
"key": "foo",
"value": "bar"
},
"append": true
}
]
}
]
},
Issues/Questions
These rules dont take affect. Each request is passed to the service but headers are not modified.
Shouldnt the route rules be applicable to inbound requests as opposed to outbound (as shown in config generated).
We want to modify response headers to i.e Add header. to each request that matches the uri sign_in
I made an example, tested it and everything works just fine.
Check below vs, tests and whole example.
Virtual service
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: nginxvirt
spec:
gateways:
- mesh
hosts:
- nginx.default.svc.cluster.local
http:
- name: match
headers:
response:
add:
foo: "bar"
match:
- uri:
prefix: /sign_in
rewrite:
uri: /
route:
- destination:
host: nginx.default.svc.cluster.local
port:
number: 80
subset: v1
Everything you need for test
apiVersion: v1
kind: Pod
metadata:
name: ubu1
spec:
containers:
- name: ubu1
image: ubuntu
command: ["/bin/sh"]
args: ["-c", "apt-get update && apt-get install curl -y && sleep 3000"]
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx1
spec:
selector:
matchLabels:
run: nginx1
replicas: 1
template:
metadata:
labels:
run: nginx1
app: frontend
spec:
containers:
- name: nginx1
image: nginx
ports:
- containerPort: 80
lifecycle:
postStart:
exec:
command: ["/bin/sh", "-c", "echo Hello nginx1 > /usr/share/nginx/html/index.html"]
---
apiVersion: v1
kind: Service
metadata:
name: nginx
labels:
app: frontend
spec:
ports:
- port: 80
protocol: TCP
selector:
app: frontend
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: nginxvirt
spec:
gateways:
- mesh
hosts:
- nginx.default.svc.cluster.local
http:
- name: match
headers:
response:
add:
foo: "bar"
match:
- uri:
prefix: /sign_in
rewrite:
uri: /
route:
- destination:
host: nginx.default.svc.cluster.local
port:
number: 80
subset: v1
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: nginxdest
spec:
host: nginx.default.svc.cluster.local
subsets:
- name: v1
labels:
run: nginx1
Test from ubuntu pod
I used curl -I for displaying response headers
curl -I nginx/sign_in
HTTP/1.1 200 OK
server: envoy
date: Tue, 24 Mar 2020 07:44:10 GMT
content-type: text/html
content-length: 13
last-modified: Thu, 12 Mar 2020 06:52:43 GMT
etag: "5e69dc3b-d"
accept-ranges: bytes
x-envoy-upstream-service-time: 3
foo: bar
As you can see the foo:bar header is added correctly.
Additional links for headers
https://istiobyexample.dev/response-headers/
Istio adds and removed headers, but doesn't overwrite
How to display request headers with command line curl
In your istioctl analyze I see you might have an 503 error
"retriableStatusCodes": [
503
]
Additional links for 503 eror
https://istio.io/docs/ops/best-practices/traffic-management/#avoid-503-errors-while-reconfiguring-service-routes
https://istio.io/docs/ops/common-problems/network-issues/#503-errors-after-setting-destination-rule
Accessing service using istio ingress gives 503 error when mTLS is enabled

Symfony & Api Unlock Route

I am facing a problem and I do not know how to solve it.
So, I build an API with the "FOSRESTBundle" and I use "lexik_jwt_bundle" to get a token.
But now, he asks me the token for each route of my API while I want there to be route accessible without the token.
How can I please?
Here is my security.yaml :
security:
encoders:
App\Entity\User:
algorithm: argon2i
# https://symfony.com/doc/current/security.html#where-do-users-come-from-user-providers
providers:
# used to reload user from session & other features (e.g. switch_user)
app_user_provider:
entity:
class: App\Entity\User
property: email
# used to reload user from session & other features (e.g. switch_user)
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
login:
pattern: ^/api/login
stateless: true
anonymous: true
json_login:
check_path: /api/login_check
success_handler: lexik_jwt_authentication.handler.authentication_success
failure_handler: lexik_jwt_authentication.handler.authentication_failure
api:
pattern: ^/api
stateless: true
guard:
authenticators:
- lexik_jwt_authentication.jwt_token_authenticator
vehicule:
pattern: ^/api/vehicules
stateless: true
anonymous: true
lexik_jwt:
authorization_header:
enabled: false
prefix: Bearer
main:
anonymous: true
# activate different ways to authenticate
# https://symfony.com/doc/current/security.html#firewalls-authentication
# https://symfony.com/doc/current/security/impersonating_user.html
# switch_user: true
# Easy way to control access for large sections of your site
# Note: Only the *first* access control that matches will be used
access_control:
- { path: ^/api/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/api, roles: IS_AUTHENTICATED_FULLY }
- { path: ^/api/vehicule, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/api/vehicules, roles: IS_AUTHENTICATED_ANONYMOUSLY }
# - { path: ^/admin, roles: ROLE_ADMIN }
# - { path: ^/profile, roles: ROLE_USER }
your order is wrong both in access_control and firewalls section:
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
login:
pattern: ^/api/login
stateless: true
anonymous: true
json_login:
check_path: /api/login_check
success_handler: lexik_jwt_authentication.handler.authentication_success
failure_handler: lexik_jwt_authentication.handler.authentication_failure
vehicule:
pattern: ^/api/vehicules
stateless: true
anonymous: true
lexik_jwt:
authorization_header:
enabled: false
prefix: Bearer
api:
pattern: ^/api
stateless: true
guard:
authenticators:
- lexik_jwt_authentication.jwt_token_authenticator
main:
anonymous: true
# activate different ways to authenticate
# https://symfony.com/doc/current/security.html#firewalls-authentication
# https://symfony.com/doc/current/security/impersonating_user.html
# switch_user: true
# Easy way to control access for large sections of your site
# Note: Only the *first* access control that matches will be used
access_control:
- { path: ^/api/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/api/vehicule, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/api/vehicules, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/api, roles: IS_AUTHENTICATED_FULLY }
# - { path: ^/admin, roles: ROLE_ADMIN }
# - { path: ^/profile, roles: ROLE_USER }

LexikJWTAuthenticationBundle - How to grant different access to different path's?

I am using LexikJWTAuthenticationBundle to authenticate in my web-application using REST Webservice.
I want to divide my application into two sections:
a public section, where everyone could see the content - without login
a private section, where you have to be logged in to edit content, users
and so on.
The idea is, to do this via url:
/api #reach the public content of the website
/api/admin #reach private admin content, if not logged in -> loginpage
I tried this in the security.yaml:
access_control:
- { path: ^/api, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/api/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/api/admin, roles: IS_AUTHENTICATED_FULLY }
But when i try to load the content like this:
curl -X GET <baseurl-backend>/api/content/list #generic example
I get:
{code: 401, message: "JWT Token not found"}
Here's the security.yaml with all the configuration:
security:
encoders:
App\Entity\User:
algorithm: argon2i
providers:
app_user_provider:
entity:
class: App\Entity\User
property: email
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
login:
pattern: ^/api/login
stateless: true
anonymous: true
json_login:
check_path: /api/login_check #path for checking
success_handler: lexik_jwt_authentication.handler.authentication_success
failure_handler: lexik_jwt_authentication.handler.authentication_failure
api:
pattern: ^/api
stateless: true
guard:
authenticators:
- lexik_jwt_authentication.jwt_token_authenticator
main:
anonymous: true
access_control:
- { path: ^/api, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/api/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/api/admin, roles: IS_AUTHENTICATED_FULLY }
Thank you for your help!
you should add anonymous: true to your api firewall.
api:
pattern: ^/api
stateless: true
anonymous: true
guard:
authenticators:
- lexik_jwt_authentication.jwt_token_authenticator
if you want to block access to api/admin you should add another firewall on top of your api firewall:
api_admin:
pattern: ^/api/admin
stateless: true
guard:
authenticators:
- lexik_jwt_authentication.jwt_token_authenticator
api:
pattern: ^/api
stateless: true
anonymous: true
guard:
authenticators:
- lexik_jwt_authentication.jwt_token_authenticator

Symfony 3.4.18 + FosUserBundle 2.0 + LexikJWT

I want to to configure LexikJWT with fosuserbunle 2.0 but i receive with postman this always
security:
encoders:
FOS\UserBundle\Model\UserInterface: bcrypt
role_hierarchy:
ROLE_ADMIN: ROLE_USER
ROLE_SUPER_ADMIN: ROLE_ADMIN
providers:
fos_userbundle:
id: fos_user.user_provider.username
firewalls:
login:
pattern: ^/api/login
stateless: true
anonymous: 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
api:
pattern: ^/api
provider: fos_userbundle
stateless: true
guard:
authenticators:
- lexik_jwt_authentication.jwt_token_authenticator
main:
pattern: ^/
form_login:
provider: fos_userbundle
csrf_token_generator: security.csrf.token_manager
# if you are using Symfony < 2.8, use the following config instead:
# csrf_provider: form.csrf_provider
logout: true
anonymous: true
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: ^/api/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/api, roles: IS_AUTHENTICATED_FULLY }
i want to work symfony / FosuserBundle with angular 6 i have choosen LexikJWT.
any help please and if someone have a toturial about symfony3/4 and angular 6 you can give it to me please
thank you
You need to change your
username_parameter: username
password_parameter: password
to
username_parameter: _username
password_parameter: _password

Symfony2: Token was not found in the SecurityContext

A firewall that should allow anonymous connection to a URL is instead requiring authentication. For example, /reports/foodbank/2013/10 should simply provide a set of values rather than require login. Syntax error?
security.yml includes:
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
foodbank:
pattern: ^/reports/foodbank/~
anonymous: ~
login_firewall:
pattern: ^/login$
anonymous: ~
secured_area:
pattern: ^/
form_login:
default_target_path: /home
use_referer: true
logout:
target: /login
access_control:
- { path: ^/reports/foodbank/~, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/, roles: ROLE_USER }
A return visit to the documentation revealed paths are regex expressions, something with which I am (unfortunately) only vaguely familiar. But the following modifications made it work:
foodbank:
pattern: ^/reports/foodbank/*
anonymous: ~
and
access_control:
- { path: ^/reports/foodbank/*, roles: IS_AUTHENTICATED_ANONYMOUSLY }