根据用户的Active Directory组设置对下拉列表项的访问权限

时间:2011-04-20 13:24:49

标签: asp.net vb.net web-services active-directory windows-authentication

背景:我有一个webForm应用程序,它根据Web服务提供的信息在数据库中注册用户,自动生成随机密码和用户名,并通过电子邮件向用户发送基于以下内容的链接以获取应用程序营销公司选择了。

问题:

  • 如何只显示当前登录用户的组以显示在MarketingCo_DropDownList

允许访问系统的每个用户都将拥有web.config定义的至少一个营销组的成员资格。例如,当前登录并属于位置“alg \ ACOMP_user_BIG”下的BIG组的用户将只能在Marketing Company下拉列表中看到BIG。当前登录并属于位于“alg \ ACOMP_user_NIS”下的NIS组的用户只能在Marketing Company下拉列表中查看NIS。

这是前端的截图: web app screenshot

这是我的最佳猜测(位于default.aspx.vb中的Private Sub GetMarketingCompanies()方法下):

    If InStr(WindowsIdentity.GetCurrent().Groups = "AMG", item.MarketingCompanyShort = "AMG", CompareMethod.Text) Then
            marketingCo.Items.Add(String.Format("{0} | {1}", item.MarketingCompanyShort, item.MarketingCompanyName))

            For Each item In ac1
                 marketingCo.Items.Add(String.Format("{0} | {1}", item.MarketingCompanyShort, item.MarketingCompanyName))
        Next
    Catch ex As Exception
        MsgBox(ex.Message)
    End Try

我一直在关注Wrox's Windows Authentication Tutorial的代码,但对于我正在尝试做的事情来说还不够彻底。

Web.config文件(仅显示相关代码):

 <authentication mode="Windows"/>
   <authorization>            
    <allow users="alg\bmccarthy, alg\phoward" />               
    <allow roles="alg\ACOMP_user_Admin" />
    <allow roles="alg\ACOMP_user_AMG" />
    <allow roles="alg\ACOMP_user_BIG" />
    <allow roles="alg\ACOMP_user_NIS" />
    <allow roles="alg\ACOMP_user_GLA" />
    <allow roles="alg\ACOMP_user_PIP" />
    <allow roles="alg\ACOMP_user_PSM" />
    <allow roles="alg\ACOMP_user_PAM" />
    <allow roles="alg\ACOMP_user_ANN" />
    <allow roles="alg\ACOMP_user_AAM" />
    <allow roles="alg\ACOMP_user_MWM" /> 
    <allow roles="alg\ACOMP_user_GIM" />
    <deny users="*" />        
</authorization> 
   <bindings>
   <basicHttpBinding>
    <binding name="BasicHttpBinding_IAcompService" closeTimeout="00:01:00"
      openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
      allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
      maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
      messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
      useDefaultWebProxy="true">
      <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
        maxBytesPerRead="4096" maxNameTableCharCount="16384" />
      <security mode="None">
        <transport clientCredentialType="None" proxyCredentialType="None"
          realm="" />
          <message clientCredentialType="UserName" algorithmSuite="Default" />
        </security>
      </binding>
    </basicHttpBinding>
  </bindings>
  <client>
  <endpoint address="http://172.17.1.40/aCompService.svc" binding="basicHttpBinding"
    bindingConfiguration="BasicHttpBinding_IAcompService" contract="aComp_ServiceReference.IAcompService"
    name="BasicHttpBinding_IAcompService" />
  </client>
 </system.serviceModel>

default.aspx.vb代码w / GetMarketingCompanies()和Page_Load()方法,应用程序从Web服务检索MarketingCompanies并通过数组将其加载到下拉列表中:

