Auth0 Home Blog Docs

Prevent ADFS users login if they are not registered

adfs
login

#1

We are evaluating an update in our workflow to implement an Authorization Code Grant.
We currently support ADFS and database connections. We do not allow users to register. Any user who wants to login into the application must first be registerd by an admin.

We find no way to prevent not registered ADFS users to login:

  • it is not posible to manually add an ADFS user. Auth0 just registers an ADFS user in the background the first time he tries to login and Auth0 gets a succesful response from the ADFS server,
  • configuring the login form to hide signup tab does not work as explained above
  • the “Disable signups” option, in the connection settings for ADFS does not exists, as there is in other types of connections like database or passwordless.

Right now we have implemented a pseudo Authorization Code Grant not OIDC compliant and with a custom login form. It uses a local database of registered users. Before any login attempt, the server checks if the user is in the database to continue to authentication in Auth0.

But we would like to find a way, fully compatible with Authorization Code Grant and with Hosted Login Page.

We have read Invite-Only Applications article, but seems to talk about database connections. There is just a parragraph saying

“You can handle this requirement in
Auth0 using an Enterprise Connection
(using federation) with the individual
customers using ADFS, SAML-P, and so
on. This allows the customer to
authenticate users with their own
Active Directory specifying who gets
access to the app.”

This seems to put the ball on the hands of the ADFS administrator (which is our customers side not our side) and makes the management of users different depending on being an ADFS user or a database user. The first being registerd in ADFS the second in our own service.


#2

I have finally found a way to do this.

Just a note though, I am not using the Authorization Code grant and I don’t know how this might interact with it.

Here are the basic steps:

  1. Setup your ADFS/Enterprise connection, AS WELL AS a regular Username-Password connection
  2. Create a rule based on the Link Users Example Rule
    This will automatically link the ADFS profile when the user first logs in
    NOTE: there’s a bit of weirdness if you have rules after this one. What seems to work is returning originalUser in the callback instead of user.
  3. (Optional) At this point, users could theoretically login using both their Username-Password combination, as well as their ADFS account. To prevent this, add a rule that looks for an arbitrary flag in the user’s app_metadata which would specify if password login is disabled

Then to add users:

  1. Use the Management API to create your desired users. Use the Username-Password connection for this.
    Set verify_email: false and email_verified: true
    At this point, you can also configure app_metadata, authorization etc…
  2. Tell the user to login. If you are using the Hosted Login page, they should get the SSO option once they enter their email address.

And that’s it! A bit of a mission, and maybe a bit hacky, but its the only way I could get this working.


#3

For connections where an upstream identity provider is involved there is indeed no possibility to manually create user profiles in Auth0 as this happens as part of a login process. For this specific scenario ADFS is pretty much equivalent to Google social as in enabling that connection means every end-user that has credentials for that identity provider can complete the authentication step.

If you want to enable a connection like ADFS, but don’t want to authorize every user that can authenticate against ADFS then independently of Auth0 being used or not you’ll have to:

  1. federate against ADFS and allow the end-user to authenticate.
  2. upon the end-user completing the authentication process you now have proof that they are who they say they are (for example, confirmation that the user owns a specific email address).
  3. having a confirmed end-user identifier you need to check that identifier against a store of previously authorized users in order to check if he can continue to access the application or not.

Translating that to using the Auth0 service the first point is achieved simply by enabling a connection, the second point is achieved because after the end-user authenticates against ADFS the Auth0 service will obtain profile information and make it available withing your tenant/domain.

The third point is where you have some flexibility; you can implement this check in a custom rule which would mean that it would happen in your tenant/domain itself and as such can be reused by multiple applications or you can choose to do this authorization check in the client application itself.

Independently of where you want to do it (rule or client application) you’ll have to have a store that keeps information about the identifiers of the subset of end-users that are authorized. For this part, I would recommend against doing it like you described; it seems that you’re using an additional username/password identity/connection as means to store the list of authorized users. This is overloading the real use cases for database connections and account linking so if you’re using them for the sole purpose of being able to store the list of authorized users within the tenant/domain itself instead of an external store I would reconsider that approach.

Personally, I would store the authorization data in an external store and either do the check from the client application or perform an external call from the rule to this store if having the check in rules could be beneficial (multiple applications have the same authorization check).