Active Directory authority needed in SharePoint Web Part

J

Jondis

I've been working on a Web Part that can update Active
Directory for some time.

I'm trying to give SharePoint administrators the ability
to add users (which requires the user to be in Active
Directory before he is added to SharePoint). I also want
to give regular users the ability to update their Active
Directory password from within SharePoint.

So far, I've successfully encapsulated my Active
Directory code into a DLL and installed it into the GAC
with the AllowPartiallyTrustedCallersAttribute.

Calling into my Active Directory object from a regular
ASP.NET web application (.ASPX page) works PERFECTLY:
Adds, Updates, Deletes.

However, when I try to call the Active Directory object
from SharePoint I get security errors:

When I simply try to load an Active Directory
DirectoryServicesEntry:

System.UnauthorizedAccessException
General access denied error
StackTrace " at
System.DirectoryServices.Interop.IAdsContainer.GetObject
(String className, String relativeName)
at System.DirectoryServices.DirectoryEntries.Find
(String name, String schemaClassName)
at DirectoryServicesHelper.UserAdmin.LoadUser(String
username)
at Evolve.SharePoint.PortalUser.GetADUser() in \\TC2
\Users\Jonathan Discount\My Documents\Visual Studio
Projects\Evolve.SharePoint.UserAdministration\Evolve.Share
Point.PortalUser.vb:line 55 at
Evolve.SharePoint.UserAdministration.btnSaveChanges_Click
(Object sender, EventArgs e) in \\TC2\Users\Jonathan
Discount\My Documents\Visual Studio
Projects\Evolve.SharePoint.UserAdministration\Evolve.Share
Point.UserAdministration.vb:line 678" String

When I get a little more ambitious and try to save to
Active Directory:

System.Runtime.InteropServices.COMException
Unspecified Error
StackTrace " at
System.DirectoryServices.Interop.IAdsContainer.Create
(String className, String relativeName)
at System.DirectoryServices.DirectoryEntries.Add
(String name, String schemaClassName)
at DirectoryServicesHelper.UserAdmin.SaveUser(DSUser
dsUser)
at Evolve.SharePoint.PortalUser.Save(String fullName)
in \\TC2\Users\Jonathan Discount\My Documents\Visual
Studio
Projects\Evolve.SharePoint.UserAdministration\Evolve.Share
Point.PortalUser.vb:line 63" String

I've made a number of modifications to SharePoint's
security settings via a Custom Policy File, including
adding:
<SecurityClass Name="DirectoryServicesPermission"
Description="System.DirectoryServices.DirectoryServicesPer
mission, System.DirectoryServices, Version=1.0.5000.0,
Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"/>

Next, I created a NamedPermissionSet for my Web Part:
<PermissionSet class="NamedPermissionSet" version="1" Name="856644171da596d2">
<IPermission class="AspNetHostingPermission" version="1" Level="Medium" />
<IPermission class="SecurityPermission" version="1" Flags="AllFlags" />
<IPermission class="WebPartPermission" version="1" Connections="True" />
<IPermission class="DirectoryServicesPermission" version="1"
Unrestricted="True" />
<IPermission class="SharePointPermission" version="1" ObjectModel="True" />
<IPermission class="SqlClientPermission" version="1" Unrestricted="True" />
</PermissionSet>

Finally, I added a UnionCodeGroup (it's the first one):
<CodeGroup class="UnionCodeGroup" version="1"
PermissionSetName="856644171da596d2">
<IMembershipCondition version="1" AssemblyVersion="1.0.0.0"
Name="Evolve.SharePoint.UserAdministration"

class="StrongNameMembershipCondition"

PublicKeyBlob="0x002400000480000094000000060200000024000052534131000400000100010087992946CC13DCBBF3984C463A24970597
1BF1FED8F874CAC4C1EAA5BBFCFF7B8922D30BBE26BE7BA0838D5283D8B81A06399A176A473C292704EE4C5C0C2F0C2F39E903F1627233D53F2CFE28D6943

AE5FED8B75DC53AD41B5484C06750F955B7392D7700DF222A60CFE8D297ABEE9C5F5D53839D40A08FF3FBAE0BF09CED5" />
</CodeGroup>

I experimented with impersonation in the web.config file
but it caused problems elsewhere: SharePoint's default is
<identity impersonate="true" />. I added an
administrator account to the identity declaration and I
got a little farther: I could query AD, but not update
it. However, the impersonation screwed up "My Site".
Everytime I went to "My Site" it would load the
administrator's personal site (regardless of which
account I'd used to log in). So impersonation is back to
the default:
<identity impersonate="true" />
(no account specified).

What other modifications do I need to make to the
SharePoint security config to authorize my Web Part for
Active Directory?

PLEASE HELP!!!

Thanks,
JD
 
J

Joe Kaplan \(MVP - ADSI\)

These errors are not related to Code Access Security (CAS) or the
DirectoryServicePermission. All of these errors are related to the security
context that is performing operations on AD.

Since your code needs to run in SharePoint, you need to use impersonation,
so unless you are using basic authentication, you are going to need Kerberos
delegation to get the user's security context to successfully hop to a
different machine. There are more details here:

http://support.microsoft.com/default.aspx?scid=kb;en-us;329986

Joe K.
 
J

Jondis

Joe,

Thanks for the post, but I'm confused. I've read that article before -- but
it is not clear which direction I need to go:
1. I've already changed the impersonation username/password in the
SharePoint web.config.
This didn't entirely allow the AD access and it screwed up SharePoint:
Whenever I went to My Site, the site that came up was for the account placed
in the impersonate tag -- not the username I had logged in with.

2. Do I change the account SharePoint's app pool runs under? Or do I
change the account IIS uses to run the application? How can I solve my
delegation problem?

3. There was nothing in the document about Kerberos... can you give me an
idea of what you had in mind?

4. Our backup plan: We've been talking about doing this task the opposite
way:
Instead of a SharePoint Web Part that has to talk to Active Directory, make
a separate ASP.NET application that has to talk to SharePoint
(since I've been able to do my AD updates from a regular ASP.NET
application). The new ASP.NET application can be authenticated by Active
Directory.
Once authenticated, the 1st thing the ASP.NET application will do is call
back into SharePoint, make sure the AD User has a SharePoint account and that
account is an Administrator account. If not, it can kick the user out.
Sounds simpler. What do you think?

Thanks in advance for all of your help!
JD
 
J

Joe Kaplan \(MVP - ADSI\)

I think the separate site might be a good idea.

With SharePoint, you have to let impersonation work or it doesn't work.
Therefore, the security context you have to work with will be the user's
security context, but that will be an impersonation-level token because you
are using WIA. Impersonation tokens can't hop to a different machine (the
double-hop issue), so you need Kerberos delegation enabled in order to get
that to happen.

Here is another article on Kerberos delegation in ASP.NET:
http://support.microsoft.com/default.aspx?scid=kb;en-us;810572

You may not want to go through the trouble though. In that case, I don't
think you'll get this to work. The only other option I can think of would
be to prompt the user for the password and then use explicit credentials in
your DirectoryEntry objects, but obviously that is kind of icky.

You could also switch to Basic auth and SSL, but no one likes that either.

HTH,

Joe K.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,756
Messages
2,569,535
Members
45,007
Latest member
OrderFitnessKetoCapsules

Latest Threads

Top