Access TFS via its API using Windows Authentication - asp.net

All,
I am using the ASP.Net MVC 4 application.
I have enabled Windows Authentication.
Till now it is working fine.
Now I enhanced the application to connect to TFS via its API.
For this, I need to use the windows authentication credentials.
I have tried using
ICredentialsProvider credential = new UICredentialsProvider();
TfsTeamProjectCollection teamProjectCollection = new TfsTeamProjectCollection(collectionUri, credential);
This works great in the development environment. But when I host the application in IIS 8.5, it is not working at all under "Application Pool Identity" and "Network Service" account.
I tried with Local System and specific user in identity of application pool, it is working.
But I need this to work based on the windows credential (Active directory).
Can anyone suggest a solution?

You can deploy your web application on the TFS App Tier and configuring its app pool to run as the same identity as the TFS web services, and enable ASP.NET impersonation. Check this case: ASP.NET MVC3 Windows Authentication Pass Through to TFS

You are likely hitting a Kerberos double hope issue.
You have two options to resolve it:
Host your mvc web app on the same server as tfs
Configure Active Directory to allow your servers identity to delegate the logged in user credentials to another service.
#1 is easy but #2 will require a bunch of work for your Active Directory domain administrators.
https://support.microsoft.com/en-us/kb/810572
You will need:
At least one Service Principal Name (SPN) configured for your server's account (either a dedicated domain\svc_myaccout or the domain\servername$ account for Network Service).
The account you use needs to be enabled to allow delegation in AD
The server that hosts your application needs to be enabled for delegation
This is not 101 and in my experience, having done this a bunch in enterprise and small business, that most Domain Administrators don't know how Kerberos delegation works, or how to configure it.
You will need to learn how and make explicit requests that they can action. Like "run 'setspn myapp.mydomain.com domain\myserviceaccount'".

Related

Implementing ASP.Net impersonation/delegation to connect to remote SQL Server from ASP.Net server not working