Private Sub GetMarketingCompanies()
    Try
        Dim ac1 As Array
        ac1 = proxy.GetMarketingCompanyNames("acompUser", "acompPass!")


        ' If InStr(WindowsIdentity.GetCurrent().Groups = "AMG", item.MarketingCompanyShort = "AMG", CompareMethod.Text) Then
        '  marketingCo.Items.Add(String.Format("{0} | {1}", item.MarketingCompanyShort, item.MarketingCompanyName))

        ' if current user role="alg\ACOMP_user_BIG" display BIG MarketingCo.Item '
        ' if current user role="alg\ACOMP_user_NIS" display NIS MarketingCo.Item '
        ' if current user role="alg\ACOMP_user_GLA" display GLA MarketingCo.Item '
        ' if current user role="alg\ACOMP_user_PIP" display PIP MarketingCo.Item '
        ' if current user role="alg\ACOMP_user_PSM" display PSM MarketingCo.Item '
        ' if current user role="alg\ACOMP_user_PAM" display PAM MarketingCo.Item '
        ' if current user role="alg\ACOMP_user_ANN" display ANN MarketingCo.Item '
        ' if current user role="alg\ACOMP_user_AAM" display AAM MarketingCo.Item '
        ' if current user role="alg\ACOMP_user_MWM" display MWM MarketingCo.Item '
        ' if current user role="alg\ACOMP_user_GIM" display GIM MarketingCo.Item '

        ' if current user = alg\ACOMP_user_Admin display all marketing companies in drop down list '
        For Each item In ac1
            marketingCo.Items.Add(String.Format("{0} | {1}", item.MarketingCompanyShort, item.MarketingCompanyName))
        Next
    Catch ex As Exception
        MsgBox(ex.Message)
    End Try
End Sub

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load, Me.Load, Me.Load
    If Not lbCarriers.Items.Count > 0 Then
        GetCarriers()
        GetMarketingCompanies()
    End If
End Sub

Default.aspx代码,其中定义了marketingCo下拉列表:

<table>
    <tr>
        <td class="style3">
            Marketing Co (auto-populated):
        </td>
        <td bgcolor="#ffffff" class="style8">
            <asp:DropDownList ID="marketingCo" runat="server" Height="23px" 
                Width="250px">
            </asp:DropDownList>
        </td>
    </tr>
        <td bgcolor="#ffffff" class="style6">
            <asp:Button ID="Send_Button" runat="server"  Text="Send Invitation" />
        </td>
    </tr>
</table>

Web服务返回一个带有MarketingCompanyShort和MarketingCompanyName的字符串数组,这些字符串作为项添加到下拉列表中 Web服务XSD文件代码:

<xs:element name="ArrayOfMarketingCompany" type="tns:ArrayOfMarketingCompany" nillable="true"/>
<xs:complexType name="MarketingCompany">
    <xs:sequence>
        <xs:element name="MarketingCompanyId" type="xs:int" minOccurs="0"/>
        <xs:element name="MarketingCompanyName" type="xs:string" nillable="true" minOccurs="0"/>
        <xs:element name="MarketingCompanyShort" type="xs:string" nillable="true" minOccurs="0"/>
    </xs:sequence>
</xs:complexType>

感谢您的期待!

如果您有任何有用的链接或建议,我会给您一个投票!

2 个答案:

答案 0 :(得分:1)

我不确定我是否完全遵循;您是否将每个组名与特定营销公司相匹配?因为这个链接不是保存在Active Directory的任何地方,只是你匹配每个文本的文本?

如果是这种情况,我认为你只想查看windows itentitfy返回的组。那样的事情呢?

For Each UserGroup in WindowsIdentity.GetCurrent().Groups
  If UserGroup.Value = "AMG" Then
    Dim Company= ac1.Cast(Of [TypeOfItemHere]).Where(Function(ac) ac.MarketingCompanyShort = "AMG").FirstOrDefault
    If Company IsNot Nothing Then
      marketingCo.Items.Add(String.Format("{0} | {1}", Company.MarketingCompanyShort, Company.MarketingCompanyName))
    End If
  End If
Next

......等等其他团体。也就是说,将WindowsIdentitiy.GetCurrent()。组传递给您的服务可能会更好,并在那里进行过滤。

答案 1 :(得分:0)

IdentityReference.Value返回当前用户的SID(例如:S-1-5-32-544)而不是组名(例如:Acomp_user_BIG)。

您需要使用IdentityReference.Translate来转换 WindowsIdentiy.Groups返回NTAccounts的安全标识符(SID)

以下是输出当前用户所属的所有组名的代码:

Public ReadOnly Property Groups As IdentityReferenceCollection
    Get
        Dim identityReferenceCollection As IdentityReferenceCollection
        Dim identityReference As IdentityReference
        identityReferenceCollection = WindowsIdentity.GetCurrent().Groups
        Dim strGroupName As String
        Dim mcisloaded As Boolean

        ' Translate the current user's active directory groups 
        For Each identityReference In identityReferenceCollection
            Dim mktGroup As IdentityReference = identityReference.Translate(GetType(NTAccount))
            ' MsgBox(mktGroup.Value)

            strGroupName = mktGroup.Value.ToString
         Next    

    End Get
End Property