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

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

Related

IdentityServer4 Quickstart for IdentityServer as Identity/api endpoints and MVC client

I'm running asp.net core 3.1 and IdentityServer4 following the quick start and guides.
I'm a bit lost when implementing IS end points and api endpoints in the same project. I want the server to host IS authentication/login urls, apis and mvc client. I want to issue bearer tokens which will be used by the IS host/mvc client and client credential clients.
I have gone through the quick starts and gotten the MVC client and the console client to authenticate with my identity server host, but when I try to use my identity server host to authenticate and then go to one of the view controllers, I just get a circular workflow back through authentication.
I believe it's because my account controller login post method isn't issuing the bearer token. I'm thinking there's a call I need make to identity server during login to get it to set the bearer cookie. (It's also possible I'm just missing something on my view controller to tell it it's part of the group to allow access?)
I have this in which allows the client credentials from the console app to work:
services.AddAuthentication("Bearer")
.AddJwtBearer("Bearer", options =>
{
options.Authority = Constants.HostUrl;
options.RequireHttpsMetadata = false;
options.Audience = "api";
});
But if I remove it, then the login workflow through the host identity server works and I can access my view and api controllers.
Is there a quick start that I'm missing that shows the identity server also being the mvc client?
Thanks
when I try to use my identity server host to authenticate to itself, I just get a circular workflow back through authentication.
Well, what does it mean for itself?
Do you try to ask for token for the service that is used to host the REST API ?
It looks like you have some kind of client (like background service whatever) and is trying to get token for that client.
Is it so?
Seems that you can use the client credentials flow However this requires clientid and secret to be stored somewhere. Here is some documentation.
You can use Identity server's Windows Authentication feature also

Impersonation fails when calling web method from SoapUI

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.

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.

Web API Service Fabric app gives unauthorized

I have created a web api hosted in service fabric. When I hit the api from client it works fine on local but is giving 401 from remote machine. I have used IntegratedWindowsAuthentication and Negotiate authentication schemes in Web API.
Can someone help on this?
Your problem is that the remote machine doesn't know about the windows account on your client so it throws a 401. Try creating an account on the remote machine with the same username and password and try again.

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

Categories

Resources