Impersonation fails when calling web method from SoapUI - c#

I have a WCF self-hosted web service (hosted in my Windows service under Local System account). Web methods have [OperationBehaviorAttribute(Impersonation = ImpersonationOption.Required)] attached. NTLM authentication is used.
In my web method's implementation I impersonate the caller and do some stuff. For this I use ServiceSecurityContext.Current.WindowsIdentity. If I don't give proper credentials when calling the web method then web service would return "401 Unauthorized".
When I call the method from Chrome then the windows identity and impersonation work great. I can create a new process under impersonated user, which will spawn in Windows session of that user (different from 0). Firefox also works when I add "localhost" string to network.automatic-ntlm-auth.trusted-uris preference. But when SoapUI calls the method then this windows identity is not set up properly. Web method is called, so NTLM works to a degree, but it just doesn't work properly. A call to ServiceSecurityContext.Current.WindowsIdentity.Owner.IsAccountSid() returns false (Owner is not a user account, but built-in "Administrators" group). Creating a new process while impersonated would create it in Windows session 0.
I've looked into HTTP communication with Wireshark, and NTLM handshake looks different between Chrome and SoapUI. No idea what to do with that information though.
How to make SoapUI to work properly with my web service and NTLM?

While I don't know how to fix the problem with WCF I switched to Web API and OWIN, and now I have a working solution.

Related

Programmatically authenticate with Azure AD for Application Proxy

I have an on-premise hosted WCF service with REST endpoint which is configured for Anonymous authentication only in IIS. I installed and configured Azure App proxy connector on the server. I am able to contact the service fine with Pass-through authentication, but struggling to authenticate from a console app when Azure AD is chosen as security mechanism. I know I could have pass-through in Azure and turn on for example windows authentication in IIS, but this is unfortunately not an option in this case.
Using a browser, I am able to access the application fine, don't even need to enter credentials, our on-premise AD is connected and synchronized with Azure AD.
I followed this walk-through despite it is not regarding application proxy, and reusing parts of code I am able to get the Access Token for my application, but when I run the http request with Authorization header I don't get the result of service operation.
Using Fiddler I can note the following:
I get http 302 (Found). I can see my Authorization header in request, and in response I get a cookie AzureAppProxyAnalyticCookie
That is followed with http 200 to login.microsoftonline.com
Example I provided link for above works fine so it is clear that I am doing something wrong. Why is Authorization header not accepted and why am I being redirected to logon page?
Thanks in advance
This is working for another service, have no idea what was wrong with the first one, but suspecting something with DNS on local server. Won't be spending more time on this, point is that I shouldn't have experienced the redirect at all, although browser handled it and managed to get me authenticated.

How to call a Web API service from MVC using windows authentication?

I've looked at a lot of questions addressing this issue and nothing seems to work. I'm trying to call a web api service from an mvc web application. This is my client code:
var client = new HttpClient(new HttpClientHandler { UseDefaultCredentials = true })
{
BaseAddress = baseAddress
};
var response = await client.GetAsync("items/5");
When I run it locally, it works. When I publish the project to the server the api always returns 401 Unauthorized. I have enabled windows authentication on the web api and mvc project in IIS. How do I get the correct windows credentials to the api from the mvc application? The web api and mvc app are running on the same IIS server.
If, by chance, the MVC app can make all requests to the WebAPI using the same Windows credentials, then I think you should be able to just configure IIS's application pool to run as a domain user. By default IIS's app pools run as some machine local account. So, if it tries to make a request over the network to a Windows Authenticated resource, the remote machine doesn't recognise the web server's machine local account. Hence the unauthorised error.
However, if you want to get the MVC app to call the WebAPI as the user who made the request to the MVC app, then you'll need to turn on impersonation in web.config. You'll probably also need to get your domain admin to turn on Kerberos delegation for your web server machine, due to the way that Kerberos/Active Directory works (look up kerberos double hop).
The problem was that apparently if you try to send a request to the same machine using a fully qualified domain name, the request will automatically fail to protect against a reflection attack.
I fixed this by changing baseAddress from
http://example.com/api
to
http://localhost/api

Calling WCF web services from an ASP.NET web application using impersonation and channel factory

I have various bits of functionality implemented in WCF web services which are currently consumed by an Excel client via a local COM-visible library. I wish to implement some of the front-end functionality in a web client. I set up my client proxy using
dataChannel.Credentials.Windows.AllowedImpersonationLevel = TokenImpersonationLevel.Delegation;
ASP.NET impersonation is turned on as is windows authentication (no anonymous). When web services and web site are hosted on the same server there are no issues and the desktop user's credentials are passed from browser to web site to WCF perfectly. However, when web site and web services are hosted on different boxes (same domain, intranet only) I get 401 authentication errors. What am I doing wrong?
It sounds like you are suffering from the kerberos "double hop" problem. By default windows does not pass the kerberos authentication token onto another server so if you have user accesses webserver A and authenticates, webserver A accesses service on webserver B. WEbserver A does not pass the auithentication through to webserver B so you get a 401. I think this article should help you enable kerberos delegation between the web site server and the web service server

WIF and WCF - Accessing Thread.CurrentPrincipal inside service method with AspNetCompatibilityMode turned off

I have a web application with a silverlight app on one of the pages. The website is secured using WIF. I am attempting to make a WCF call from silverlight to a service hosted in the same appdomain as my website.
If I have AspNetCompatibilityMode enabled this works fine. The browser has already authenticated and so when the WCF call is made the FedAuth cookies are sent up by the silverlight client and WIF correctly sets the HttpContext.Current.User from the session cookies (FedAuth/FedAuth1).
Unfortunately I need to have AspNetCompatibilityMode turned off. In this case I can see that the silverlight WCF call still passes the FedAuth cookies to the server and the SessionAuthenticationModule correctly sets the Thread.CurrentPrincipal. Unfortunately, the sessionauthenticationmodule seems to run in a different thread from the actual WCF method I am trying to invoke therefore I have lose the identity somewhere along the WCF/WIF pipeline.
Is there a way around this? I have tried creating a custom implementation of SessionAuthenticationModule and overriding SetPrincipalFromSessionToken (inside which I can access my claims etc.) but I am not sure where I can store the principal so that I have acess to it after the channel handler dispatches the call to my service on another thread.

WCF security, changing the WindowsIdentity from inside a service

I have a client app that calls a WCF service on a different server
in the service I print out the following:
1. ServiceSecurityContext.Current.WindowsIdentity.Name;
2. WindowsIdentity.GetCurrent().Name;
1 above gives me my windows login and 2 gives me the windows login that the server is logged in as
How can i change 2 so that it gives me my windows login (not the login of the server)? Is there a way to force it?
i want to do this because in the WCF service i need to call another service with my original windows login credentials
Check out these links about impersonating the caller's identity in a WCF service - that'll be what you have to do, basically:
WCF security guidance - How To Impersonate the original caller
Delegation and Impersonation with WCF
Setting up WCF to Impersonate Client credentials
Caller impersonation for WCF services
Marc

Categories

Resources