I've setup an Asp.Net Core 2.0 application following the guide here
The goal is to enable Windows Authentication. I've enabled NTLM and Negotiate. I'm working (and will update) on testing Kerberos and Basic as well, but I fear I might not get the automatic sign-in that negotiate brings.
The application works correctly, and when hosted on Service Fabric I can access it directly from the server IP and port. Windows authenticates correctly, everyone is happy, birds are singing, rainbows appear in the sky... its great.
However, when I try to access the application via the Service Fabric Reverse Proxy service, I hit a wall. My browser prompts me for credentials, and will not accept anything that I pass into it.
I fear this may be a limitation of the built in reverse proxy, but this is something so common that its hard to believe that to be the case.
Is there a way to enable pass-through Windows authentication for the built in proxy?
Note: This is not hosted in Azure, but on premises.
Update: Enabling Basic Authentication and Kerberos didn't help either. Basic authentication actually further complicated the issue. With just Basic authentication enabled, I got repeated 401s, even when connecting directly to the service.
Related
I am using Windows Server 2018, IIS 10 and my web application targets .Net Framework 4.5.1. My API, I built using .Net Core 2.1 and Visual Studio 2017. Both the website and the API use windows authentication.
I used this person's tutorial to try and setup Kerberos two hop authentication (https://blogs.msdn.microsoft.com/surajdixit/2018/02/07/kerberos-configuration-manager-for-internet-information-services-server/).
Steps I've taken and tried,
Set the app pool to run under a custom domain account.
Added an SPN to the domain account that points to the website DNS address in the domain
Switched the app pool to classic mode
Turned on Windows Authentication and Impersonation for the website.
Had system admin grant the custom domain account delegation rights.
The current problem I am facing, is now that I made all these modifications to the app pool and the website in IIS, when I try to connect to the website, it prompts for credentials, which shouldn't happen as it should authenticate me through my windows domain account, when I input the credentials, it just refreshes with the prompt for credentials again. When running locally everything works correctly and the HttpClient in my web application successfully calls out to the API.
I have spent hours on this and would appreciate any help. I am out of ideas.
So after trying multiple walkthroughs and working with other developers, I found that the issue was both applications, the web app and the api, running on the same server. Once I moved the api to it's own dedicated server, I had no need for impersonation and was able to just load the user profile credentials from the app pool as it was running as a domain account. HttpClient and WebClient objects were both successful then at making requests to the api by setting UseDefaultCredentials = true.
If anyone ever has this issue, try hosting your api on a different server. I spent a few days thinking it was something I had done wrong in configuring things, and in the end, it was just where I was hosting the applications.
There may be a way to make this work successfully on the same server, but I was unable to make it work. Maybe someone else who is more experienced can add to this post to help show how to do this on the same server. Happy coding everyone.
I have been scratching my head how to solve the issue described below.
So, the company where I work uses Visual Studio Team Services (was Visual Studio Online), and it is integrated/connected to our AD, meaning that If I log in to my workstation I can log in to Team Services without authenticating myself, like SSO.
I'm going to create an application which communicates to Team Services via Team Services SOAP and WebApi clients and here is the problem. I need a user to be able to communicate with Team Services and doing stuff (reading data, creating work items, creating test suits, etc.). I see little chance to convince IT to create a user only for this. They going to reject my request due to security risks.
The application architecture looks this:
browser: angularjs application, spa, calling only the WebApi service
server: WebApi service, which is responsible to communicate with Team Services and transforming data back and forth between the client and Team Services.
database: persisting data for later analysis
There is an idea in my mind, where I can get somehow the windows credentials from the OS and push it down to the server which uses it to communicate with Team Services. In Team Services, we will see that the particular user did things.
The question, how is possible that? The articles I have found searching for something similar, always mention .Net MVC app where I need to modify the web.config in order to get the credentials. But, in my architecture there is no .Net MVC app running on local machines. There is only a SPA running in browsers.
Or my architecture is not fit for this purpose? Shall I rework it and using MVC app to be able to get the credentials and working with them? But, the question still stands, how can I pass the credentials through the calls calling Team Services?
Do you know blog entries dealing with cases like above?
Thanks for any help in advance!
I think you have a bit of confusion over your terms. The SPA (Single Page App) has javascript code delivered by the server to the browser that calls the .NET WebApi code. In order to get the browser to use Kerberos/Windows Authentication you need to add
<system.web>
<authentication mode="Windows" />
</system.web>
to your web.config on the server where the .NET app is running (under IIS).
From here...
http://www.asp.net/web-api/overview/security/integrated-windows-authentication
"On the client side, Integrated Windows authentication works with any browser that supports the Negotiate authentication scheme, which includes most major browsers. For .NET client applications, the HttpClient class supports Windows authentication:"
Then the browser will do the rest for you and the HttpContext.CurrentUser in the .NET code on the server will be set to the windows user of the clients browser.
We have self-hosted C# WCF service providing rest API over HTTPS.
Problem:Configuring the certificates for SSL requires admin rights. I assume it is to do with WCF depends on http.sys for http/https handling. The service is meant to be deployed on customer environments. So it would be nice if it can run without requiring admin rights.
Looks like WCF depends on http.sys,
Can I self-host an HTTPS service in WCF without the certificate store and without using netsh http add sslcert?
Like to know if any other embedded web server solution exist that support SSL and not requiring admin rights on the machine?
Checked so far,
http://nancyfx.org/
https://github.com/pvginkel/NHttp
Both doesn't seem to support SSL.
Most windows hosted web stacks rely on the HTTP Server API which is the API around the kernel HTTP stack (a.k.a HTTP.sys). The .Net HttpListener class does so as well (same as WCF, the OWIN self hosted asp.Net and so on which rely on it).
Just making sure, you do know you can authorize the identity you application runs under to bind to an HTTPS URL even if it's not running as an admin account, right? If you could gain admin right just for the installation phase that could solve you problem? (assuming you checked that already)
You can read more on a blog post i wrote about that here
To go into the effort of building an http stack on top of raw sockets would be a great effort and with little gain and so around .Net i doublt you would find anything like that.
Unless, it wished to be cross platform.
Any java based web server would probably do just that, using the JVM's http stack and relying on a java keystore to provide the required certificates for the SSL. (To keep it portable across different OS's)
If you wanna go java i am sure you can find many such web servers.
If you care to try and bind to a web server using CGI have a look at mongoose (Never used it to be honest).
Another option which comes to mind is to use an ssl proxy like Stunnel to stand in front of the web server. It would do the SSL part using non-windows certificate store.
It's running into an Intranet, .net framework 3.5, hosted in IIS 7.0 and it's using wsHttpBinding with null security. Now I have to protect it to allow only specific users can run it.
Seems that I should use SSL and certificates but I'd really like stay away of that because looks complex, basically I'm looking for the simplest way.
I took a look to netTcpBinding and seems to me this is the right way, if so, can you confirm if using net.tcp it would be able to be consumed by some asp.net site.
Any comments are welcome.
Thanks,
In your case you have an intranet, which means that you have internal users. It depends where the call to the WCF service is coming from.
If we assume:
Internal users, who login to a windows domain
The client machines and the server are in the same domain
The user runs a windows app on their machine, which makes the WCF call
Then the simplest solution is to use windows authentication
The client makes the call in the security context of the logged on user
The server checks the group membership of the user to determin if it should allow access
You said you are using an Intranet app.
If so, you could turn on Windows Authentication, and allow only specific users in IIS (this is also controlled in the web.config). If everyone is on the intranet, it should authenticate automatically without users needing to enter a password or user name.
However, if anyone outside your intranet needs to reach this service, you'll need to include SSL & https to protect the credentials sent to the service.
I want to write a web service using Visual Studio. The service needs to support some type of authentication, and should be able to receive commands via simple HTTP GET requests. The input would only be a method call with some parameters, and the responses will be simple status/error codes. My instinct would be to go with an ASP.NET Web Service, but this isn't an option in C# 4.0 and it makes me wonder if I should be using something that's more up-to-date. I've looked into WCF, but it seems like this requires a running application on the client-side - is there a way to query a WCF host by just accessing a URL?
The authentication is also an important piece. Developing my own little authentication system seems like a bad idea - I've read that it's too easy to mess up. What would be the standard way of authenticating with a web service like this?
I'd love to look up all of the specifics on this and learn it myself, but I really don't even know where to begin. Some direction would be greatly appreciated!
For a simple HTTP service that takes commands via GET (you should actually consider using POST...) I would use straight ASP MVC, not a true
'web service'. WCF wants to guide you down the path of SOAP and your clients will curse you forever. RESTful WCF is also an alternative, but it still seem overkill imho.
As for authentication, you have two viable authentication schemes:
Windows Integrated security, which will work only if client is inside intranet or connected with a VPN or DirectAccess solution
HTTP Digest, which is poorly supported by the ASP authentication modes (only support authenticating against a Active Directory forest user base).
With Windows authentication you don't do anything on the server side code, simply mark the the web.config <authentication mode="Windows" />. 'Windows' authentication is understood by most user agents. Is trivial to program clients of your service to use Windows authentication too, simple set the request's Credentials to the current user DefaultCredentials.
With Digest authentication the server will challenge the user agent to authenticate, but the ASP validation unfortunately, as I said, only works for validating a trusted NT domain. The client though does not need to be in the intranet (there is no NTLM SSPI exchange between client and server). Programming a client is faily easy, in .Net simply set the requet Credentials to a properly initialized CredentialsCache:
CredentialCache myCache = new CredentialCache();
myCache.Add(new Uri("http://www.contoso.com/"),"Digest", new NetworkCredential(UserName,SecurelyStoredPassword,Domain));
...
request.PreAuthenticate = true;
request.Credentials = myCache;
It is important to reuse the cache between requests, otherwise the client will do two round-trips with each call.
In theory you can also have a third authentication path: full duplex SSL. But the 'trivial' problem of client certificate deployment makes this alternative a dead end for anybody short of a fully pre-installed enterprise PKI.