Trying to list the directories and files within a specific folder. This folder will depend on the current user (Page.User) which logs in by Windows Authentication (NTLM) and is retrieved from the Active Directory (homedirectory property).
I am using a domain user to access the AD and retrieve the folder location, this works fine.
What fails is retrieving the sub folders using System.IO.DirectoryInfo.GetDirectories() even with impersonation.
Here's the code I'm using for impersonation:
System.Security.Principal.WindowsImpersonationContext impersonationContext;
impersonationContext = ((System.Security.Principal.WindowsIdentity)User.Identity).Impersonate();
I have checked that the user being impersonated has access to the folder.
From what I have found so far it seems that I either need to set up delegation or Kerberos authentication, is this true? Are these the only ways to achieve this? Shouldn't impersonation be enough?
Impersonation allows the website service account to impersonate (pretend to be) another user on that machine. So querying AD to see what rights you (or the impersonated user) have is allowed.
Requesting access to a UNC share on another machine is asking the other machine to accept that the website service account is acting on behalf of the user being impersonated. This is delegating. The other machine is not checking the users credentials itself but delegating that check to the webserver.
If the client is connecting the the website from yet another machine (normally the case for webservers), then you have a "double hop" from client to webserver to UNC file server.
I'd suggest you need to configure Kerberos (via the SetSPN utility) and look enabling delegation rights for the website service account (witihin AD users and Computers). if you have problems setting this up, I heartily recommend a tool called DeleConfig.
Related
I've got an IdentityServer setup to connect to an external ADFS server. I'm able to login and obtain an access token via OAuth2 / OpenId Connect. An AspNet.Core WebApi runs within an IIS AppPool with a user that has Kerberos delegation enabled (should have, not sure how to check since I'm not into infrastructure).
What I want to achieve is that the ClaimsIdentity I get from IdentityServer on the WebApi is transformed back to a WindowsIdentity using impersonation, without a password. Just a username should be sufficient. With the actual impersonated WindowsIdentity I should then logon to a database and do some mutations.
I'm not sure if this is even possible, but I've been struggling with this for quite some time now.
I took this as a base for the Impersonation implementation. The only problem I have is that the Context.User.Identity doesn't return a WindowsIdentity, but a ClaimsIdentity.
Another approach I tried is using var user = new WindowsIdentity(username); where username would be the UPN. That creates an Identity, with ImpersonationLevel.Identity instead of ImpersonationLevel.Impersonated. When I run WindowsIdentity.RunImpersonated() with this users access token will give an Access Denied, or IOException when loading the needed assemblies.
So first question: how do I check if the IIS AppPool user has the correct Kerberos delegation rights?
Second question: is it even possible to impersonate a user only with a username?
What you're describing is delegation with "any" authentication method. Protocol-wise this is called Service-for-User-to-Proxy. It requires that the service account is granted that right and you need to check the Active Directory service account is configured for that. You also need to indicate which services can receive impersonated connections.
Once you've configured the service account you should restart the machine running the code (things get negatively cached in memory which takes a while to time out). If your app is running in IIS your service account should already be configured to use the correct Windows local privileges to impersonate.
However, keep in mind that this permission gives your application global permissions for whatever service you're requesting a service ticket to. That means your app can impersonate everyone, which is rightfully a little dangerous.
I have two Windows services (one runs as network service and the other runs as local system). And the system in which these services are running are part of domain. These services uses active directory as central store and the idea is to be able to add/remove/read entries from this store.
We are simply using System.DirectoryServices.Protocols.LdapConnection.BeginSendRequest(DirectoryRequest request .... http://msdn.microsoft.com/en-us/library/system.directoryservices.protocols.ldapconnection.beginsendrequest(v=vs.110).aspx ) and passing AddReuest as input to add entries to the Active Directory.
However, the operation is failing with System.DirectoryServices.Protocols.DirectoryOperationException with message The user has insufficient access rights (same error for both network service as well as computer/local system account). But I did add the computer account to the store in Active Directory and granted full permissions on the store. I am not sure what I am missing?
Is it not possible to add/remove entries on active directory even though computer account has granted full permissions? (I thought local system/network service simply pass the computer credentials over network - I have taken quick peek at the following links for reference The difference between the 'Local System' account and the 'Network Service' account? or http://technet.microsoft.com/en-us/library/bb680595.aspx)
Incidentally, please note that as long as I run the service with one of the domain user accounts the operations are passing. And search (read operations) are passing for all the accounts.
You might be mistaking an authentication problem with an authorization problem. Granted, when nothing works, its hard to tell them apart.
The rights you set in AD are probably ok, but you never get there. In the security event log of the computer that hosts the Active Directory, there is probably a access denied for a network logon of \\server_a. On the Active Directory server, give the computer account (SERVER_A) the privilege "Access this computer from the network".
It will solve the authentication part, letting the process acquire an access token that will be used by Active Directory to perform authorization.
If you are in a low volume lab, you can also try to enable Active Directory Diagnostic Logging, with the Security Events registry entry.
I'm going to put this as an answer instead of a comment though I'm not yet sure if it will help.
When approaching permissions issues like this, I tend to think in terms of sets. I'd start by looking at the set of membership provided to your two different test cases, the machine account and service account with something like a powershell script described here: https://stackoverflow.com/a/20410668/44656.
It's possible that your service account has a permission granted via indirect membership that your machine account does not.
If that doesn't shed light on it, you can try enabling auditing on the ActiveDirectory server and looking for the failed access attempts. Usually a failed permission check does a decent job of highlighting why something is being denied. Auditing can be configured via global auditing policy and setting SACLs on specific object(s) you are interested in.
I have a few newbie web service/Windows rights questions since I've typically been a LINUX/embedded dev in the past.
What directories does a web service executing on a server have access to by default?
I ask because I tried to write to C:\ and got an access violation. I kind of assumed I would in this case, but I assume there are some areas of the file system the web service can write to and read from by default, right? Or is it just the current working directory?
*How can I give a web service permissions to look at a new directory it didn't have default access to?*
This is C# - ASMX - .NET 3.5 - IIS
The WebService doesn't really have any associated access controls associated with it (in a sense). It is however tied to the access control of the user account which is being used to run the application. By default this is usually some built in user account with limited permissions.
IIS uses a number of built-in Windows accounts, as well as accounts
that are specific to IIS. For security reasons, you should be aware of
the different accounts and their default user privileges. It can be a
security risk to change the identity of a worker process so that it
runs as an account with a high level of access, such as the
LocalSystem user account.
See a list of possible user accounts here: http://www.microsoft.com/technet/prodtechnol/WindowsServer2003/Library/IIS/3648346f-e4f5-474b-86c7-5a86e85fa1ff.mspx?mfr=true
If you have Anonymous Authentication enabled you can usually check the settings on that to see which account is being used to run the web service. (Depending on which version of IIS you are using, clicking Edit should let you view the default user account)
After finding the account, usually you will have to explicitly grant it the permissions on the folders (read and write) that you want to give it access to. The default user account usually has pretty limited access (and for good reason). You can grant permissions on the Security tab of the properties of any of the folders on a Windows file system (Properties->Security)
If you're using Windows Authentication, then you should have the same access rights as the authenticated user using the application as long as the resources are local to the IIS server.
Currently I have a windows service written in C# (running as LocalSystem) which creates a user account, needed for impersonation, by using the DirectoryEntry to add the user/password and associated UserFlags. Then it simply uses this account to perform some tasks (using impersonation) using the LogonUser() functionality - works perfectly.
However this account should ONLY be used for impersonation by my service, a user should NEVER be able to login (even if he has the credentials) locally or via the network.
To accomplish this I tried setting the Local Policies for “Deny logon locally” and “Deny access to this computer from the network” and added the user my service creates. Now however impersonation fails with the following:
Logon failure: the user has not been granted the requested logon type at this computer (1385)
So, I guess this is NOT the right way to do it … but I need to secure lockdown the account so it can only be used by my service for impersonation purposes and to ensure that no one else can ever logon to the account (even if they have all the credentials).
Is there something in LSA I can use? Or using the DirectoryEntry code similar to when the account was created? Is there a way to allow for an account to exist but not allow users to interactively logon?
Any help would be much appreciated.
Thanks,
You can run the service under the "Network Service" account and grant the server access to the applicable domain resources. Other than that, I am not certain there is a way to solve your problem with a user account.
I get an UnauthorizedAccessException everytime I try to access (just read) a file on a network share "\\server\folder1\folder2\file.pdf."
I am impersonating the domain\aspnet user which has read & write access to the above mentioned folders. The file is not read-only.
I tried finding the permissions via System.Security.Permissions.FileIOPermission. It just says NoAccess to all files.
I'm not sure what else I can do.
I am using Visual Studio 2008, ASP.net 2.0 on Framework 3.5, WinXP, IIS 5.1.
ASP.NET user will not work with network path. So you need to have a windows account that
will have all the rights and then you need to imposernate things in web.config like following.
<identity impersonate="true" userName="domainname\windowuseraccount" password="password"/>
I'll assume you have set up the impersonation properly. You have turned off anonymous access, set the authentication mode to Windows and set impersonation to true, etc.
Even with all that done properly and the correct account impersonating you will still not be able to access the file. The account being impersonated is using what are called network credentials. These are only valid on the machine on which the impersonation is taking place. When you attempt to access a file on the computer itself the access is performed with the user's credentials but for a file on a share the access is done as a non-authenticated user and so no access is allowed.
In order to allow you to use the user's credentials for remote work, i.e. accessing a share, integrated security for a remote database, etc. you need to use delegation rather than impersonation. This is a somewhat complicated topic involving your Active Directory set-up and your IIS configuration. Have a look at this article, it should give you a good place to start.
Make sure that the domain user has Security rights and Share rights. That is, on the shared folder, add the domain user under the "Sharing" tab in the properties, as wells as under the "Security" tab.
What IIS version are you using? If it is version 6, you can place the web app in it's own application pool, then set the identity of that application pool to be a domain user account. Then, grant that domain user account access to the network share.
FYI you can place the following in an aspx file to verify what identify your pages are running as:
<%# Page Language="C#" %>
<% Response.Write(System.Security.Principal.WindowsIdentity.GetCurrent().Name); %>
To access a network share the above user will need to be a domain account setup by a network administrator.