Custom UserProvider config symfony 4 - symfony

I would like to create my own LdapUserProvider to apply different role regarding the username.
Accutally my LDAP works really good with the default LdapUserProvider from symfony.
As the LDAP doc say :
The ldap user provider, using the LdapUserProvider class. Like all other user providers, it can be used with any authentication provider.
How can I do to use a customized User provider please?
security:
providers:
my_ldap:
ldap:
service: Symfony\Component\Ldap\Ldap
base_dn: o=xxx
search_dn: cn=xxx Downloader,ou=ApplicationUsers,o=xxx
search_password: 'xxx'
default_roles: [ROLE_USER]
uid_key: uid
filter: "{uid_key}={username}"
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
main:
anonymous: true
# provider: App\Services\MyLdapUserProvider
logout:
csrf_token_id: logout
path: /logout
target: /login
form_login_ldap:
csrf_parameter: _csrf_token
login_path: login
check_path: login
service: Symfony\Component\Ldap\Ldap
dn_string: 'o=xxx'
query_string: 'uid={username}'
target_path_parameter: home
default_target_path: /home
access_control:
- { path: /index, role: IS_AUTHENTICATED_FULLY }
- { path: ^/admin, roles: ROLE_ADMIN }
Edit:
Thank you for your answer #Vyctorya
I think this is what I need!
In security.yaml this is how I call the service:
security:
providers:
myLdap:
id: App\Services\MyLdapUserProvider
and this is my service.yaml:
services:
App\Services\MyLdapUserProvider:
arguments:
$ldap: '#Symfony\Component\Ldap\LdapInterface'
$baseDn: 'o=xxx'
$searchDn: 'cn=xxx Downloader,ou=ApplicationUsers,o=xxx'
$searchPassword: 'xxx'
$defaultRoles:
'ROLE_USER'
$uidKey: 'uid'
$filter: '{uid_key}={username}'
Symfony\Component\Ldap\LdapInterface:
arguments: ['#Symfony\Component\Ldap\Adapter\ExtLdap\Adapter']
Symfony\Component\Ldap\Adapter\ExtLdap\Adapter:
arguments:
- host: ....
I don't uderstand why baseDn is not defined...
Cannot autowire service "App\Services\MyLdapUserProvider": argument "$baseDn" of method "Symfony\Component\Security\Core\User\LdapUserProvider::__construct()" is type-hinted "string", you should configure its value explicitly.

Look at this Symfony Documentation.
You need to adjust your configuration:
security:
providers:
enter_you_custom_name_here:
id: AppBundle\Security\User\UserProvider
and create the UserProvider. Extend Symfony\Component\Security\Core\User\LdapUserProvider and override loadUserByUsername($username)

Related

API Platform - Swagger UI with JWT Authentication

