Using windows authentication for database connection - Which user is used? - asp.net-web-api

I have am ASP.NET Web API application that currently makes use of SQL Authentication when connecting to the database. I would like to change the connection to using Windows Authentication. In doing so, how do I specify the user that the web app, and therefore the database access, makes use of? I am using IIS v8.5.9600.16384

I can't say I agree with using integrated for the applications DB access as it makes security a bit more challenging as well as the coding issues tied to always having to deal with the possibility of different priv's for each user but obviously I don't know all the requirements of your situation.
So to answer your question:
If your connection string is set to Intergated Security the identity of the executing thread is used to provide the credentials.
By default the identity of the ASP.NET Worker Process will be the network credentials tied to the identity.
You can view the credentials like this:
IPrincipal threadPrincipal = Thread.CurrentPrincipal;
Console.WriteLine("Name: {0}\nIsAuthenticated: {1}" +
"\nAuthenticationType: {2}",
threadPrincipal.Identity.Name,
threadPrincipal.Identity.IsAuthenticated,
threadPrincipal.Identity.AuthenticationType);
You may set the identity via impersonation in the web.config or programatically.
Web.config:
<identity impersonate="true" userName="accountname" password="password" />
Code: (using the creds of the HttpContext user) this assumes that IIS is using integrated too
System.Security.Principal.WindowsImpersonationContext impersonationContext;
impersonationContext =
((System.Security.Principal.WindowsIdentity)User.Identity).Impersonate();
//User is the HttpContext.User
//Insert your code that runs under the security context of the authenticating user here.
impersonationContext.Undo();

You will have to turn off Anonymous Authentication and enable Windows Authentication via IIS Manager.

Related

Windows custom Credential Provider

Working on a custom credential provider which authenticates the user based on the response from a server. If the server or a third party responds with a yes, the CP should allows the user to login without any further authentication but I couldn't find a way to avoid the user authentication. Can we avoid the authentication and allow the user to login based on the response from another server ?
I am trying it on Windows 10. Developing using VC++.
Thanks, Shan.

Accessing Credentials on TAM Backend Server

I have a setup with Tivoli Access Manager (TAM) as reverse proxy for some application servers on the backend side. TAM is responsible for authenticating users. Is it possible to access the credentials a user passed in during TAM authentication in the backend applications?
I need this because the backend applications connect to a Host-System and there the credentials are needed to log in.
there are a couple of options you might have for this :
Since you mention TAM, I guess you are still using 6.X, so you can use a custom CDAS (Cross-domain Authentication Service) library. You would need to implement the library yourself in C and handle the authentication part and return the clear text password as an extended entitlement in the credential. This will allow you to add this extended entitlement as an injected HTTP header for the junctions that require the password. You can get more information here : http://www-01.ibm.com/support/knowledgecenter/SSPREK_6.1.0/com.ibm.itame.doc_6.1/am61_web_devref58.htm%23chap-wsd-write-custom
You can implement your own External Authentication Interface. EAIs are external web applications where WebSEAL can delegate the authentication part. In that EAI, as in CDAS, you would have to handle the authentication part yourself - probably against TAM user registry - and then return the clear text password as an extended attribute in the credential to be used as a custom HTTP header for the junction that requires it. See http://www-01.ibm.com/support/knowledgecenter/SSPREK_6.1.0/com.ibm.itame.doc_6.1/am61_web_devref128.htm%23appx-wsd-eai
Leverage Tivoli Federated Identity Manager and a custom STS chain to do the authentication and return the clear text password as part of the credential.
For all 3 of the above options, you would need to modify the existing backend application to read the injected HTTP header and use the clear text password to perform the actions to the Host.
I have done all 3 for various integrations and I think your best choice is writing an EAI, as CDAS got deprecated with ISAM 7 and the 3rd option requires an additional software component.

Impersonation in ASP.NET web application does not work when running on IIS

I am working on ASP.NET 4.0 MVC3 web application that works in intranet environment. The application makes use of Windows authentication. Its application pool is run by domain user that has spn set on a domain controller. Authentication works using Kerberos (on IE and Firefox after some additional configuration).
Now I want to upload files to sharepoint, but it's important for me to upload the file as the user currently logged in into the application (so the file is created on Sharepoint with his/her credentials).
I have the following code in ResourceExists(Uri uri) function:
'...
Dim identity As System.Security.Principal.WindowsIdentity = HttpContext.User.Identity
Dim impersonationContext = identity.Impersonate()
response = request.GetResponse()
impersonationContext.Undo()
'...
This works when running locally, but when I deploy to the server I get the exception:
System.Net.WebException: The remote server returned an error: (401) Unauthorized.\r\n at WebDav.WebDavClient.ResourceExists(Uri uri)\r\n at Website.Website.WebdavController.Upload(HttpPostedFileBase file, UploadViewModel vm)
I read something about passing on the credentials, that is not possible with NTLM, but I am sure I am using Kerberos (I checked the headers with wireshark and fiddler) and I see the following:
Authorization: Negotiate YIIFpQYGKwYBBQUCoIIFmTCCBZWgJDAiBgkqhkiC9x...
Any ideas why the impersonation does not work when running on the IIS server?
I found the answer here:
http://support.microsoft.com/kb/810572
"Kerberos does not work in a load-balanced architecture and IIS drops back to NTLM authentication. Because you cannot use NTLM for delegation, any applications or services that require delegation do not work. For more information, click the following article number to view the article in the Microsoft"
And that was exactly the case. I tried now with another machine that is not load-balanced and it works.
The only thing that still surprises me is that ImpersonationLevel of the identity is still Impersonate not Delegate...
After setting <identity impersonate="true"/> in your web.config try the following:
using (((WindowsIdentity)User.Identity).Impersonate())
using (var client = new WebClient { Credentials = CredentialCache.DefaultNetworkCredentials })
{
string result = client.DownloadString("http://sharepoint");
}
you need to configure your site correctly in IIS for impersonation to work.
see Configure ASP.NET Impersonation Authentication (IIS 7)

