We want to authenticate users for our web application using OAuth 2.0 via Azure B2C AD. Users managed the B2C AD will come from different sources, some we create ourselves but most will sign up themselves and we want to enable other identity providers such as Github or Google, hence Azure B2C AD instead of Azure Active Directory. We also want to put these users (including some of the self-signed-up ones) into groups.
The basic authentication workflow (including the the signup process) works: We created an app in a B2C tenant, enabled Web API access, generated a client secret and a user flow for signing in and signing up and set up our 3rd party identity providers.
We initiate the user authentication on
https://<tenant>.b2clogin.com/tfp/<tenant>.onmicrosoft.com/<user-flow>/oauth2/v2.0/authorize?client_id=<client-id>&redirect_uri=<redirect-uri>&scope=<client-id>&response_type=code
The user returns with a valid authorization code and we use that to
request an access token from https://<tenant>.b2clogin.com/tfp/<tenant>.onmicrosoft.com/<user-flow>/oauth2/v2.0/token
using the following POST data:
{
"code":"<authorization-code>",
"client_id":"<client-id>",
"client_secret":"<client-secret>",
"redirect_uri":"<redirect-uri>",
"grant_type":"authorization_code"
}
We then want to use this access token to fetch the user's profile data (including username, email and group memberships) from Azure AD Graph API (https://graph.windows.net//me?api-version=1.6). The docs explicitly say that B2C directories must not use the new Microsoft Graph API https://docs.microsoft.com/en-us/azure/active-directory-b2c/active-directory-b2c-devquickstarts-graph-dotnet
The API responds that the token is expired:
<?xml version="1.0" encoding="utf-8"?><error
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"><code>Authentication_ExpiredToken</code><message
xml:lang="en">Your access token has expired. Please renew it before
submitting the request.</message></error>
But the timestamp in the token decoded by https://jwt.ms/ says otherwise:
{
"typ": "JWT",
"alg": "RS256",
"kid": "X5eXk4xyojNFum1kl2Ytv8dlNP4-c57dO6QGTVBwaNk"
}.{
"iss": "https://<tenant>.b2clogin.com/<id>/v2.0/",
"exp": 1553689573,
"nbf": 1553685973,
"aud": "<client-id>",
"idp": "github.com",
"name": "<username>",
"oid": "<oid>",
"sub": "<sub>",
"emails": [
"<email>"
],
"tfp": "B2C_1_SignupAndSignin",
"azp": "<client-id>",
"ver": "1.0",
"iat": 1553685973
}.[Signature]
However, the aud
in the token is our app only, not the Azure AD
Graph API. That suggests that the token issued by Azure B2C AD is
simply not valid for the Graph API.
So our question is, what is the proper way to:
- obtain an access token for a B2C AD User which will allow us to fetch user info
- read profile and group memberships for an authenticated B2C AD User
Some answers to Secure API with Azure AD/B2C users suggest creating a second app to query the Graph API. Is that the only way to achieve our goals?