-->

Set Access to dropdownlist items based on the User

2020-07-27 06:29发布

问题:

Background: I have a webForm app that registers a user in the database based on the information provided with a web service, auto-generates a random password and username, and e-mails the user a link to take an application based on the marketing company selected.

Questions:

  • How do I get only the currently logged in user's groups to show up under the MarketingCo_DropDownList

Each user allowed access to the system will have membership in at least one of the marketing groups as defined by the web.config. For example, a user that is currently logged in and belongs to the BIG group under location "alg\ACOMP_user_BIG", will only be able to see BIG in the Marketing Company drop down list. A user that is currently logged in and belongs to the NIS group located under "alg\ACOMP_user_NIS" will only be able to see NIS in the Marketing Company drop down list.

Here's a screenshot of the front end:

Here's my best guess (located under Private Sub GetMarketingCompanies() method in default.aspx.vb):

    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

I've been going off the code from Wrox's Windows Authentication Tutorial but it's not thorough enough for what I'm trying to do.

Web.config file (pertinent code displayed only):

 <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 code w/ the GetMarketingCompanies() and Page_Load() Methods where the application retrieves MarketingCompanies from the webservice and loads it into the dropdownlist through an array:

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 code where the marketingCo drop down list is defined:

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

The Web service returns an Array of Strings w/ MarketingCompanyShort and MarketingCompanyName that are added as items to the drop down list Web Service XSD File Code:

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

Thanks for looking!

If you have any helpful links or suggestions, I'll give you an up-vote!

回答1:

I'm not sure that I quite follow; are you matching each group name to a particular marketing company. In that this link isnt saved in Active Directory any place, just by you matching up the text of each?

If thats the case I think you just want to check what groups are returned by the windows itentitfy. So somthing like this?

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

...And so on for the other groups. That being said it would probably be better to pass the WindowsIdentitiy.GetCurrent().Groups to your service instead and do the filtering there.



回答2:

IdentityReference.Value returns the current user's SID's (ex: S-1-5-32-544) not the group name (ex: Acomp_user_BIG).

You need to use IdentityReference.Translate to convert the Security Identifiers (SID's) that WindowsIdentiy.Groups returns into NTAccounts

Here is code that will output all the group names that the current user belongs to:

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