Asp.NET Delegation and Calling a SharePoint Webservice - asp.net

I'm trying to make a call to the SharePoint Search Webservice from an Asp.NET 4.0 application that does not reside on the SharePoint server. Everything seems to work, accept it is using the AppPool's credentials (a domain service account) to authenticate to SharePoint, which only returns results that that pin has access to. What I need to be able to do is impersonate the calling user, so that I get results for that user and not the domain account. I've set the server that the application is running under up to be trusted for delegation to the http spn that the SharePoint server is using, but I get a 401 error when doing the impersonation in my code. What could I be doing wrong?

you have to impersonate your call to the sharepoint web service.
you can do this at a web application level, with either the calling user or a static user, inside the web.config in the system.web node using the identity element, i.e...
<system.web>
<identity impersonate="true" />
</system.web>
or you can do this with inline code when you make your requesting call.
here is a microsoft KB on how to impersonate with an asp.net application. http://support.microsoft.com/kb/306158

Related

Login Failed for user Using SignalR and Impersonation

I have implemented SignalR in my ASP.NET WebForms application and am successfully connecting to the hub. However, when a call is made to the database (SQL Server) I get Login failed for user 'MY_DOMAIN\MY_PC_NAME'. Note that the user being failed is the PC name and not the user I am impersonating (see below).
My Web.Config is set to impersonate a user who does have access to the database and this works for all calls made to the database that are not via SignalR processes.
IIS is set to use Windows Authentication for the application (and also has ASP.NET Impersonation enabled).
During debug of the SignalR process, the Context.User.Identity is the user that is authenticated in the browser session.
Is there a way to ensure that the impersonated user in the Web.Config is honored by SignalR when making SQL calls?
For reference:
Impersonate Tag in Web.Config: <identity impersonate="true" userName="MY_DOMAIN\MY_USER" password="MY_PASSWORD" />
Connection String in Web.Config: <add name="SiteDatabase" connectionString="Server=SERVER_NAME; Database=DATABASE_NAME; Integrated Security=SSPI" />
I changed the AppPool identity in IIS from LocalSystem to use the same user as that set in the impersonate of the Web.Config file and the SignalR process successfully connects to the database!
I don't know yet if this is the perfect solution or why SignalR won't honor the Web.Config impersonate, but it at least gets me going...

How to integrate an ASP.Net intranet with Active Directory?

I'm currently working on an intranet portal for my company, it will remain internal, only users with accounts on our domain will have access to it. At the moment, I use forms authentication method, and authenticate users against the Active Directory domain with System.DirectoryServices. I also interrogate the AD with System.DirectoryServices.AccountManagement to manage access rights depending on the Active Directory groups the user belongs to and I store some data in user sessions and everything works fine.
I've been asked to study whether Single Sign-On could be implemented in our context, all our users work in RDS without exceptions, so they always are in an authenticated session and the higher-ups would prefer not having to sign in at all. As far as rewritting the code to authentify and authorize users as explained here and here
I'm not too concerned.
I tried everything on a blank ASP.Net MVC5 project, to which I added an ADO.Net model with integrated security. My dev SQL Server is hosted on a remote server (not the dev desktop), the same server also hosts the dev IIS server. In production, both services will be on separate servers. This worked fine as long as I was debugging localy on my desktop, but once I published to the IIS server, I hit the first snag and couldn't get out of it.
When I changed settings in the IIS app to disable anonymous and enable windows authentication, IIS automatically changed <authentication mode="Forms" /> to <authentication mode="Windows" /> in the web.config file (as suggested here), but I couldn't make it work with Integrated Security=True or Integrated Security=SSPI, I get an error page saying [SqlException (0x80131904): Login failed for user 'DOMAIN\MACHINE$'.].
The connection string reads like: <add name="ASPNetProjectEntities" connectionString="metadata=res://*/Models.ModelASPNetProject.csdl|res://*/Models.ModelASPNetProject.ssdl|res://*/Models.ModelASPNetProject.msl;provider=System.Data.SqlClient;provider connection string="data source=MACHINE;initial catalog=DATABASE;persist security info=True;Integrated Security=SSPI;MultipleActiveResultSets=True;App=EntityFramework"" providerName="System.Data.EntityClient" />
I tried to add the machine account DOMAIN\MACHINE$ to SQL logins and grant it rights to the database, but no dice. I tried to authorize delegation in the server AD account and activate identity impersonation, but that didn't work either. I can only make it work on the remote IIS server if I put a SQL user/pass in the connection string.
So I'm at loss what could be missing here to make it work with Integrated Security. Or will I have to put SQL credentials in the connection string and encrypt it on IIS?
You're confusing Integrated Security with the authentication mechanism of your website. If you use Integrated Security, the connection used from your web app to SQL Server will use the account that the application pool your web app is running as is using. To use Integrated Security, have a service account created in AD, set your app pool to run as that account, and grant the necessary permissions to that service account in SQL Server.
Note that whether you're using forms auth or integrated security isn't relevant to how the web app connects to SQL Server, unless you're using impersonation, which you should never use.

Passing a FedAuth cookie to Web Service Calls