I'm trying to set up impersonation/delegation for a web application using ASP.NET 4.5/SQL Server 2016. The goal is to use the Windows authentication on the web application and the SQL Server.
I reproduced on Azure a setup similar to the one which will be used for production, but I can't seem to find what is making the impersonation not working.
Azure VM #1 [machine name: test-iis-server]: Windows Server 2012 running IIS 8.5 and acting as Active Directory Domain Controller
Azure VM #2 [machine name: test-sql-server]: Windows Server 2016 running SQL Server 2016
Azure VM #3 [machine name: test-client]: Windows 10 machine for simulating a user connecting to the website
I created an Active Directory domain named TEST. It is possible to connect to the 3 machines with users created in Active Directory.
IIS Web server configuration:
In the web.config file:
Authentication mode = Windows
Identity impersonate = True
validation validateIntegratedModeConfiguration = False
Integrated security = SSPI
In IIS Manager:
Windows authentication = Enabled (Kernel-mode authentication = Disabled, Providers = Negotiate:Kerberos)
ASP.NET Impersonation = Enabled
Application pool = Integrated Managed Pipeline (Identity = Custom Identity: test\my-svc-account)
In Active Directory Users & Computers
For each computers (web server, sql server and user computer), I went into Properties and checked in the Delegation tab Trust this
computer for delegation to any service (Kerberos only).
SQL Server Configuration
I did not setup anything here. I assumed that ASP.NET will use the credentials of the user logged in the web application to access the
SQL Server database.
Edit: SQL Server service account: test\my-svc-account
Results:
If I don't use impersonation in the web application and use a defined user/pwd login created in SQL Server, my application works normally and I can get the Windows user credential if I want.
Using impersonation, I get a SQL Server connection error when I open the web application page: Login failed for user 'TEST\test-iis-server$'.
Expected behavior:
The web application will log into SQL Server using the credentials used to log into the "test-client" machine.
I've read a lot on how to implement the impersonation/delegation for my solution, but can't seem to find what's wrong. Anyone has any idea where the proble might come from and how I can resolve it?
Edit #1:
From what I've read, it seems like I need to setup SPNs. I'm confused about how to set them up correctly for my double-hop scenario.
I have created a user account in Active Directory to act as a service account. I've set this account to be trusted for delegation.
I use this account as the identity for my application pool in IIS and as the service account of the SQL Server instance.
Yes, you do need to configure SPNs for both the ASP.NET app pool identity, and the SQL Server service account.
It's relatively straightforward, but you need to make sure you get the right values.
In AD Users and Computers find the 'my-svc-account' account and open the properties. Navigate to the attribute editor tab (if you don't see it, enable advanced features through the ADUC 'View' menu). Find the servicePrincipalName attribute and edit it. Add the following:
http/servicename.foo.com
http/servername <== optional
Where service.foo.com matches your DNS name. If this is a CNAME, you need to also include the underlying A record name as well. So if servicename.foo.com maps to whatever.cloudapp.net, you need to add an SPN for whatever.cloudapp.net. This is for IE, because IE is ...dumb... and trying to be smart (it resolves the DNS down to lowest named record and requests an SPN for that).
Then do the same for the SQL Server service account.
MSSQLSvc/sqlserver.foo.com
MSSQLSvc/sqlserver <== optional
This needs to be the FQDN of the SQL Server host.
Lastly, you need to enable Constrained Delegation between the App Pool identity and the SQL Server service account. This is the 3rd radio button in the delegation control. Add the SQL Server SPN as a delegated target.
Restart IIS and SQL. Try browsing to the app. You should now see it connect to SQL as your named user.

Can't get rid off "Login failed for user IIS APPPOOL\NETWORKSERVICE"

I'm trying to access a sql server database from an ASP NET app configured to work with IIS.
I have several questions now,
1) Authentication in IIS: I need to know if my authentication settings for the site are ok:
I tried with Windows Authentication set to Disabled, but the problem continues.
2) Are the settings for the user NT AUTHORITY\Sericio de red well configured? ("Servicio de red" means Network Service)
3) When I added the login for network service, I only found "Servicio de red", I guess it's the equivalent for NetworkService, I'm I right?, My windows 7 ultimate is an spanish version, I just changed the windows interface by using a windows upgrade to make it appear in english. Is there a problem with it?, I guess it's right because the access to the database is being done through the IIS APPPOOL\Servicio de red user.
My DefaultAppPool identity is set to to AppPoolIdentity
If you want to see what I have tried, see this thread.
The whole project, along with a backup of the database I'm using can be found here, called MyServiceSolutionInIIS
What I'm trying is to build a WCF Data Service that offers information that comes from an entity data model generated from a sql server database. This service will be used by a WPF App as a client.
I'd like to avoid creating a user for it, I think it can be done with the App Pool
Okay so the way this works is, whatever application pool your endpoint is running under passes its credentials to the SQL Server. So, you have two options:
Run the default application pool under NetworkService, or;
Use SQL Authentication when connecting with your web service to the SQL Server.
Honestly, the latter is the most common, but in your situation you may be just fine by changing the default application pool to run under NetworkService.
This has nothing to do with the authentication you've chosen (well, mostly nothing.. you can control which credentials anonymous users run under). Every website runs in an app pool, and this app pool has an AppPoolIdentity.
I'm a little confused as to why it would be claiming it's IIS AppPool\NetworkService, since NetworkService should be NT AUTHORITY\NetworkService, or IIS AppPool\MyAspService or IIS AppPool\DefaultAppPool.
There is a lot more information on App Pool Identities here:
http://www.iis.net/learn/manage/configuring-security/application-pool-identities
Note: There is a bug in IIS 7.5 (the version of IIS that comes with Windows 7 and Windows Server 2008 R2) that sometimes causes authentication problems with AppPoolIdentities if the users password changes (say, if you have mandatory password change policies). There is a hotfix here:
http://support.microsoft.com/kb/2545850/en-us
More info here:
IIS application using application pool identity loses primary token?
There so many scenarios in which this issue occurs.
First thing you need to clear if you are using windows authentication and you are not mentioning any username password in your connection string then:
What happens when you run your code through localhost: when you run your wcf test client from localhost, it will be able to communicate to database as local debug mode application is calling database by your account's service. So it has access to database because devenv.exe is running under your user account.
But when you deploy your web service in IIS. Now understand this service runs under IIS not under your account. So you need to assign access rights to IIS service to access the sql server for windows authentication. Here your web service would not be able to communicate to the SQL server because of access rights issue and Login Failed for user_______ (here your user will come)
So if you are using windows authentication to connect your database, you just have to change the IIS Application pool settings. You need to change IIS Application pool's identity to:
local System (for single windows user).
Network Service (for intranet users or domain users)
Below are the Steps for windows authentication WCF:
•Open IIS (windows+R (run) then type inetmgr, then click ok)
•double click your PC name under Connections
•Click Application Pools
•Select your app pool (DefaultAppPool)
•Then under actions on the right click Advanced Settings:
•Go to Process Model section and
•click on Identity.
•Now select LocalSystem (for single windows authentication user).
or select Network Service (for Intranet users)
Now open your sql server management studio: open run-> then type ssms then press ok in ssms, login using your windows authentication account. open security tab expand logins tab then you will be able to view your account.
Now open properties of your account go to userMapping then select the database you want to connect then check the role membership services you want to use for the selected database click ok. (For network services i.e. intranet users you need to configure above settings for NT AUTHORITY\SYSTEM user too)
add Trusted_Connection=True; property in your connection string. Save it & deploy the web service. Restart app pool.
you will be able to connect the database now.

