Restrict Access to Custom Portal Based on Assignment Group

Rajesh Bandila
Tera Contributor

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

4 REPLIES 4

Shruti
Mega Sage
Mega Sage

Hi @Rajesh Bandila 

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);

 

Ankur Bawiskar
Tera Patron
Tera Patron

@Rajesh Bandila 

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.

Regards,
Ankur
Certified Technical Architect  ||  9x ServiceNow MVP  ||  ServiceNow Community Leader

@Rajesh Bandila 

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.

Regards,
Ankur
Certified Technical Architect  ||  9x ServiceNow MVP  ||  ServiceNow Community Leader

Chavan AP
Tera Guru

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'
};

 

Chavan AP
[ Architect | Certified Professional]

Was this response helpful? If so, please mark it as Helpful and Accept as Solution to help others find answers.