diff --git a/jsc_custom/authenticator/oauthenticator.py b/jsc_custom/authenticator/oauthenticator.py
index e330360006c18a893b09744fd2aaaeb87860fdde..3dde5236a1f782c1f74a701a1e05527414a2a9fc 100644
--- a/jsc_custom/authenticator/oauthenticator.py
+++ b/jsc_custom/authenticator/oauthenticator.py
@@ -40,6 +40,17 @@ res_pattern = re.compile(
     r"(?P<accounttype>[^:]+)$"
 )
 
+res_groups_pattern = re.compile(
+    r"^urn:"
+    r"(?P<namespace>.+?(?=:res:)):"
+    r"res:"
+    r"(?P<parentgroup>[^:]+)?"
+    r"(?::(?!role=)(?P<childgroup>[^:#]+))?"
+    r"(?::(?!role=)(?P<grandchildgroup>[^:#]+))?"
+    r"(?::role=(?P<role>[^#]+))?"
+    r"#(?P<authority>.+)$"
+)
+
 group_pattern = re.compile(
     r"^urn:"
     r"(?P<namespace>.+?(?=:group:)):"
@@ -81,7 +92,9 @@ def get_groups_default(user_info):
         -   urn:<namespace>:group:parentgroup#authority
         -   default
     """
-    entitlements = user_info.get("entitlements", [])
+    entitlements = user_info.get(
+        "entitlements", user_info.get("oauth_user", {}).get("entitlements", [])
+    )
     groups = []
 
     def add_sub_groups(group, role, authority, rightmost_group=True):
@@ -126,9 +139,47 @@ def get_groups_default(user_info):
                     groups.append(group)
                 add_sub_groups(group, role, authority, rightmost_group)
                 rightmost_group = False
+        else:
+            match = res_groups_pattern.match(entry)
+            if match:
+                namespace = match.group("namespace")
+                grandchildgroup = match.group("grandchildgroup")
+                childgroup = match.group("childgroup")
+                parentgroup = match.group("parentgroup")
+                role = match.group("role")
+                authority = match.group("authority")
+                rightmost_group = True
+                if grandchildgroup:
+                    group = f"urn:{namespace}:group:{parentgroup}:{childgroup}:{grandchildgroup}"
+                    if group not in groups:
+                        groups.append(group)
+                    add_sub_groups(group, role, authority, rightmost_group)
+                    rightmost_group = False
+                if childgroup:
+                    group = f"{namespace}:{parentgroup}:{childgroup}"
+                    if group not in groups:
+                        groups.append(group)
+                    add_sub_groups(group, role, authority, rightmost_group)
+                    rightmost_group = False
+                if parentgroup:
+                    group = f"{namespace}:{parentgroup}"
+                    if group not in groups:
+                        groups.append(group)
+                    add_sub_groups(group, role, authority, rightmost_group)
+                    rightmost_group = False
 
     if "default" not in groups:
         groups.append("default")
+
+    for attribute in ["org_domain", "voperson_external_affiliation"]:
+        value = user_info.get(
+            attribute, user_info.get("oauth_user", {}).get(attribute, None)
+        )
+        if value and type(value) == list:
+            groups.extend(value)
+        elif value and type(value) == str:
+            groups.append(value)
+
     return list(set(groups))
 
 
@@ -550,23 +601,26 @@ class CustomGenericOAuthenticator(GenericOAuthenticator):
         #  - last login (additional information for the user)
         #  - used authenticator (to classify user)
         #  - hpc_list (allowed systems, projects, partitions, etc.)
-        access_token = authentication["auth_state"]["access_token"]
-        headers = {
-            "Accept": "application/json",
-            "User-Agent": "JupyterHub",
-            "Authorization": f"Bearer {access_token}",
-        }
-        req = HTTPRequest(self.tokeninfo_url, method="GET", headers=headers)
-        try:
-            resp = await authenticator.fetch(req)
-        except HTTPClientError as e:
-            authenticator.log.warning(
-                "{name} - Could not request user information - {e}".format(
-                    name=authentication.get("name", "unknownName"), e=e
+        if self.tokeninfo_url:
+            access_token = authentication["auth_state"]["access_token"]
+            headers = {
+                "Accept": "application/json",
+                "User-Agent": "JupyterHub",
+                "Authorization": f"Bearer {access_token}",
+            }
+            req = HTTPRequest(self.tokeninfo_url, method="GET", headers=headers)
+            try:
+                resp = await authenticator.fetch(req)
+            except HTTPClientError as e:
+                authenticator.log.warning(
+                    "{name} - Could not request user information - {e}".format(
+                        name=authentication.get("name", "unknownName"), e=e
+                    )
                 )
-            )
-            raise Exception(e)
-        authentication["auth_state"]["exp"] = resp.get("exp")
+                raise Exception(e)
+            authentication["auth_state"]["exp"] = resp.get("exp")
+        else:
+            authentication["auth_state"]["exp"] = time.time() + 1200
 
         preferred_username = (
             authentication["auth_state"]