I’ve written a script that can tie into your environment for Storefront or other web service. This is preferable over the powershell HTTP listener (IMHO) because it can just run on the IIS server and doesn’t need to rely on any external program/service. It’s a simple script to pull out whether a user is a part of a group or not. However, it does require impersonation to be able query Active Directory if your environment does not allow anonymous queries (I believe most do not). Impersonation will make the request come from the machine account, which typically does have authorization to query AD.
In order to set this up, I’ve created a web application in IIS with impersonation set.
1 2 3 4 5 6 7 8 9 10 11 |
cd "%WINDIR%\system32\inetsrv" :: Create application pool appcmd add apppool /Name:"Impersonate" appcmd set config /section:applicationPools -[name='Impersonate'].processModel.identityType:NetworkService :: add web app mkdir C:\inetpub\wwwroot\ADInfo appcmd add app /site.name:"Default Web Site" /path:/ADInfo /physicalPath:C:\inetpub\wwwroot\ADInfo appcmd set app "Default Web Site/ADInfo" -applicationPool:Impersonate appcmd set config "Default Web Site/ADInfo" /section:system.web/compilation /+"assemblies.[assembly='System.DirectoryServices, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a']" |
NOTE: this was run on a Server 2016 box. If your System.DirectoryServices assembly has a different version and public key you will need to update this script with that information.
This script does the following: “Create application pool”
“Add Web App”
And the “appcmd set config” creates our web.config file:
And the GroupMembership.aspx file:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
<% // Created by: Trentent Tye // Creation Date: May 11, 2017 // File Name: GroupMembership.aspx // Description: Checks for specific group membership and returns true or false %> <%@ Page Language="C#" %> <%@ Import Namespace="System.DirectoryServices" %> <% { string parameter = Request.QueryString["DisplayName"]; DirectorySearcher ds = new DirectorySearcher("LDAP://OU=Accounts,DC=bottheory,DC=local"); // must be in the format LDAP://OU=Accounts,DC=bottheory,DC=local ds.Filter = string.Format("(&(objectCategory=person)(objectClass=user)(displayName={0}))", parameter); SearchResult sr; sr = ds.FindOne(); if (sr == null) { //try searching with SamAccountName as Citrix will default to that if the DisplayName isn't populated. // https://citrix.github.io/storefront-sdk/requests/#get-user-name // "If the full user name is unavailable, the user's logon name is returned instead." ds.Filter = string.Format("(&(objectCategory=person)(objectClass=user)(samAccountName={0}))", parameter); sr = ds.FindOne(); } try { var memberGroups = sr.Properties["memberOf"]; string Ret = "true"; foreach(object memberOf in memberGroups) { if ((memberOf.ToString()).Contains("SessionPersistenceDisabled")) { Ret = "false"; } } Response.Write(Ret); } catch (Exception ex) { Response.Write("NotFound"); } } %> |
To call the file, it’s the %hostname%\ADInfo\GroupMembership.aspx?DisplayName=%username%
For example:
And then we just modify our script.js to point to this URL instead:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
function workspaceControlEnabled(username) { //call custom web service which queries LDAP for group membership and returns true for the "EnableWorkspaceControl" group, or false for the "DisableWorkspaceControl" group //if the user is not in either group the default is 'true' CTXS.trace("workspaceControlEnabled"); var result = ""; $.ajax({ type: "GET", url: "../../ADInfo/GroupMembership.aspx?Displayname=" + username, dataType: "text", async: false, success: function (data) { CTXS.trace("workspaceControlEnabled data:" + data); result = data; } }); return result; |