I have an ASP.NET site running on Azure at https://[appname].cloudapp.net. I also have an asmx web service running as a subapp in the same instance at https://[appname].cloudapp.net/WebService.
The root site is protected with passive ADFS authentication. Since the web service inherits settings from the root application's web.config, it is also protected.
My problem is that when I make web service calls, the FedAuth cookie is not getting passed along to the web service and I always receive the STS login page as a response from the web service.
How can I make use of the FedAuth cookie retrieved from signing into the root app to authenticate my web service calls?
You should make the web service anonymous and handle a different type of authentication (assuming the service needs to be secured). You cant "pass" the FedAuth cookie because that lives in the browser. So unless you do the Web service call from the browser using ajax you wont be able to do it. One thing you could do is passing the original ADFS SAML token to the web service and validate it, but that wont be trivial in asmx.
<location path="WebService">
<authorization>
<allow users="*" />
</authorization>
</location>

WCF, IPC Named Pipes, ASP.NET, and <identity impersonate="true" />

We have a .NET 4.0 Windows Service that is hosting an endpoint over a Named Pipe (using IPC). This service is running under the context of User A.
We have an ASP.NET-hosted client that is requesting the operation that is exposed by the aforementioned service. This client runs under the context of User B (via Anonymous Access ,via <identity impersonate="true" />).
The problem:
If we use <identity impersonate="true" /> in our web.config (this cannot be changed), we get "Failed to connect to an IPC Port: Access is denied." exceptions when the client tries to call the hosted operation. If <identity impersonate... /> does not exist (perhaps by virtue of not using ASP.NET, say a client Console Application), we have no issue.
Does anyone out there know how to get this configuration working so we stop receiving Access Denied errors? It has something to do with authentication but we just can't work it out.
Recalling from 70-503: net.pipes only works with Windows security. It's obvious because the whole process (WCF) is on the current (Windows) machine only. ASP.NET runs under the credentials of a dedicated ASP.NET-user by default who's rights are strictly limited. I don't aspect the ASP.NET user having access to the current machine, accessing local files, net.pipes etc. It only has access to the folder your website runs from. So, by impersonating that very user is like ensuring having only the rights to run a website.
What you can do is impersonate to a specific Windows account who has the appropriate rights. This can be done using programmatic impersonation. Or use delegation. Read about it here to use the solution who fits best.
Not possible due to NetWorkService being restricted from seeing or accessing the pipe.
Answer here

Why does Windows/Integrated Authentication in IIS not pass user credentials to SSRS and SQL?

Issue:
In ASP.NET 4.0, I use my SSRS 2005 server's ReportService2005.asmx web service to get a list of reports. Also in .NET, I use Entity Framework to communicate with my MS-SQL 2005 database. When I use Visual Studio Development Server as my web server, calls to SSRS and SQL work fine. But when I switch to IIS 5.1, both SSRS and Entity code produce errors. I use only Windows/Integrated Authentication in IIS.
Errors:
For SSRS, I get The request failed with HTTP status 401: Unauthorized.
For Entity Framework, I get Login failed for user ''. The user is not associated with a trusted SQL Server connection.
Attempted Solutions:
In the Web.Config I added <identity impersonate="true" /> and that fixed Entity Framework errors but not SSRS errors. I expanded the identity reference to include my username and password, and that fixed all errors.
Question:
Why does specifying my username and password fix the errors, and why does SQL say I am not specifying a username ('')? I thought Windows Authentication automatically impersonated the current user. How can I fix this without hardcoding a "service" account into the web.config?
Windows or Integrated authentication means that user is identified using windows credentials (or token) but it does not means that the request in running under that user. ASP.NET run-time will execute the request under worker process (App Pool) identity unless you configure it to impersonate some other identity.
So when you are accessing the site using development server, the server is running under your identity and so access to SSRS and Sql Server is done under your identity and it works.
When you loaded your site under IIS, ASP.NET request would be run under whatever identity is configured for the application pool. Typically this identity is local user and hence access to network resources such as SSRS or Sql Server would be denied. Adding <identity impersonate="true" username="your name" ../>, ASP.NET will run requests under your identity and that should work for both SSRS and Sql Server.
The curious case here is <identity impersonate="true" /> - under this setting, ASP.NET will impersonate currently authenticated windows identity. However, for this to work correctly, you have configure both IIS and ASP.NET on integrated authentication and deny anonymous access (in ASP.NET as well as IIS). Failing to do so may result in not authenticating current user's identity and the request would be run under anonymous user's identity (as configured in IIS). If you marked integrated authentication in IIS but not in ASP.NET then identity would not be passed to the ASP.NET request. You need to check your environment to see what exact scenario you had faced but ultimate result was your ASP.NET request was running under credential that has access to SQL Server but not to SSRS.
You also need to be aware of the 'double hop' issue - this means that your credentials can only be used twice.
If you are accessing a website using Windows Authentication and impersonation, that website can call another service as you. If that other service is another website (i.e. Reporting Services) which in turn calls another service (e.g. database) it cannot pass your credentials on again. This means that the database will throw an error if it expects credentials from the user.

Resources