Redirect not happening when user does not exist

Hello,

I am trying to set up Open OnDemand to redirect to a waiting page when users do not yet exist. Users are created in Keycloak and then synced to our LDAP servers, which means there may be a delay of a few minutes between a user existing in Keycloak and being able to access Open OnDemand, and actually existing on the OnDemand system (e.g. id user0001 will return id: user0001: no such user for a few mins)

I have configured my ood_portal.yml as follows for this:

map_fail_uri: '/nouseryet'
register_uri: '/nouseryet'
register_root: '/var/www/ood/register'

but I’m still getting the following error message come up - when I was expecting to be redirected:

This is what I see in the httpd logs - first the 404 and then the successful access after the user appears in LDAP/SSSD:
(130.246.X.X is where I’m browsing from)

[Tue Mar 07 15:23:12.081154 2023] [lua:info] [pid 222645] [client 130.246.X.X:19012] req_protocol="HTTP/1.1" req_handler="" req_method="GET" req_accept="text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8" req_user_agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/110.0" res_content_length="117" req_content_type="" res_content_encoding="" req_status="404" req_origin="" time_user_map="0.002" local_user="iris0012" req_referer="" res_content_language="" req_port="443" log_time="2023-03-07T15:23:12.81028Z" req_server_name="portal.scarf.rl.ac.uk" log_hook="ood" req_accept_charset="" req_hostname="portal.scarf.rl.ac.uk" res_content_location="" res_content_disp="" req_is_websocket="false" remote_user="iris0012" res_location="" req_user_ip="130.246.X.X" req_is_https="true" req_filename="/opt/rh/httpd24/root/var/www/html/pun" req_uri="/pun/sys/dashboard" time_proxy="0" res_content_type="" req_accept_language="en-us,en;q=0.5" req_cache_control="" req_accept_encoding="gzip, deflate, br"
[Tue Mar 07 15:24:08.024096 2023] [lua:info] [pid 222651] [client 130.246.X.X:1852] req_protocol="HTTP/1.1" req_handler="proxy-server" req_method="GET" req_accept="text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8" req_user_agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/110.0" res_content_length="904" req_content_type="" res_content_encoding="" req_status="200" req_origin="" time_user_map="0.002" local_user="iris0012" req_referer="" res_content_language="" req_port="443" log_time="2023-03-07T15:24:08.23919Z" req_server_name="portal.scarf.rl.ac.uk" log_hook="ood" req_accept_charset="" req_hostname="portal.scarf.rl.ac.uk" res_content_location="" res_content_disp="" req_is_websocket="false" remote_user="iris0012" res_location="" req_user_ip="130.246.X.X" req_is_https="true" req_filename="proxy:http://localhost/pun/sys/dashboard" req_uri="/pun/sys/dashboard" time_proxy="1.301" res_content_type="text/html; charset=utf-8" req_accept_language="en-us,en;q=0.5" req_cache_control="" req_accept_encoding="gzip, deflate, br"

The generated /opt/rh/httpd24/root/etc/httpd/conf.d/ood-portal.conf looks OK to me?

  SetEnv OOD_USER_MAP_MATCH ".*"
  SetEnv OOD_MAP_FAIL_URI "/nouseryet"
  Alias "/nouseryet" "/var/www/ood/register"
  <Directory "/var/www/ood/register">
    Options FollowSymLinks
    AllowOverride None

    AuthType openid-connect
    Require claim realm_access.roles:scarf-trial
  </Directory>
</VirtualHost>

The actual page does look OK to me - this is what I was expecting to see (ignore the ugly HTML - that’ll be neatened up when I get it working!)

image

I’m not quite sure what I’m doing wrong here! Does anyone have any advice please? Thanks!

I’m seeing the same thing, looks like we opened our questions almost the same time. Perhaps I should close mine?

I’ll look into it and report back on this topic.

OK - apparently registering only works for when you can’t map the user. Because you were both able to map the user - it went onto the next stage which is starting the Per User Nginx. You can note that the error message is from nginx_stage.

When you fail to map a user - you get an error message like this. At this point, because I was unable to map this user - I could then redirect to a register page.

So do you think a custom mapping script that checks for the user existing on the system is the solution here? (that would otherwise return back the username passed to it?). Is there a particular return code or something it should do if mapping should fail? Thanks!

I think the contract is you should just exit 1 if you want to fail. Let me update the latest docs now because you may run into this issue - the $1 being passed into the script is URL encoded and that’s not obvious/or even mentioned in the documentation.

You can go that route and I would have suggested it, only it runs all the time, on every request. So it could be expensive to run this script on every single request to catch this edge case.

Of course it’s your site, it’s your center, and an extra 10-30ms (or however much time) may not even be that bad. You can set the lua_log_level to debug to see how long it takes to map users to get a sense of how fast you can execute this script.

Ah right! Yes every request may not be ideal, but I suppose if that’s the only way to do it… - is there anything else you would suggest here - or is that the only way forward if we want to be able to give users a message if the account doesn’t exist yet?

Yea, sorry, I think you only have these options:

  • live with the behavior as it is
  • create a user_map_cmd that can check for to see if the user actually exists and this will allow you to use your register page.

I’ve created this ticket upstream because it does seem like we should redirect to the register page on this failure.

Also - documentation has been updated so these docs now correctly account for url encoded input.

https://osc.github.io/ood-documentation/latest/authentication/overview/map-user.html?#user-map-command-for-advanced-mappings

I’ve gone with this script (as my registration page also creates the users home directory and I want to check its there already - might add a sleep and recheck)

#!/bin/bash

INPUT_USER="$1"

# check the user exists
if user=$(getent passwd "$INPUT_USER") ; then
  # check the users home directory exists
  homedir=${user%:*}
  homedir=${homedir##*:}
  if [[ -e "$homedir" ]] ; then
    echo "$INPUT_USER"
    exit 0
  fi
fi

exit 1

I’m going with this for now - and it is working for us!

#!/bin/bash

INPUT_USER="$1"

# check the user exists
if user=$(id "$INPUT_USER") ; then
  echo "$INPUT_USER"
  exit 0
fi

exit 1

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.