2009-08-12 3 views
0

service d'indexation est mis en place sur notre serveur de fichiers pour indexer un dossier de deux douzaines de (appelés « scopes » dans la terminologie du service d'indexation), dont tous ne sont accessibles à tous les utilisateurs . J'ai un script de recherche ASP fonctionnant sous IIS avec l'authentification intégrée de Windows, ce qui signifie que lorsqu'un utilisateur connecté au réseau utilise la page de recherche, il ne voit que les résultats auxquels il a l'autorisation d'accéder. C'est une bonne chose.service d'indexation Windows - Liste des étendues accessibles à l'utilisateur actuel

Mais comment puis-je montrer à l'utilisateur une liste des champs auxquels ils ont accès à? (En d'autres termes, une liste des dossiers qui seront recherchés). Les étendues peuvent être énumérées par programmation en utilisant l'objet CatAdm, mais cela nécessite des permissions d'administrateur que mon script ASP n'a pas, et de toute façon il ne me dit pas si l'utilisateur actuel a ou non accès. J'ai essayé l'astucieuse astuce d'activer l'indexation des répertoires (le paramètre de registre FilterDirectories) et ensuite faire une requête pour les répertoires seulement ("@Attrib^a 0x10", pour vérifier l'indicateur d'annuaire dans les attributs du fichier), mais bien sûr cela me donne aussi des sous-répertoires ... Je pourrais parcourir les résultats et prendre seulement les meilleurs répertoires, mais cela semble mettre beaucoup de charge sur le serveur juste pour générer cette liste simple. De plus, j'ai configuré alias afin que le service d'indexation retourne des chemins de réseau au lieu des chemins locaux, mais il me semble avoir rencontré un service d'indexation bug car l'alias est appliqué à tout sauf haut niveau eux-mêmes répertoires.

Quelqu'un at-il des meilleures suggestions?

Répondre

0

Jusqu'à présent, cette question a seulement eu 7 vues, et m'a valu le badge "Tumbleweed", mais néanmoins j'ai pensé que je suivrais avec une explication de ma solution finale. L'utilisation de l'objet CatAdm était vraiment la seule option à la fin, parce que c'est la seule façon de contourner le bogue dans le service d'indexation lié aux alias (mentionné dans mon article original). Une méthode (qui est relativement facile dans ASP.NET, et possible dans ASP Classic avec l'utilisation d'un composant COM personnalisé d'équivalent) serait d'utiliser l'emprunt d'identité: utiliser un compte privilégié pour lire la liste des étendues du Objet CatAdm, puis utilisez le compte de la requête HTTP autorisée pour effectuer une requête sur ces étendues. Les résultats contiendront uniquement les répertoires auxquels ce compte a accès.

Le problème est que seuls les comptes d'administrateur ont l'autorisation d'utiliser l'objet CatAdm, et en utilisant un compte administrateur pour répondre aux requêtes HTTP ne sont pas bonnes pratiques, d'un point de vue de la sécurité. Donc, bien que cela ajoute au fardeau administratif, j'ai décidé d'écrire un script HTA séparé qui doit être exécuté (sur le serveur lui-même, pas via HTTP) chaque fois que des répertoires sont ajoutés ou supprimés du catalogue. Le script lit la liste des champs d'application de l'objet CatAdm et l'écrit dans un fichier de configuration:

Function makeConfig(catalogName) 
     Set machine = CreateObject("Shell.LocalMachine") 
     Set adm = CreateObject("Microsoft.ISAdm") 
     Set cat = adm.GetCatalogByName(catalogName) 

     Dim config 
     config = "<%" & vbCrLf 
     config = config & "' Automatically generated by " & document.location.pathname & " at " & Now & vbCrLf 
     config = config & "' This file is indended for inclusion by the intranet search script." & vbCrLf 
     config = config & "catalogMachine = """ & machine.MachineName & """" & vbCrLf 
     config = config & "catalogName = """ & catalogName & """" & vbCrLf 

     scopeFound = cat.FindFirstScope() 
     While scopeFound 
      Set scope = cat.GetScope() 
      If Not scope.ExcludeScope Then 
       ' Must be lowercase because query results are returned in lowercase 
       dir = lcase(scope.Path) 
       If scope.Alias <> "" Then 
        alias = scope.Alias 
       Else 
        alias = scope.Path 
       End If 

       config = config & "dirs(""" & dir & """) = """ & alias & """" & vbCrLf 
      End If 
      scopeFound = cat.FindNextScope() 
     Wend 

     config = config & "%>" & vbCrLf 
     makeConfig = config 
    End Function 

Ensuite, le script de recherche lui-même se contente de lire le fichier de configuration et utilise pour trouver la liste des répertoires accessibles. Pour contourner le bogue du service d'indexation, il est nécessaire de mapper du répertoire physique à l'alias:

Set dirs = CreateObject("Scripting.Dictionary") 
%><!--#include file="search_config.asp"--><% 
catalogURI = "query://" & catalogMachine & "/" & catalogName 

queryString = "" 
For Each dir In dirs 
    If queryString <> "" Then 
    queryString = queryString & " or " 
    End If 
    queryString = queryString & "@Path = """ & dir & """" 
Next 

' But the @Path attribute is not indexed, and running queryString 
' as is will return no results. Solution: limit search to only 
' directories, i.e. items with the 0x10 flag set in @Attrib. 
queryString = "@Attrib ^a 0x10 and (" & queryString & ")" 

' No point asking for sorted query results, because we need 
' to map the results from real paths to network aliases and 
' sort again ourselves. 
Set query = Server.CreateObject("ixsso.Query") 
query.Catalog = catalogURI 
query.Query = queryString 
query.Columns = "path" 
query.MaxRecords = dirs.Count 
Set rs = query.CreateRecordSet("sequential") 

i = 0 
Do While Not rs.EOF 
    ReDim Preserve accessibleAliases(i) 
    accessibleAliases(i) = dirs(rs("path").Value) 
    i = i + 1 
    rs.MoveNext 
Loop 
rs.Close 

BubbleSort accessibleAliases 
Questions connexes