Closed eved42 closed 2 years ago
Hi there!
The purpose of this bundle, basically, is to help you get the "access token" via OAuth. If you have user authentication working, then it means that you should have code in your authenticator that looks something like this:
$accessToken = $this->fetchAccessToken($client);
$azureUser = $client->fetchUserFromToken($accessToken);
That $accessToken
is the same as the $token
variable you see in the docs - https://github.com/thenetworg/oauth2-azure#microsoft-graph - and you can freely use it to make API requests to the Azure API using whatever tool you like for making API requests. If you want to access the underlying $provider
that you see in those docs, you can call $client-> getOAuth2Provider()
from this bundle.
I hope that helps!
@weaverryan Thank you for you answer, is was very helpful!
If we want to use Microsoft Graph, we can't use the same access token than the authentication, it's a specific token. I managed to make it works, here is my code :
I store the profile photo into the session so I injected RequestStack
in the authenticator.
// src/Security/AzureAuthenticator.php
// ...
use Symfony\Component\HttpFoundation\RequestStack;
class AzureAuthenticator extends OAuth2Authenticator implements AuthenticationEntrypointInterface
{
private $clientRegistry;
private $em;
private $router;
private $requestStack;
public function __construct(ClientRegistry $clientRegistry, EntityManagerInterface $em, RouterInterface $router, RequestStack $requestStack)
{
$this->clientRegistry = $clientRegistry;
$this->em = $em;
$this->router = $router;
$this->requestStack = $requestStack;
}
// ...
public function authenticate(Request $request): Passport
{
$client = $this->clientRegistry->getClient('azure');
$accessToken = $this->fetchAccessToken($client);
return new SelfValidatingPassport(
new UserBadge($accessToken->getToken(), function() use ($accessToken, $client) {
// Get user data from Azure AD
$azureUser = $client->fetchUserFromToken($accessToken);
// Get the corresponding user account in the database
$user = $this->em->getRepository(User::class)->findOneBy(['email' => $azureUser->getUpn()]);
// User doesn't exist -> creation
if (!$user) {
$user = new User();
$user->setFirstname($azureUser->getFirstName());
$user->setLastname($azureUser->getLastName());
$user->setEmail($azureUser->getUpn());
$this->em->persist($user);
$this->em->flush();
}
// Get the user profile photo (need to use Microsoft Graph API)
$provider = $client->getOAuth2Provider();
$baseGraphUri = $provider->getRootMicrosoftGraphUri(null); // https://graph.microsoft.com
$provider->urlAPI = $baseGraphUri;
$provider->resource = $baseGraphUri;
// Swap the Azure AD access token for a Microsoft Graph token
$graphAccessToken = $provider->getAccessToken('refresh_token', [
'refresh_token' => $accessToken->getRefreshToken(),
'resource' => $baseGraphUri
]);
// Get photo
$photoData = $provider->get($baseGraphUri.'/v1.0/me/photo', $graphAccessToken);
$photo = $provider->get($baseGraphUri.'/v1.0/me/photo/$value', $graphAccessToken);
$src = 'data:'.$photoData["@odata.mediaContentType"].';base64,'.base64_encode($photo); // for <img src="$src" />
// Store into session
$session = $this->requestStack->getSession();
$session->set('azure.user-img-src', $src);
return $user;
})
);
}
// ...
Hello,
I use your bundle with a Symfony 6.1 project for a Azure authentication. The user authentication is working well and now I would like to get the Microsoft profile picture of the user. Is there a simple way to do that ?
In the documentation of the TheNetworg Azure AD provider, I see that it is possible to use Microsoft Graph API to get the user data. But I don't understand how I should use it with your bundle.
I think I should do something in
AzureAuthenticator > authenticate()
, can someone help me please ?