How to host asp.net application using Window authentication using window servicing account

I am working into an organization which uses Active directory for any kind of application authentication.
We recently created a web application on ASP.NET using Sql Server for database connectivity. During development process we used window authentication for connecting to Sql Server 2008. When application got completed it was a time to host this application on IIS.
Challenges
We have been asked to use window servicing account to host this application on server. We are not supposed to use any kind of username passwords anywhere. It should be active directory driven and window authentication driven.
Now I don't have any idea how to proceed with this. Do I need to make any changes to web config to configure impersonation, or I need to change my connection string.
I only know we have to use Window authentication.
Any guidelines would be a big help
This is what I've always done:
Create an application pool for the site to use. You can use a pool that is already created if you want.
Set the Identity of the application pool to the AD service account your IT staff wants you to use.
Ensure that service account also has access to the database resources
Configure your connection string to use Integrated Security.
Configure Windows authentication & impersonation in your web.config.
For #4 & 5: http://msdn.microsoft.com/en-us/library/bsz5788z(v=vs.100).aspx
Inside connection string use trusted connection, other configuration can be found here:
WindowsIdentity and Classic .Net App Pool
Just make sure you set Impersonation to Enabled.

Domain Login, asp.net

I need clarification how to apply domain login in my asp.net application.
So I have following architecture: Three machines: at one is working asp.net application, another one is database server, and from last machine I am accessing application.
My application should work like this: I am accessing application from last machine it takes my domain name check if it exists in the user table and it should authenticate me.
But it works only when application is running at one machine and I am accessing application from the same one. It is connected with that impersonation in web.config file give me access only to local resources.
I find some articles at MSDN but they are too complex to apply and understand:
Explained: Windows Authentication in ASP.NET 2.0
How To: Use Protocol Transition and Constrained Delegation in
ASP.NET 2.0
How To: Create a Service Account for an ASP.NET 2.0 Application
Building Secure ASP.NET Applications: Authentication, Authorization,
and Secure Communication
From these articles I know that solution should use kerberos, delegation and impersonation. But I have no idea how to apply it.
What I have to do to implement domain login in my application? Do you have a nice tutorial how to do it? Do I have to modify only my application code or configuration of server (second machine)?
Update 1
I logged some information:
On my machine:
System.Security.Principal.WindowsIdentity.GetCurrent().Name
Returns: [myDomainName][myUserName]
System.Security.Principal.WindowsIdentity.GetCurrent().AuthenticationType
Returns: Kerberos
On three machines architecture:
System.Security.Principal.WindowsIdentity.GetCurrent().Name
Returns: [IIS APPPOOL][ApplicationName]
System.Security.Principal.WindowsIdentity.GetCurrent().AuthenticationType
Returns: Negotiate
You need to set up ASP.Net to use Windows Authentiation and impersonation (it sounds like you've done this). Then, you need to set up the web server for kerberos delegation and make sure you have the proper spn's configured for IIS and the application server.
It's working in the 2 machine case because there's no delegation involved there. It's the second authentication hop that requires kerberos.

SQL Server Integrated Authentication Mode

I was wondering when using Windows Authentication mode in a connection string from a web application. Application itself is using Windows Authentication for authorization. Which account will be used to login to SQL Server.
Is't the web application pool account?
User account who logged in to web application using windows auth?
Any other account?
Application is running under Win Ser 2008 64 bit and IIS 7. Application pool account is Network Service.
It depends on how you configure it. From http://msdn.microsoft.com/en-us/library/ms998292.aspx and http://msdn.microsoft.com/en-us/library/bsz5788z.aspx ...
ASP.NET applications do not impersonate by default. As a result, when they use Windows authentication to connect to SQL Server, they use the Web application's process identity. With this approach, your front-end Web application authenticates and authorizes its users and then uses a trusted identity to access the database. The database trusts the application's identity and trusts the application to properly authenticate and authorize callers. This approach is referred to as the trusted subsystem model.
The alternative model referred to as the impersonation/delegation model uses the original caller's Windows identity to access the database. This approach requires that your ASP.NET application is configured to use impersonation. See the section "Impersonation / Delegation vs. Trusted Subsystem" in this document.
So depending on how you have configured it, it could use either the app pool account (not when not using impersonation) or the account of the logged-in user that is using the web application (when using impersonation).
See http://msdn.microsoft.com/en-us/library/134ec8tc.aspx for impersonation information.
It's the application pool user who connects to the database, if you specified Integrated Security in your connection string.
The problem that i was having was that my application pool account in SQL Server needed to be set to the db_owner role before it worked. I spent a long time trying to figure this out.
I was using Windows Authentication, Windows 7 home premium, and IIS all on the same computer. I'm posting this in case someone else run into a similar problem. The book i used did not say to use db_owner but the reader and writer accounts instead.

Resources