Authenticate domain user after connection to domain is inaccessible C# - c#

We have an MVC application that validates windows users by instantiating a principalcontext, locally and for domain users. However, this immediately fails when a connection to the domain cannot be made. Is there a way to leverage the capability of windows to still validate domain credentials when disconnected from the domain?
We see that in SSMS you can also use windows authentication after the server has lost access to the domain.
To be clear, the machine is joined to the domain but does not have access to the domain controller, i.e. a corporate laptop that is taken home.
Thanks for the help in advance.

The answer is in how Kerberos (and I believe NTLM is similar) works in that they use session tickets. So once authentication is successful against a domain controller, you have a "ticket" that proves you authenticated. When you authenticate to anything else that requires Windows authentication, the ticket is sent.
To take advantage of this, you must use the built-in Windows authentication. You cannot take a username and password and try to authenticate them that way.
If everyone who uses your website can use Windows authentication - then you can enable it for your whole site.
If you have a mixed audience - some who have a domain account and some that don't - it's a little trickier, but still doable. I've done it. You can look at the OWIN-MixedAuth project. I haven't used that specifically.
That project seems to use a separate button for the Windows authentication. When I did it, I made it seamless (it tries Windows auth and fails back to a login page). I did that by doing an AJAX request in the background to a page that requires Windows authentication, and if it succeeds, just forward on. If it fails, show the login fields.
All that said, I don't know it will work if the server cannot reach the domain. It will probably work for users who have already authenticated to the site before it lost connection to the domain, or if the site is hosted on the same computer that it is being accessed from. But it might not work if a user it has never seen before tries to login while there is no access to the domain. You will have to test.
But the benefit of using Windows authentication anyway is that you can make the login seamless. As long as the site is in your Trusted Sites (in the Windows Internet Options) then IE and Chrome will automatically send the user's credentials.

Related

How can I authenticate a windows user over a REST API call without IIS/WCF?

