Restrict Access to Custom Portal Based on Assignment Group
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
yesterday
Hi Everyone,
I have created a custom portal in ServiceNow, and I need to restrict access to this portal so that only users who are part of a specific assignment group (Hardware) can access it.
The requirement is:
- Only users who belong to the Hardware assignment group should be able to view and access the portal.
- All other users should be denied access to this portal.
Could you please guide me on how to implement this? Are there any recommended approaches or best practices to achieve this kind of group-based access control?
Thanks in advance for your support!
Best regards,
Rajesh Bandila
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
yesterday
You can achieve this by redirecting users to default portal if they are not part of Hardware assignment group
Navigate to Service Portal -> Portals -> Open custom Portal -> Theme -> Header
Update the server script of the header as per the requirement
var portalSuffix = '/esc'; //default portal suffix
if (gs.getUser().isMemberOf('<group_sys_id>') || gs.hasRole('admin')) {
portalSuffix = '/custom'; //custom portal suffix
}
data.portalName = portalSuffix;
Update the client controller of the header
var c = this;
var url = $window.location.href;
var urlPrefix = '';
var portalSuffix = '';
if (url.indexOf('?') != -1) // If URL contains '?', replace only portal name in complete url
{
urlPrefix = url.substr(0, url.indexOf('?'));
urlSuffix = url.substr(url.indexOf('?'));
portalSuffix = c.data.portalName + urlSuffix;
} else { // if url doesn't contains '?', replace the portal name only
urlSuffix = c.data.portalName;
portalSuffix = urlSuffix;
}
$location.url(portalSuffix);
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
yesterday
You can use SPEntryPage script include for this logic
check this link
Role based redirection with SPEntryPage
If my response helped please mark it correct and close the thread so that it benefits future readers.
Ankur
✨ Certified Technical Architect || ✨ 9x ServiceNow MVP || ✨ ServiceNow Community Leader
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
yesterday
Hope you are doing good.
Did my reply answer your question?
If my response helped please mark it correct and close the thread so that it benefits future readers.
Ankur
✨ Certified Technical Architect || ✨ 9x ServiceNow MVP || ✨ ServiceNow Community Leader
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
yesterday
I have updated SPEntryPage script include for you as suggested by Ankur, see if it can help you
How It Works:
Authorized Users (Members of "application" assignment group):
Can access /customPortal normally
Login and navigation work as expected
Unauthorized Users (Not in "application" group):
Automatically redirected to /sp/ portal
/**
*
* Service Portal sample script include to indicate
* 1. which login page should be used
* 2. the starting page after the user is authenticated
*
* Script is configured using system properties
* PROPERTY VALUE
* glide.entry.page.script new SPEntryPage().getLoginURL();
* glide.entry.first.page.script new SPEntryPage().getFirstPageURL();
*
* functions can return a path or null if no overrides are necessary
*
**/
var SPEntryPage = Class.create();
SPEntryPage.prototype = {
initialize: function() {
this.logVariables = false; // for debugging
this.customPortal = "/customPortal/"; // Custom portal for Application team
this.defaultPortal = this.getDefaultPortal(); // The URL suffix for default portal
this.applicationGroupName = "application"; // Assignment group name that has access
},
/***
*
* Check if user is member of Application assignment group
*
**/
hasApplicationGroupAccess: function() {
if (!gs.getUserID()) return false; // Not logged in
var userSysId = gs.getUserID();
// Check if user is a member of the application assignment group
var groupMember = new GlideRecord("sys_user_grmember");
groupMember.addQuery("user", userSysId);
groupMember.addQuery("group.name", this.applicationGroupName);
groupMember.query();
if (groupMember.hasNext()) {
if (this.logVariables) {
gs.log("User " + gs.getUserName() + " has access to customPortal via application group membership");
}
return true;
}
if (this.logVariables) {
gs.log("User " + gs.getUserName() + " does NOT have access to customPortal - not in application group");
}
return false;
},
/***
*
* Get the current requested portal from URL
*
**/
getCurrentPortalFromURL: function() {
var uri = gs.getProperty("glide.servlet.uri") || "";
var url = gs.getSession().getURI() || "";
if (url.indexOf("/customPortal") === 0 || url.indexOf("customPortal") > -1) {
return this.customPortal;
}
return null;
},
/***
*
* Fetch the default portal suffix
*
**/
getDefaultPortal: function() {
var gr = new GlideRecord("sp_portal");
gr.addQuery("default", true);
gr.query();
if (gr.next())
return "/" + gr.getValue("url_suffix") + "/";
return "/sp/"; // Default to /sp/ instead of /esc/
},
/***
*
* Get appropriate portal based on user access
*
**/
getPortalForUser: function() {
var requestedPortal = this.getCurrentPortalFromURL();
// If user is trying to access customPortal
if (requestedPortal === this.customPortal) {
if (this.hasApplicationGroupAccess()) {
return this.customPortal;
} else {
// Unauthorized access - redirect to default portal
gs.log("SECURITY: User " + gs.getUserName() + " attempted unauthorized access to customPortal. User is not a member of 'application' assignment group. Redirecting to default portal.");
return this.defaultPortal;
}
}
// For any other portal or default behavior
return this.defaultPortal;
},
/***
*
* Referred to by property: glide.entry.page.script
*
**/
getLoginURL: function() {
// When requesting a page directly (eg: /problem_list.do)
// The platform session_timeout.do sets the login page to welcome.do
// Since we are handling the login, clear that value
var session = gs.getSession();
var nt = session.getProperty("nav_to");
var sPage = session.getProperty("starting_page");
if (nt == "welcome.do")
session.clearProperty("nav_to");
if (!sPage && !nt)
session.putProperty("starting_page", gs.getProperty("glide.login.home"));
// Determine which portal to use based on access control
var portalToUse = this.getPortalForUser();
// Send the user to the portal's login page
var portalGR = new GlideRecord("sp_portal");
portalGR.addQuery("url_suffix", portalToUse.replace(/\//g, ""));
portalGR.addNotNullQuery("login_page");
portalGR.query();
if (portalGR.next())
return portalToUse + "?id=" + portalGR.login_page.id;
// Send to the a default login page
return portalToUse + "?id=login";
},
/***
*
* Referred to by property: glide.entry.first.page.script
*
**/
getFirstPageURL: function() {
var session = gs.getSession();
this.logProperties('before', session);
// Check access control for customPortal
var requestedPortal = this.getCurrentPortalFromURL();
if (requestedPortal === this.customPortal && !this.hasApplicationGroupAccess()) {
gs.log("SECURITY: User " + gs.getUserName() + " denied access to customPortal. User is not a member of 'application' assignment group. Redirecting to default portal.");
session.putProperty("login_redirect", "true");
return this.defaultPortal;
}
// has roles and is not a Service Portal page - go to UI16
var nt = session.getProperty("nav_to");
var isServicePortalURL = new GlideSPScriptable().isServicePortalURL(nt);
var redirectURL = session.getProperty("login_redirect");
if (user.hasRoles() && !redirectURL && !isServicePortalURL)
return;
// user may have logged in from a frame, the /login_redirect.do page will bust out of it
if (!redirectURL) {
// redirectURL is nav_to
// if nav_to == "welcome.do" then use starting_page
var sPage = session.getProperty("starting_page");
if (sPage && nt == "welcome.do")
nt = sPage;
// Avoid a redirect loop to the home page
var ep = gs.getProperty("glide.login.home");
if (nt) {
if (ep == nt)
nt = null;
}
// PRB726860: if page is still welcome.do, go to glide.login.home preserving frameset
if (nt == "welcome.do") {
session.putProperty("nav_to", ep);
return;
}
session.putProperty("login_redirect", nt || "true");
return "/login_redirect.do?sysparm_stack=no";
}
session.clearProperty("login_redirect");
session.clearProperty("nav_to");
if (redirectURL && redirectURL.indexOf("sys_attachment.do") > -1)
return redirectURL;
// Determine return URL based on access control
var portalToUse = this.getPortalForUser();
var returnUrl = portalToUse;
if (redirectURL && redirectURL != "true") {
var spUrl = new GlideSPScriptable().mapUrlToSPUrl(redirectURL);
returnUrl = spUrl ? portalToUse + "?" + spUrl : redirectURL;
if (!user.hasRoles() && !spUrl && redirectURL.indexOf("home_splash.do") > -1)
returnUrl = portalToUse;
}
this.logProperties('after', session);
if (this.logVariables) {
gs.log('redirectURL: ' + redirectURL);
gs.log('User: ' + user.getName());
gs.log('is internal: ' + (!user.hasRoles()));
gs.log('returnUrl: ' + returnUrl);
gs.log('portalToUse: ' + portalToUse);
gs.log('hasApplicationGroupAccess: ' + this.hasApplicationGroupAccess());
}
return returnUrl;
},
logProperties: function(beforeOrAfter, session) {
if (!this.logVariables)
return;
gs.log('SPEntryPage: Redirect ------------------------------- ' + beforeOrAfter);
gs.log('session.starting_page: ' + session.getProperty("starting_page"));
gs.log('session.nav_to: ' + session.getProperty("nav_to"));
gs.log('session.login_redirect: ' + session.getProperty("login_redirect"));
gs.log('gs.fURI: ' + session.getURI());
},
type: 'SPEntryPage'
};
[ Architect | Certified Professional]
Was this response helpful? If so, please mark it as ✅ Helpful and ✅ Accept as Solution to help others find answers.