Table of contents
Authentication and authorization are closely related, so closely that they are often confused, combined or commingled (yes, I too thought the spelling was comingled). I argue, though, that in general we should maintain a strict separation:
Authentication (AuthN) uniquely identifies who the user is.
Authorization (AuthZ) determines what the user can do.
TLDR
If you use a verify function or other method within the Authentication Scheme with social sign-on (Google, Azure, Facebook, OIDC, etc.) to invalidate a user that passes the social sign-on (for example, the user's email address is not in your domain), the user will not get any feedback as to why they are not able to authenticate. They will just get redirected back to the login screen (which they successfully logged into already). Instead, use an application level Authorization Scheme and modify the error message as described below.
The Longer Story
It seems simple but people, myself included, often embed some authorization into our authentication process. In many cases you have no choice. If you do your own authN, for example via APEX workspace users, database users, a table of users and passwords, even a corporate LDAP server, those users are the only users you can positively identify. If you can't identify them, they can't authenticate to your application. Let's take the case of LDAP users, though. Your company may include many users in the LDAP server that are not allowed to use the application you have developed. Should your authN scheme reject those users, or should there be an authZ scheme that rejects them. If we follow the strict guidance above, it should be an authZ scheme (not the authN scheme). This is even more striking if you use a public authN mechanism, for example Google or Facebook authentication. You may authenticate a user that has nothing to do with your application at all. Should you reject the user at the point of authentication, or should the user be rejected via authorization...or both?
This is probably a good time to mention that if you are a more visual learner, you can watch APEX Instant Tips Episode #132 for much of the same info.
I admit, there are solid arguments to rejecting the authentication if the user is not a valid user of your system. Perhaps I use Azure or Google to authenticate my users...and my users all must have an email address in the @inielsen.net domain. One could argue that any user with an email address in a different domain is "not a user" and, therefor, should not be able to authenticate. As described in the TLDR, there is a practical reason, however, to allow the user to authenticate and then stop the user at the point of application authorization instead of at the point of authentication. If you use the Authentication Scheme the user will not get any feedback as to why they are not able to authenticate. The user simply gets redirected back to the login screen. By using an application level Authorization Scheme the user will get an error page. You can customize the error they receive, allowing you to tell the user why they can't use the application.
In short, instead of repeatedly seeing this (with no indication why)
your user will successfully login but then receive a customized message like this:
How To...
Step 1: Configure your AuthN Scheme without any additional checks--no extra session verify function or anything beyond the standard authentication.
Step 2: Create an AuthZ scheme that does the check you would like. It will look something like this:
Step 3: Edit the Application Definition > Security. Add you application level AuthZ scheme:
Step 4: Configure the additional error message...the portion that will show below the error message in the image directly above. Navigate to Shared Components > Globalization > Text Messages. Create a new text message with the name APEX.AUTHORIZATION.ACCESS_DENIED.APPLICATION. (For more on this topic see APEX Cataclysmic Failure Messages.)
It will look something like this:
The End
That's all folks. Happy authenticating...or authorizing.