While developing an on-premise, intranet-only REST API server for my company, I managed to completely confuse myself regarding authentication issues.
I have:
A REST web server implemented in C#, using self-hosted Nancy, running as a Windows Service
A C# client that can query the server, run by a user in our company
I do not have:
Any form of access to our Active Directory and/or domain controller, apart from what any application running under Windows normally has
Any way to influence AD settings or configuration
Active Directory Federation Services (ADFS) (I think. We use Windows 7 and Office 2010, just to give some perspective on the state of the software landscape)
Azure Active Directory (AAD)
I want:
A way for the server to authenticate that a request is made by a user of our company
It is perfectly fine if the client has to sent some additional authentication data with each request, as long as it does not contain the user's password in any form
I do not want to:
Have to set up any additional software (my server must be minimum configuration and maintenance, so the average user can install and run it)
Install / configure / maintain an IIS server (see above)
Use ASP.net (way too big for my needs, plus see above point(s))
Handle user passwords in any way (company policy and common sense)
Impersonate the user (I only need to validate the authenticity of the request)
Implement my own user account database. We already have half a dozen services that need their own username/password combinations, I do not want to add yet another one
I have read articles that show how to use Windows authentication with IIS, or how to use Azure Active Directory (AAD) with Nancy. Other questions here have already informed me how to authenticate username / password combinations against the Active Directory. However, none of these satisfy all of my requirements or have requirements of their own (like AAD/ADFS) that I cannot meet.
It seems that Kerberos/SSPI might be what I want, but it seems very involved and quite complicated to get working with C#. It is possible I will have to go this route, but I could really benefit from some minimal working example (the accepted answer provides a C# implementation/wrapper, including an example project, but I can't seem to be able to make heads or tails of it).
Maybe I am naive, but what I image the solution to be is something along the following lines:
The client queries a service (AD, Domain controller, ...?) for some form of authentication token, using the credentials of the currently logged in user
The token is then sent to the server together with the username, as part of the request that needs to be authenticated
The server extracts the token, and queries the same service (AD, Domain controller, ...) whether the token is authentic, valid and belongs to the user in question
Is this possible at all? Ideally, with some sort of ready made library that I can plug in to my projects (I'm reaching, I know)?
You can do this with stateless authentication and Jwt. Send a username and password to "/ auth" (example) and "/ auth" will search the AD (example) and validate if the user exists, then create a Jwt token with the name of the user on load. When you make a request, you will only send a Jwt token and Nancy validates the token.

Can a website authenticate against multiple ADFS servers?

We have an ASP.NET/MVC website that's using FormsAuthentication. As is usual, when the user tries to access a page, and doesn't have a valid FormsAuthentication cookie, IIS redirects him to the login view. When the user does a HttpPost to the login controller, our controller action makes a call to our WebApi webservice, which validates username, password, and customerid against a Sql Server database. If the authentication passes, the controller action sets a FormsAuthentication cookie, and redirects to the page the user had asked for.
Now sales is making noises about "Single Sign-On", though I'm not clear exactly what they mean by that. From what I've read, in the Microsoft World this usually means accessing MS's Active Directory Federation Services.
At this point I have almost no idea how this would work, but before I dig into this too deeply, would it be possible to put the authentication code within the WebApi webservice, where we could choose to validate against the Sql Server database, or against whichever ADFS server was appropriate for the specified customer?
Our problem is that we have I don't know how many thousands of users, working for some hundreds of customers. Many customers will not have ADFS running, and those who do will each have their own ADFS server.
Most of what I see with respect to Single Sign-On seems to involve doing browser redirection to the ADFS server, then redirection back, and looks to be avoiding login at all, if you're already logged in. I don't think we can do that, in our case. We can't know which ADFS server to redirect to, until we hit the database.
So, the question - is it possible to do ADFS authentication entirely from C# code in our WebAPI web service?
(One possible complication - the website itself has zero access to any database. The sole configuration setting in its web.config is the base URL of the webservice. Whatever authentication happens has to happen in the webservice, not in the website.)
First of all, "Single Sign-On" (SSO) is not limited to ADFS. It simply means that you type your credentials only once, and then all systems you access automatically "recognize" you; all subsequent authorizations request are transparent. For instance, if you have several web sites using Windows Authentication in your company Intranet (same AD domain), you have SSO: you authenticate once when you log in to your computer, and then your web browser authenticates automatically to these web sites using NTLM or Kerberos. No ADFS in this case.
What ADFS (and "Federation" more generally) allows, is SSO accross security boundaries. In Windows world, a security zone is typically created by an Active Directory forest; everything within this forest is accessible using SSO provided by Windows authentication. But as soon as you leave this zone (SaaS application, web site in another company network), you need another authentication protocol to perform SSO, and these protocols are implemented in ADFS.
Then about your particular problem:
What you could do is instead of using FormsAuth, you use AdfsAuth. When a unknown user accesses a page, he would be redirected to ADFS for authentication (using browser redirects as you correctly mention). To know which ADFS server should authenticate your user, you need a way to differentiate them indeed: a list of IP range per customer? a different URL per customer? If you don't have something like this, then the only way is to show them a list of choices such as: "I work for CompanyA", "I work for CompanyB", "I work for CompanyC", "I don't work for any of these companies and want to authenticate using FormsAuth."
In this case, what your WebApi web service has to do is: if I know which ADFS server to use, redirect the user there. Otherwise authenticate the user as usual using the database.
When you use AdfsAuth for a customer, your database is useless. You can delete all credentials related to this customer.
do ADFS authentication entirely from C# code in our WebAPI
Well it's possible to "re-implement" ADFS in your service, but you won't get SSO if you do that. When you use federation, your redirect the user to the ADFS server of his company. This ADFS server is in the same domain as his computer, so the user gets SSO here. Once again, your users can't get SSO if you authenticate them yourself, because your users are not in the same security zone as your site.
When authenticating to multiple identity providers, it is typical redirect to your own STS. So, in this case, you would have www.yourapp.com redirecting to sts.yourapp.com, which redirects to sts.somecustomer.com.
The specific tools to enable such a dataflow is the home realm parameter (whr), and the AD FS Powershell API (to allow IDP maintenance).
Your RP-STS acts as the trust-point for the app, and manages selection of the appropriate IDP. One RP-STS, many IP-STS's. Each of your Customer's IP-STS gets set up as a Claims Provider Trust in AD FS.
As always, Vittorio has already covered the subject better than I could.

how can i authenticate the whole computer instead of web browser?

For the past 2 years we have created 3 desktop application and 2 admin section(web) for one of my client.
Every application uses its own authentication process.
I have merged the authentication process for web in single unit.
But the client wants to have one screen for getting authenticated on desktop application as well as on website.
he also want to use different browser and the username /password should be asked only once irrespective of browser opend.
I tried to use cookies for web. but every browser has got its own cookies.
Can any one suggest how can i authenticate a user for the whole computer so that authentication information is available to desktop application as well as to website irrespective of the browser being used?
Edit: As suggested by joe using windows authentication is not possible in my case.
So i created one more table with following column
ip,userid,authenticatedat
when ever a user is authenticated i insert its ip,userid, and time in table.
when ever a non authenticate user comes first i look in the table if the ip is present and authenticatedat is within 30 min i assume user is authenticated and set the session/variable with data required.
This i have checked and found it is working .
I have found this is not secure.
Windows authentication is the only way I know of doing this. Assuming your users are on a domain you control, then their Windows credentials would validate them, and they wouldn't ever need to enter a username and password.
Outside of that, I can only think of hacky dirty methods of making this happen. You could install a single authentication service on their machine which is available to connect to remotely from other applications - those apps would call your service, and that service would authenticate the user and pass an authentication token back. Easy enough for Windows apps, but making that work on a web app wouldn't be fun. Your web server wouldn't be able to talk to this service, so you'd have to rely on the client javascript talking to the service and retrieving a token or hash, and then the javascript passing this on to the web server.
Anything you put on a local machine, you have to assume the user can reverse engineer and manipulate, so if you need real security, I doubt you'll find a solution. Best bet is just to make the user log in every time you need to, and have your authentication/authorization code on your web service layer.

Authenticate with AD from iOS

Ok, I have looked around and could not find a solution to this problem. I have an ASP.NET web application that is using Windows Authentication.
I have a public web services that I use for an iPad App I have developed. For security reasons all of my Web Services requires a header with login information.
Right now, I have a separate database that I authenticate users from. Its a built in authentication for when my application is installed using Forms Authentication.
What I would like to do is when the user on the iPad logs into the system, it passes the Login and Password to the Web Service in the hearder... which it does now.
But, how can I Authenticate that User and Password against the Active Directory to make sure the user has access?
Thannks,
Cory
But, how can I Authenticate that User and Password against the Active
Directory to make sure the user has access?
That's straightforward in c#: Validate a username and password against Active Directory?
More AD tasks in c# (including authentication)
Right now, I have a separate database that I authenticate users from.
Its a built in authentication for when my application is installed
using Forms Authentication.
Based on this statement, it sounds like you have a database of credentials which duplicates credentials in AD? If that's the case, not sure that's a good idea.
And/or it also sounds like credentials which match those in AD are being passed around (possibly in plain text?) This might be a business requirement, but I would recommend that all communication is done over SSL and that the AD accounts belong to a domain setup specifically for this purpose that is not trusted (or only partially trusted) by the rest of the network.

Domain Authentication from .NET Client over VPN

I am writing a ClickOnce WPF app that will sometimes be used over VPN. The app uses resources available only to domain authenticated users. Some of the things include accessing SSRS Reports, accessing LDAP to lookup user information, hitting web services, etc.
When a user logs in from a machine that is not authenticated on the domain, I need to somehow get his credentials, authenticate him on the domain, and store his credentials.
What is the recommended approach for
authenticating domain users over
VPN?
How can I securely store the credentials?
I've found several articles but, not much posted recently and a lot of the solutions seem kinda hacky, or aren't very secure (ie - storing strings clear text in memory).
It would be cool if I could use the ActiveDicrtoryMembershipProvider, but that seems to be geared for use in web apps.
EDIT:
The above is kind of a workaround. The user must enter their domain credentials to authenticate on the VPN. It would be ideal to access the credentials the user has already entered to login to the VPN instead of the WindowsIdentity.GetCurrent() (which returns the user logged into the computer). Any ideas on how that could work? We use Juniper Networks to connect to the VPN.
Answer
I ended up doing basically what was suggested in the link below. When the app starts, I'll detect whether the user is on the domain. If so, I'll use those credentials when calling services. If the user is on the VPN (but not on a domain authenticated machine), I prompt for the user's credentials and authenticate via System.DirectoryServices. If the user gives valid credentials I'll store the domain, user and password in a SecureString. The app then uses that information to create credentials to pass to various services.
Thanks!
This answer to the question might help.
--EDIT--
If the client is logging under their AD credentials then WindowsIdentity.GetCurrent() would return a valid WindowsIdentity.
If client is not logged onto the domain then you can provide a pop up that would ask for AD credentials.
Well, just thinking...

Categories

Resources