2009-08-12 3 views
0

Служба индексирования настроена на нашем файловом сервере, чтобы индексировать пару десятков папок (называемых «областями» в терминологии службы индексирования), не все из которых доступны для всех пользователей , У меня есть сценарий поиска ASP, работающий под IIS с интегрированной аутентификацией Windows, а это означает, что когда пользователь, войдя в сеть, использует страницу поиска, они будут видеть только те результаты, к которым у них есть разрешение на доступ. Это хорошая вещь.Служба индексирования Windows - список областей, доступных для текущего пользователя

Но как я могу показать пользователю список областей, к которым у них есть доступ? (Другими словами, список папок, которые будут искать). Области могут быть перечислены программным путем с использованием объекта CatAdm, но для этого требуются разрешения администратора, которые мой ASP-сценарий не имеет, и в любом случае он не говорит мне, имеет ли текущий пользователь доступ или нет.

Я пробовал умный трюк, позволяющий индексировать каталоги (параметр реестра FilterDirectories), а затем делать запрос только для каталогов («@Attrib^a 0x10», чтобы проверить флаг каталога в атрибутах файла), но, конечно, это также дает мне подкаталоги ... Я мог бы пропустить результаты и взять только топ-каталоги, но, похоже, накладывает большую нагрузку на сервер, чтобы создать этот простой список. Более того, я настроил псевдонимы, чтобы служба индексирования возвращала сетевые пути вместо локальных путей, но я, похоже, столкнулся с ошибкой службы индексирования, потому что псевдоним применяется ко всему , за исключением самих каталогов верхнего уровня.

Есть ли у кого-нибудь лучшие предложения?

ответ

0

Пока этот вопрос имеет только 7 просмотров и заработал мне значок «Tumbleweed», но тем не менее я думал, что продолжу объяснение своего окончательного решения.

Использование объекта CatAdm действительно было единственным вариантом в конце, потому что это единственный способ обойти ошибку в службе индексирования, связанную с псевдонимами (упоминается в моем первоначальном сообщении).

Один метод (который относительно простой в ASP.NET и возможен в ASP Classic с использованием пользовательского COM-компонента эквивалента) заключается в использовании олицетворения: используйте привилегированную учетную запись для чтения списка областей из CatAdm, затем используйте учетную запись разрешенного HTTP-запроса для выполнения запроса по этим областям. Результаты будут содержать только те каталоги, к которым эта учетная запись имеет доступ.

Проблема заключается в том, что только учетные записи администратора имеют разрешение на использование объекта CatAdm, а использование учетной записи администратора для обслуживания HTTP-запросов не является хорошей практикой с точки зрения безопасности.

Итак, хотя это добавляет к административной нагрузке, я решил написать отдельный сценарий HTA, который должен быть запущен (на самом сервере сервера, а не через HTTP) в любое время, когда каталоги будут добавлены или удалены из каталога. Скрипт считывает список областей из объекта CatAdm и записывает его в файл конфигурации:

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 

Тогда сам скрипт поиска просто считывает конфигурационный файл и использует это, чтобы найти список доступных каталогов. Чтобы обойти ошибку службы индексирования, необходимо отобразить из физического каталога в псевдоним:

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