I'd like to add the "Authorize" button on Swagger, like described here : https://api-platform.com/docs/core/jwt#documenting-the-authentication-mechanism-with-swaggeropen-api
I installed LexikJWTAuthenticationBundle, it works fine with Curl. But when I browse to http://localhost:8000/api, I only see {"code":401,"message":"JWT Token not found"}.
Am I missing something?
Here's my security.yaml:
security:
encoders:
App\Entity\User:
algorithm: bcrypt
providers:
db_provider:
entity:
class: App\Entity\User
property: username
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
api_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
main:
pattern: ^/
anonymous: ~
provider: db_provider
form_login:
login_path: app_security_login
check_path: app_security_login
csrf_token_generator: security.csrf.token_manager
logout:
path: /logout
target: /
remember_me:
secret: '%kernel.secret%'
lifetime: 604800
path: /
access_control:
- { path: ^/admin, roles: ROLE_ADMIN }
- { path: ^/api/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/api, roles: IS_AUTHENTICATED_FULLY }
- { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/register, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/, roles: ROLE_USER }
role_hierarchy:
ROLE_ADMIN: ROLE_USER
ROLE_SUPER_ADMIN: [ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH]
access_decision_manager:
strategy: unanimous
And my api_platform.yaml:
api_platform:
title: 'My project'
version: '0.0.1'
mapping:
paths: ['%kernel.project_dir%/src/Entity']
swagger:
api_keys:
apiKey:
name: Authorization
type: header
Bit late to this, but I faced this same issue. Your security configuration is stating that any route beginning with /api requires authentication, which includes /api itself. If you want to keep the documentation on the /api route, add a trailing slash to the security configuration;
firewalls:
...
api:
pattern: ^/api/
and
access_control:
- { path: ^/api/, roles: IS_AUTHENTICATED_FULLY }
This will leave /api as publicly accessible, whilst requiring a valid token to be provided for /api/*.
Alternatively, you can leave the security configuration as it is and move the documentation to a different URL (e.g. /docs). For this, you may need to add /docs as an IS_AUTHENTICATED_ANONYMOUSLY path under access_control depending on your other rules.
Then when the documentation page is accessible, click the Authorize button at the top of the page and enter Bearer <valid JWT token>.
It's old but here is the solution in 2021
You have to decorate open api factory
Edit :
Don't put hyphen (-) in the name of the authorization and in the scheme key otherwise it won't work (probably other special characters)
In config/packages/api_platform.yaml :
swagger:
versions: [3]
api_keys:
JWT: // The name of the authorization to display on swagger UI
name: Authorization
type: header
In config/services.yaml :
App\OpenApi\JwtDecorator:
decorates: 'api_platform.openapi.factory'
arguments: [ '#App\OpenApi\JwtDecorator.inner' ]
autoconfigure: false
enter code here
The decorating service : in OpenApi\JwtDecorator
class JwtDecorator implements OpenApiFactoryInterface
{
public function __construct(
private OpenApiFactoryInterface $decorated
) {}
public function __invoke(array $context = []): \ApiPlatform\Core\OpenApi\OpenApi
{
$openApi = ($this->decorated)($context);
$schemas = $openApi->getComponents()->getSecuritySchemes();
$schemas['JWT'] = new \ArrayObject([
'type' => 'http',
'scheme' => 'bearer',
'bearerFormat' => 'JWT'
]);
return $openApi;
}
}
I could fix my problem. In my case problem was, in public and private openssl keys. First I fixed it, the second, problem was in encoding. I used the source below to achieve result. Just take a look to link below
LexikJWTAuthenticationBundleSandbox

Checking a user's password on Ldap with dynamic dn in symfony 3

With sf3
symfony 3 password can be checked but with a static dn
dn_string: 'uid={username},dc=example,dc=com'
So I created my own UserAuthenticationProvider class
But now I don't know how to declare it in my security.yml ?
security.yml
providers:
your_db_provider:
entity:
class: AcSecurityBundle:User
property: username
fos_userbundle:
id: fos_user.user_provider.username
secured_area:
pattern: ^/
anonymous: true
provider: your_db_provider
form_login:
csrf_token_generator: security.csrf.token_manager
use_referer: true
form_login_ldap:
service: ldap
use_referer: true
logout: true
AcSecurityBundle/AcUserAuthenticationProvider.php
class AcUserAuthenticationProvider extends UserAuthenticationProvider
{
function checkAuthentication(UserInterface $user, UsernamePasswordToken $token)
{
$username = $token->getUsername();
$password = $token->getCredentials();
if ('' === $password) {
throw new BadCredentialsException('The presented password must not be empty.');
}
try {
$query = "(sAMAccountName=$username)";
$search_dn = "CN=app,OU=apps,DC=domain,DC=be";
$search_password = "mdp";
$this->ldap->bind($search_dn, $search_password);
$t = $this->ldap->query("OU=At,OU=user,DC=domain,DC=be", $query);
$entry = $t->execute();
if ($entry->count() > 0) {
$dn = $entry[0]->getDn();
}
$this->ldap->bind($dn, $password);
} catch (ConnectionException $e) {
throw new BadCredentialsException('The presented password is invalid.');
}
}
}
Thank you
Since Symfony 3.1 Symfony uses a new ldap provider
Symfony\Component\Ldap\Ldap
Provider Example:
services:
app.ldap:
class: Symfony\Component\Ldap\Ldap
factory: [ 'Symfony\Component\Ldap\Ldap', 'create']
arguments:
- ext_ldap
- host: srv-host
#debug: true
The string associated to the adapter you wish to use. Only one is
supported for now, which is ext_ldap.
New Ldap provider by Symfony, explained.
Security Provider Example:
providers:
#webservice_provider:
#id: app.webservice_user_provider
company_ldap:
ldap:
service: app.ldap
base_dn: DC=example, DC=local
search_dn: "CN=AdminName,OU=YourAdminGroup,DC=example,DC=LOCAL"
search_password: 'AdminPass'
default_roles: ROLE_USER
Now you are allowed to look in your ldap system. If you set your
form_login_ldap right, your users can authenticate via your form
Security form_login_ldap Example:
form_login_ldap:
provider: company_ldap
service: app.ldap #system/provider your user authenticate to
dn_string: '{username}#example.local'
csrf_token_generator: security.csrf.token_manager
check_path: /login_check #make sure the check is behind the firewall
login_path: /login #make sure login IS_AUTHENTICATED_ANONYMOUSLY
logout:
path: /logout #logout path
target: /login #after logout redirect to login
anonymous: true
Access_control/firewall Example:
access_control:
- { path: ^/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/admin/, role: ROLE_ADMIN }
- { path: ^/, role: ROLE_USER } #all pages require user to be logged in
Now you have your dynamic ldap login form.
Symfony login form setup.
Hope this helps you. Took me 8 days to figure this out by myself.
You don't need to do any of the above. You can use the DN string as:
dn_string: '{username}'
That's actually the default value according to the docs.This will work because AD supports several bind methods in addition to a full DN (such as the sAMAccountName or UPN).

Symfony2 Aimeos admin site login gives error

I installed the Aimeos 2016 bundle on Symfony 3.1.2. The /list route works but when I go to /admin and try to log in, I get an error:
Unable to find the controller for path "/admin_check". The route is wrongly configured.
I did not do anything else to the code.
Any help would be appreciated!
Did you've set up Symfony authentication exactly like in the example?
security:
providers:
admin:
memory:
users:
admin: { password: secret, roles: [ 'ROLE_ADMIN' ] }
aimeos_customer:
entity: { class: AimeosShopBundle:User, property: username }
in_memory:
memory: ~
encoders:
Symfony\Component\Security\Core\User\User: plaintext
Aimeos\ShopBundle\Entity\User:
algorithm: sha1
encode_as_base64: false
iterations: 1
firewalls:
aimeos_admin:
pattern: ^/(admin|extadm|jqadm|jsonadm)
anonymous: ~
provider: admin
form_login:
login_path: /admin
check_path: /admin_check
aimeos_myaccount:
pattern: ^/myaccount
provider: aimeos_customer
http_basic:
realm: "MyAccount"
main:
anonymous: ~
access_control:
- { path: ^/(extadm|jqadm|jsonadm), roles: ROLE_ADMIN }
- { path: ^/myaccount, roles: ROLE_USER }
The Symfony security framework is quite picky about the configuration an even minor changes will break it

FOSOAuthServer : Not able to retrieve access token in api while using HWIOAUTHBUNDLE

While Using FOSOAuthServerBundle as OAuthServer and HWIOAuthBundle as OAuth Client, these both application have FOSUSerBundle integration.
I am facing issue in retrieving access token, which will use in sending user response to client application.
Please anyone can help me out.
<?php
public function userAction(Request $request)
{
$user = $this->get('security.context')->getToken()->getUser();
if($user) {
$user = $this->getDoctrine()->getRepository('EparUserBundle:User')->find(
$this->get('security.context')->getToken()->getUser()
);
return new JsonResponse(array(
'id' => $user->getId(),
'username' => $user->getUsername(),
'email' => $user->getEmail()
));
}
return new JsonResponse(array(
'message' => 'User is not identified'
));
}
FosOAuthServer config.yml and security.yml below:
fos_oauth_server:
db_driver: orm # Driver availables: orm, mongodb, or propel
client_class: Epar\Bundle\UserBundle\Entity\Client
access_token_class: Epar\Bundle\UserBundle\Entity\AccessToken
refresh_token_class: Epar\Bundle\UserBundle\Entity\RefreshToken
auth_code_class: Epar\Bundle\UserBundle\Entity\AuthCode
service:
storage: fos_oauth_server.storage.default
user_provider: fos_user.user_manager
client_manager: fos_oauth_server.client_manager.default
access_token_manager: fos_oauth_server.access_token_manager.default
refresh_token_manager: fos_oauth_server.refresh_token_manager.default
auth_code_manager: fos_oauth_server.auth_code_manager.default
options:
# Prototype
#key: []
# Example
# supported_scopes: string
# Changing tokens and authcode lifetime
access_token_lifetime: 3600
refresh_token_lifetime: 1209600
auth_code_lifetime: 30
supported_scopes: user
# Token type to respond with. Currently only "Bearer" supported.
#token_type: string
#realm:
# Enforce redirect_uri on input for both authorize and token steps.
#enforce_redirect: true or false
# Enforce state to be passed in authorization (see RFC 6749, section 10.12)
#enforce_state: true or false
template:
engine: twig
Security.yml
# app/config/security.yml
security:
encoders:
FOS\UserBundle\Model\UserInterface: sha512
role_hierarchy:
ROLE_ADMIN: ROLE_USER
ROLE_SUPER_ADMIN: ROLE_ADMIN
providers:
fos_userbundle:
id: fos_user.user_provider.username
firewalls:
administration:
switch_user: true
context: user
pattern: /administration*
form_login:
provider: fos_userbundle
login_path: /administration/login
check_path: /administration/login_check
failure_path: /administration/login
default_target_path: /administration/
use_forward: false
use_referer: true
always_use_default_target_path: true
logout:
path: /administration/logout
target: /administration/login
anonymous: ~
main:
pattern: ^/
form_login:
provider: fos_userbundle
csrf_provider: form.csrf_provider
logout: true
anonymous: true
oauth_token:
pattern: ^/oauth/v2/token
security: false
oauth_authorize:
pattern: ^/oauth/v2/auth
form_login:
provider: fos_userbundle
check_path: /oauth/v2/auth_login_check
login_path: /oauth/v2/auth_login
use_referer: true
anonymous: true
context: connect
# Add your favorite authentication process here
api:
pattern: ^/api
fos_oauth: true
stateless: true
anonymous: true # can be omitted as its default value
access_control:
- { path: ^/administration/login, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/administration/login_check, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/api, roles: [ IS_AUTHENTICATED_ANONYMOUSLY ] }
- { path: "/administration.*", role: ROLE_ADMIN }
HWIOAuthBundle application config.yml & security.yml
config.yml
hwi_oauth:
http_client:
timeout: 10 # Time in seconds, after library will shutdown request, by default: 5
verify_peer: false # Setting allowing you to turn off SSL verification, by default: true
ignore_errors: false # Setting allowing you to easier debug request errors, by default: true
max_redirects: 1 # Number of HTTP redirection request after which library will shutdown request,
# by default: 5
#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:
# confirmation: true
account_connector: my_user_provider
# name of the firewall in which this bundle is active, this setting MUST be set
firewall_name: main
fosub:
username_iterations: 30
properties:
# these properties will be used/redefined later in the custom FOSUBUserProvider service.
github: githubID
atssso: atsssoID
resource_owners:
github:
type: github
client_id: *******
client_secret: ********
scope: "user:email"
atssso:
type: oauth2
client_id : 4_1u2nw1clcdy8o4kk84o004s0000oo0kkkw8ow8sg8koowo0c4c
client_secret: v5sa4t4sylcgsgkg8cosws4400k4s0okg48cgc8ccgk8sg4o4
access_token_url: http://192.168.11.71/atssso/web/app_dev.php/oauth/v2/token
authorization_url: http://192.168.11.71/atssso/web/app_dev.php/oauth/v2/auth
infos_url: http://192.168.11.71/atssso/web/app_dev.php/api/user
user_response_class: HWI\Bundle\OAuthBundle\OAuth\Response\PathUserResponse
scope: "user"
paths:
identifier: id
nickname: username
#realname: ["first_name", "last_name"]
realname: username
email: email
# here you will add one (or more) configurations for resource owners
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:
github: "/login/check-github"
atssso: "/login/service/atssso"
login_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
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: ^/admin/, role: ROLE_ADMIN }

Why do I seem as not authenticated in Symfony debug profiler?

When I open my home page by http://domain/app_dev.php/ru/ in Symfony debug profiler I have the following info:
Logged in as: admin
Authenticated: No
Token class: UsernamePasswordToken
My security.yml is:
providers:
users:
entity:
class: BWUserBundle:User
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
auth:
pattern: ^/
anonymous: ~
form_login:
login_path: /%locale%/user/sign-in
check_path: user_sign_in_check
success_handler: bw_user.auth_success_handler
logout:
path: user_sign_out
target: home
access_control:
- { path: ^/admin, roles: ROLE_ADMIN }
- { path: ^/demo/secured/hello/admin/, roles: ROLE_ADMIN }
Why am I not authenticated after successful login as admin? Help to understand what it means?
You have actually removed the Symfony's default firewall:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
You must declare it to be first firewall in your securty.yml.

Resources