Entra External Id self-service registration results in "AADSTS131010: User not allowed by policy conditions."

Stefan Schneider-Kennedy (DGS) 20 Reputation points
2024-02-08T06:41:26.05+00:00

I'm evaluating Entra External Id as an OAuth SSO provider for my web app that also allows the user to self register an account. I'm experiencing the following error when trying to receive an access token for users who have just self-registered with my tenant. Getting the access token for existing users works fine.

Does anybody know what might be the cause of this error and how to fix it?

This is an example error response with the trace and correlation ids censored.

{'error': 'invalid_grant', 'error_description': 'AADSTS131010: User not allowed by policy conditions. Trace ID: 00000000-0000-0000-0000-0000000000000 Correlation ID: 00000000-0000-0000-0000-0000000000000 Timestamp: 2024-02-05 23:20:24Z', 'error_codes': [131010], 'timestamp': '2024-02-05 23:20:24Z', 'trace_id': '00000000-0000-0000-0000-0000000000000', 'correlation_id': '00000000-0000-0000-0000-0000000000000', 'suberror': 'bad_token'}

I've tried a few things:

  1. I've gone through the login flow again in the same browser session after 15 minutes. I get the same error, so I don't think this is a timing issue.
  2. I've written my own code to redeem the OAuth token (rather than using MSAL) to confirm the parameters I was passing. In particular I tried with only the 'openid' scope, thinking an overly broad scope might have been the problem. Still got the error.
  3. I've signed in with the user I just registered in a separate browser session. This worked as expected and gave me the access token. Even after this successful sign in my original browser session returned the same error when I tried to sign in again. So the cookies in that browser session are 'bad' somehow.
  4. Looked at my Entra Conditional Access Policy settings. I don't believe I have anything set, in part because this feature is not supported by the free trial.

I've found a couple of similar questions on other forums which I think are the same problem. Neither have answers currently:

I've included the code I'm using to test this below. It's a Python Flask app which you can use to reproduce the issue as follows:

  1. Create an App Registration in your Entra External Id tenant. On the Authentication tab set the Redirect URI to 'http://localhost:8000/oauth/callback' and the supported account type to 'Accounts in any organizational directory (Any Microsoft Entra ID tenant - Multitenant)'. Create a client id/client secret pair on the 'Certificates & Secrets' page.
  2. Install the requirements listed in the first block to your Python virtual environment.
  3. Run AZURE_CLIENT_ID=... AZURE_CLIENT_SECRET=... AZURE_AUTHORITY=... python app.py. Populating the ... with the appropriate values.
  4. Visit 'http://localhost:8000/login'.
  5. Create a new user when prompted and go through the flow to completion.
  6. You should be redirected to the app and will see an error like the above.

requirements.txt

msal==1.26.0
flask==3.0.1

app.py

import json
import os

import msal
from flask import Flask
from flask import (
    Blueprint,
    redirect,
    make_response,
    request,
)


views = Blueprint("views", __name__)


def build_msal_app():
    # A value like 00000000-0000-0000-0000-000000000000
    client_id = os.environ["AZURE_CLIENT_ID"]
    # A value like g_123~exhw84r...
    client_secret = os.environ["AZURE_CLIENT_SECRET"]
    # A value like https://mytenant.ciamlogin.com/
    authority = os.environ["AZURE_AUTHORITY"]

    return msal.ConfidentialClientApplication(
        client_id,
        authority=authority,
        client_credential=client_secret,
    )


@views.route("/login")
def login():
    app = build_msal_app()
    redirect_url = app.get_authorization_request_url(
        [],
        redirect_uri="http://localhost:8000/oauth/callback"
    )

    return redirect(redirect_url)


@views.route("/oauth/callback")
def authorized():
    code = request.args.get("code", "")
    result = build_msal_app().acquire_token_by_authorization_code(
        code,
        scopes=[],
        redirect_uri="http://localhost:8000/oauth/callback"
    )
    if "error" in result:
        return json.dumps(result)
    else:
        return "access token: " + result["access_token"]


app = Flask(__name__)
app.register_blueprint(views)

if __name__ == "__main__":
    app.run(host='0.0.0.0', port=8000)
Microsoft Entra External ID
Microsoft Entra External ID
A modern identity solution for securing access to customer, citizen and partner-facing apps and services. It is the converged platform of Azure AD External Identities B2B and B2C. Replaces Azure Active Directory External Identities.
2,651 questions
{count} votes

1 answer

Sort by: Most helpful
  1. Kasperi Pohtinen 0 Reputation points
    2024-04-09T03:24:09.79+00:00

    I had opened an azure support ticket recarding this issue and got the following response:

    Upon receiving the response from our internal team, we have been indicated that this is a known issue which is being worked on by our PG Team.    The fix for this issue is already underway with an ETA for April 19th. 

    1 person found this answer helpful.