SSO (Single sign on ) in MVC

has anyone implemented signgle sign on in MVC? Can anyone give me any example for single sign on in MVC.
I've implemented a SSO solution between multiple ASP.NET MVC applications hosted on the same parent domain (app1.domain.com, app2.domain.com, ...) by using Forms Authentication and setting the domain property of the cookie in web.config of all applications:
<forms
name="ssoauth"
loginUrl="/login"
protection="All"
timeout="120"
requireSSL="true"
slidingExpiration="false">
domain="domain.com"
/>
When you set the domain property of the cookie, this cookie will automatically be sent by the client browser to all applications hosted on this domain and will be able to authenticated the user automatically.
If you want to implement a cross domain SSO using Forms Authentication here's what you could do:
The user navigates to foo.com and signs in. The application hosted on foo.com uses standard Forms Authentication, nothing fancy.
The user decides to go to bar.com and clicks on a link that you created. This link could contain a token parameter which will contain the encrypted username. This encryption could be done using the machine keys and look something like this: https://bar.com?token=ABC.
The application hosted on bar.com receives the request and because it uses the same machine keys as the other application it is capable of decrypting the token and fetching the username. Then it simply signs in the user by emitting an authentication cookie locally and the user is automatically signed in bar.com.
Below is an example for SSO for websites sharing same domain
http://www.codeproject.com/Articles/27576/Single-Sign-on-in-ASP-NET-and-Other-Platforms
Please see my answer here. Basically you need to set Authentication mode to windows on web.config and use HttpContext class to retrieve user identity which takes data from Active directory
https://stackoverflow.com/a/40938106/950944

How to authenticate user while calling WCF service using AJAX?

I have a WCF service which needs to be called from client side(ajax call).
I want to use ScriptManager on ASPX page to add a ServiceReference to the WCF service (or) JQuery ajax call to the WCF service. I want to deny anonymous users accessing the WCF service. Is there any way to do user authentication before calling a service method from JavaScript? how to secure my WCF service calls from client side?
There are a number of things you can do to secure your WCF services. Probably the easiest way is if your services are already part of the existing overall ASP.NET application is to enable ASP.NET Compatibility Mode for your services. If your ASP.NET app uses authentication to validate users (e.g. forms authentication) and you are enabling that via a session cookie, then ASP.NET Compatibility Mode does most of that work for you.
By default, this is disabled, but you can enable it with an addition to your web.config:
<system.serviceModel>
...
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
...
</system.serviceModel>
This will enable compatibility mode for all your services in your application. You can also enable this on a service by service basis by setting the web.config value and also using the AspNetCompatibilityRequirements attribute on your service class not the interface):
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]
public class FooService: IFooService {
}
When you enable this setting, you have access to HttpContext.Current (like an ASP.NET page) and it will also enforce that a user must be authenticated before accessing the .svc file (just like you have to be authenticated before accessing any .aspx file). If you try to access a .svc file without being authenticated, and you're using forms authentication, the caller will be redirected to the default login page and, after successful authentication, will be redirected to the .svc file.
This suggestion makes a few assumptions:
your services are in an ASP.NET application;
you're using some type of ASP.NET authentication (like forms authentication) to validate users' credentials and persist a validation ticket in a cookie;
This suggestion, while maybe not the most secure or robust, is probably the simplest to at least get up and running and secure your site to a reasonable degree.
Here's a good MSDN library intro article on ASP.NET compatibility mode.
If this works, perhaps the next step is to look into something like HMAC authentication (which involves a bit more work and the coordination of secret keys - but it's definitely more secure IMHO). Here's a nice walk-through of implementing it - http://blogs.microsoft.co.il/blogs/itai/archive/2009/02/22/how-to-implement-hmac-authentication-on-a-restful-wcf-service.aspx
I hope this helps. Good luck!!
I'm not sure if this will help but I placed a layer between my WCF and webapp. I'd make an AJAX servicereference call to a local asmx. This came under the protection of the forms authentication ticket. The asmx would then do any further security checks (if that specific user making the call was allowed to request that data or shape the data based on the user) and then forward the call on to my WCF service.
This way my service layer did not need to know about the users for each app accessing it and only had a concern for delivery of requested data.
The asmx webservice took the responsibility of security.
Then I made the WCF hosted in IIS using WAS and only allowed Windows Auth access for the identity that the webapp app pool was running as.
So:
ASPX -> ASMX WebService -> WCF
I think that would give you the control/separation and security you are asking for?
for WCF web http service The only way to secure a Web endpoint is to expose it through HTTPS, using transport security. When using message-based security, security information is usually placed in SOAP headers and because the messages sent to non-SOAP endpoints contain no SOAP envelope, there is nowhere to place the security information and you must rely on transport security.

Resources