We use Drupal and this module in a university setting. Shib returns basic information in an attribute such as student vs. staff. In the current state this modules works great already for most use cases, but provides a few challenges as well. Anybody with a valid identity from the Shib provider will always get authenticated and added into the Drupal user table with the minimum role of "authenticated user". This potentially adds a lot more user entries than necessary and causes problems because some Drupal funcionality is by default available to authenticated users (without the option to take the permission away from them). Moreover, standard blocks such as "Who is online" include such users.
Use case: I want to build an application just for students. However, all staff can click the Shib login button and authenticate successfully which will give them an entry in the Drupal user table, make them appear in the newest members, who is online blocks etc. I can obviously use the role matching to elevate students up with regard to their permissions, but I cannot downgrade staff to anything other than authenticated user. I have come up with a few workarounds (such as blocking staff users right after Shib login), but it would be a lot cleaner to include some basic authorization settings in this module to deny access.
Here is the proposed solution:
1) Add an option in the shib role matching to deny access to users who match certain criteria in Shib attributes (right now I can only grant roles and make these settings sticky). The simplest option would be to add a checkbox like the sticky one which reads deny access to application. In my case I could add a regex with the appropriate Shib attribute, value = staff and tick the box to deny access.
2) The most logical point in the process to stop the user from interacting with the application is just before the custom form that can be enabled for customization of username, email and terms of service gets displayed. Once we have the checkbox for the deny access in the settings, the very first check should be if the deny access rule matches. If it does, the whole process should be stopped and the user should be shown a customized message why she cannot use the application.
The only question to consider is how the deny access matching will work exactly in a case when users have multiple attributes (e.g. a user is a student and a staff). We could deny access as soon as the attribute is found or check for a single match only to the attribute. We could potentially even offer that as a configuration option.
An alternative would be to make this a new configuration option to not mix it into the roles matching or add an "include" vs. "exclude" role type.
I am looking for some feedback from others if such a feature would be useful. I am not sure if I can develop it myself, but I could start ;-)
Comments
Comment #1
jelo commentedDoes anybody have any feedback on this issue? It seems to me as a common requirement to not always allow every Shib authenticated user access to the Drupal application.
An alternative to my earlier suggestions would be to remove the default setting which currently makes every authenticated Shib user an authenticated user in Drupal. If we remove that default, than we could use the Shib Group Rules to define who of our authenticated Shib users becomes a Drupal authenticated user. You could use a shib argument with a wildcard regex to make any authenticated Shib user an authenticated Drupal user if you want to do that (i.e. recreate the previous default)... But it would at least give you the option to work with sub segments of users as returned by the Shib provider.
Comment #2
laas commentedI second this feature request, specifically as proposed in #1: create a way to avoid automatically making every Shibboleth user an authenticated Drupal user.
Comment #3
bajnokk commentedIt would be easier to add one another twist into the spaghetti of conditions before user creation. An admin may probably specify a condition (possibly logically combining multiple conditions) when a user entry SHOULD NOT be created.
Additionally, probably a checkbox can be added to also fail with an "Access denied" message if an existing user matches the rejecting criteria (for example his affiliation had changed).
At the moment I'm not really interested in this use-case but I'm willing to review anything that is contributed.
Comment #4
bajnokk commentedComment #5
jelo commentedTo me those are two different use cases:
1) The first case is to completely block sets of users from being recorded in the Drupal user table based on specified criteria. Identity providers may handle dozens of affiliations and any particular application may be only targeted at one of those affiliations. Without this functionality, hundreds of user accounts may end up in the Drupal user table with minimal or no access to the application.
2) The scenario that you describe to show access denied if an affiliation changes would naturally occur if access control is implemented correctly I believe. In this case I have an entry in the user table, but if certain criteria change (such as in my case a staff member retiring) the access changes, driven through changes in the user role.
I am still trying to figure out how to best prevent user account creation through a custom module without having to patch Shib Auth. Registration form validation errors don't seem to be an option because Shib does not go through the registration form. Hook user presave does not seem to work either. Any ideas?
Should Shib just expose a hook that modules can use to write their own global rules and if these fail block user registration?
Comment #6
jelo commentedThis would do the trick:
shib_auth.module (line 763):
I added a function to check for any registration blocks.
This functions looks like this:
For this to function I added the variable "block_text" in shib_auth_config and in shib_auth_forms.inc.
However, now my custom logic sits in a hacked Shib Auth module. I assume it would be cleaner to implement a hook so that I can put my logic into a separate module to determine if a user should be blocked or not. How would I implement a hook so that the logic from function shib_auth_block_test could be stored outside of the module code?