Symfony 6 login issue: loadUserByIdentifier(): Argument #1 ($identifier) must be of type string, null given
| Q | A |
|---|---|
| Bug? | no |
| New Feature? | no |
| Support question? | yes |
| Version | 2.0.0-BETA2 |
Actual Behavior
What is the actual behavior?
When you call the Application Login URI (which is /connect/auth0) and correctly filled in your credentials, I got redirected to the callback url (/login/check-auth0?code=123456) the following error messages:
Uncaught PHP Exception TypeError: "HWI\Bundle\OAuthBundle\Security\Core\User\OAuthUserProvider::loadUserByIdentifier(): Argument #1 ($identifier) must be of type string, null given, called in /vendor/hwi/oauth-bundle/src/Security/Core/User/OAuthUserProvider.php on line 43" at /vendor/hwi/oauth-bundle/src/Security/Core/User/OAuthUserProvider.php line 24
HWI\Bundle\OAuthBundle\Security\Core\User\OAuthUserProvider::loadUserByIdentifier(): Argument #1 ($identifier) must be of type string, null given, called in /vendor/hwi/oauth-bundle/src/Security/Core/User/OAuthUserProvider.php on line 43
Like the error is displaying, my UserResponseInterface is empty.
Even when the Auth0 logs contain the Success Login and Success Exchange.
Expected Behavior
When you call the Application Login URI (which is /connect/auth0) and correctly filled in your credentials, a new OAuthUser should be created and stored by the Symfony application.
Steps to Reproduce
I'm on Symfony version 6.0 and PHP version 8.1, using hwi/oauth-bundle version 2.0.0-BETA2.
But the same error was visible in Symfony 5.2 and PHP 7.4.
This is my config/packages/security.yaml:
security:
providers:
hwi:
id: hwi_oauth.user.provider
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
main:
pattern: ^/
oauth:
resource_owners:
auth0: "/login/check-auth0"
login_path: /login
use_forward: false
failure_path: /
oauth_user_provider:
service: hwi_oauth.user.provider
logout:
path: /auth0/logout
target: /
# 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: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/tool, roles: ROLE_OAUTH_USER }
- { path: ^/admin, roles: ROLE_OAUTH_USER }
This is my config/packages/hwi_oauth.yaml:
hwi_oauth:
firewall_names: [main]
resource_owners:
auth0:
type: oauth2
class: 'App\Client\Auth0ResourceOwner'
client_id: "%env(AUTH0_CLIENT_ID)%"
client_secret: "%env(AUTH0_CLIENT_SECRET)%"
base_url: "https://%env(AUTH0_DOMAIN)%"
scope: "%env(AUTH0_SCOPES)%"
This is my \App\Client\Auth0ResourceOwner:
<?php
namespace App\Client;
use Symfony\Component\OptionsResolver\Options;
use Symfony\Component\OptionsResolver\OptionsResolver;
use HWI\Bundle\OAuthBundle\OAuth\ResourceOwner\GenericOAuth2ResourceOwner;
class Auth0ResourceOwner extends GenericOAuth2ResourceOwner
{
/**
* {@inheritdoc}
*/
protected array $paths = [
'identifier' => 'user_id',
'nickname' => 'nickname',
'realname' => 'name',
'email' => 'email',
'profilepicture' => 'picture',
];
/**
* {@inheritdoc}
*/
public function getAuthorizationUrl($redirectUri, array $extraParameters = []): string
{
return parent::getAuthorizationUrl($redirectUri, array_merge(array(
'authorization_url' => $this->options['authorization_url'],
'audience' => $this->options['audience'],
), $extraParameters));
}
/**
* {@inheritdoc}
*/
protected function configureOptions(OptionsResolver $resolver)
{
parent::configureOptions($resolver);
$resolver->setDefaults([
'authorization_url' => '{base_url}/authorize',
'access_token_url' => '{base_url}/oauth/token',
'infos_url' => '{base_url}/userinfo',
'audience' => '{base_url}/userinfo',
'scope' => 'openid user profile'
]);
$resolver->setRequired([
'base_url',
]);
$normalizer = function (Options $options, $value) {
return str_replace('{base_url}', $options['base_url'], $value);
};
$resolver->setNormalizer('authorization_url', $normalizer);
$resolver->setNormalizer('access_token_url', $normalizer);
$resolver->setNormalizer('infos_url', $normalizer);
$resolver->setNormalizer('audience', $normalizer);
}
}
Possible Solutions
I have absolutely no idea what I'm doing wrong or which setting I forgot. This is a project that was working in August 2021, but now (April 2022) I'm dusting off. Can someone point me in the right direction to solve this login issue?
@jasperpoppe I had the same error you have until I set the scope option to openid profile email. Also, I'm using the Auth0ResourceOwner shipped with the library.
Hi @alsciende!
Thanks for your feedback.
I'm trying to use the Auth0ResourceOwner, but I got the following error message:
Class "\OAuth\ResourceOwner\Auth0ResourceOwner" must implement interface "HWI\Bundle\OAuthBundle\OAuth\ResourceOwnerInterface".
Is your hwi_oauth.yaml file looking like this?
hwi_oauth:
firewall_names: [main]
resource_owners:
auth0:
type: oauth2
class: '\OAuth\ResourceOwner\Auth0ResourceOwner'
client_id: "%env(AUTH0_CLIENT_ID)%"
client_secret: "%env(AUTH0_CLIENT_SECRET)%"
base_url: "https://%env(AUTH0_DOMAIN)%"
scope: "%env(AUTH0_SCOPES)%"
@jasperpoppe Hi! Here is my hwi_oauth.yml file: https://github.com/alsciende/effusion/blob/main/config/packages/hwi_oauth.yaml.
Its content is:
hwi_oauth:
resource_owners:
auth0:
type: auth0
client_id: '%env(AUTH0_CLIENT_ID)%'
client_secret: '%env(AUTH0_CLIENT_SECRET)%'
base_url: 'https://%env(AUTH0_DOMAIN)%'
scope: 'openid profile email'```
Hey @jasperpoppe @alsciende , can you check if applying: https://github.com/hwi/HWIOAuthBundle/pull/1913 fixes your problem? Thanks!
Hi @stloyd ! Thanks for your time!
When I apply your bugfix to the 2.0.0-BETA2 branch, I got following error message:
Attempted to call an undefined method named "getUserIdentifier" of class "HWI\Bundle\OAuthBundle\OAuth\Response\PathUserResponse".
@jasperpoppe You should try dev-master as beta3 that contains a fix for this was not yet released.
When on dev-master and Symfony 6.1, I got following error message:
User identifier was not found in response.
@jasperpoppe According to Auth0 docs and your code above:
protected array $paths = [
'identifier' => 'user_id',
'nickname' => 'nickname',
'realname' => 'name',
'email' => 'email',
'profilepicture' => 'picture',
];
This: 'identifier' => 'user_id', should be: 'identifier' => 'email', (or preferred_username or other unique value).
In built-in we use use sub for identifier: https://github.com/hwi/HWIOAuthBundle/blob/master/src/OAuth/ResourceOwner/Auth0ResourceOwner.php#L28
Ok, now I got this weird error which isn't even loading my app.
hwi_oauth.yaml:
hwi_oauth:
firewall_names: [main]
resource_owners:
auth0:
type: oauth2
class: 'App\Client\Auth0ResourceOwner'
client_id: "%env(AUTH0_CLIENT_ID)%"
client_secret: "%env(AUTH0_CLIENT_SECRET)%"
base_url: "https://%env(AUTH0_DOMAIN)%"
scope: "%env(AUTH0_SCOPES)%"
src/Client/Auth0ResourceOwner.php:
<?php
namespace App\Client;
use Symfony\Component\OptionsResolver\Options;
use Symfony\Component\OptionsResolver\OptionsResolver;
use HWI\Bundle\OAuthBundle\OAuth\ResourceOwner\GenericOAuth2ResourceOwner;
class Auth0ResourceOwner extends GenericOAuth2ResourceOwner
{
/**
* {@inheritdoc}
*/
protected array $paths = [
'identifier' => 'sub',
'nickname' => 'nickname',
'realname' => 'name',
'email' => 'email',
'profilepicture' => 'picture',
];
/**
* {@inheritdoc}
*/
public function getAuthorizationUrl($redirectUri, array $extraParameters = []): string
{
return parent::getAuthorizationUrl($redirectUri, array_merge(array(
'authorization_url' => $this->options['authorization_url'],
'audience' => $this->options['audience'],
), $extraParameters));
}
/**
* {@inheritdoc}
*/
protected function configureOptions(OptionsResolver $resolver)
{
parent::configureOptions($resolver);
$resolver->setDefaults([
'authorization_url' => '{base_url}/authorize',
'access_token_url' => '{base_url}/oauth/token',
'infos_url' => '{base_url}/userinfo',
'audience' => '{base_url}/userinfo',
'scope' => 'openid user profile email'
]);
$resolver->setRequired([
'base_url',
]);
$normalizer = function (Options $options, $value) {
return str_replace('{base_url}', $options['base_url'], $value);
};
$resolver->setNormalizer('authorization_url', $normalizer);
$resolver->setNormalizer('access_token_url', $normalizer);
$resolver->setNormalizer('infos_url', $normalizer);
$resolver->setNormalizer('audience', $normalizer);
}
}
The error I got:
Warning: Undefined array key "type"
No clue where I can set that missing type key.
When I don't set a custom resource owner class in my hwi_oauth.yaml file, I got following:
Invalid configuration for path "hwi_oauth.resource_owners.auth0": All parameters are mandatory for types 'oauth2' and 'oauth1'. Check if you're missing one of: 'access_token_url', 'authorization_url', 'infos_url' and 'request_token_url' for 'oauth1'.
@jasperpoppe This should be fixed after #1915.
After updating the dev-master package and using your #1913 pull request, I still got the error message like one of my previous comments: https://github.com/hwi/HWIOAuthBundle/issues/1901#issuecomment-1192393680
@jasperpoppe Can you paste response after which you get that error? Cause according to linked docs it should work with sub.
So, this is the steps I take to reproduce this error:
- I go to
/connect/auth0(to login) - I got redirected to
/login/check-auth0?code={code_id} - Then I see the error
When I dump the $response data from src/Security/Core/User/OAuthUserProvider.php#L43, I see the three roles I defined in auth0:
[OAuthUserProvider.php] on line 43:
array:1 [▼
"http://schemas.microsoft.com/ws/2008/06/identity/claims/role" => array:3 [▼
0 => "administrator"
1 => "group-responsible"
2 => "wristband-responsible"
]
]
So there is no sub or other $paths I defined in src/Client/Auth0ResourceOwner.php.
For me it seems that there is wrong url used to get user info or due to usage of audience you got different response (my guess)