Kerberos, delegation and how to do this correctly? - kerberos

I've got two separate homemade applications that need to communicate among themselves. One is a frontend application (asp.net actually), the other is a backend interface to an accounting application. The backend interface was not created specifically for this frontend - it is a generic interface that many other applications use to integrate with our product.
For the convenience of users we wish to provide a Windows Authentication in our frontend application. That means however that we need to pass the credentials on to the backend application which has to check them.
We do not wish to set up our frontend as a "trusted" application to the backend which can authenticate itself as any user. If the frontend was to be hacked, it would then also compromise the backend system.
As I understand it, one way to do it with Windows Authentication is Kerberos Delegation. However this requires to be explicitly enabled for the user that is to be delegated, and the machine which does the delegation (the server with our frontend). By default these options are disabled in Active Directory, and I suspect that many sysadmins will have their reservations about turning them on for all their users.
Also, I'm not really sure that this is what Kerberos Delegation was meant for. I don't need our frontend to impersonate the user that is connecting. I just need to prove that this user has authenticated itself to me.
How would you do this?

I'm not clear what you can and can't do with your use case but I can answer the question what Kerberos Delegation was meant for.
First let's talk about what Kerberos does prior to delegation. It is important to understand this part well because it is subtle.
Kerberos authenticates the identity of BOTH ends of a communication between two end-points across a network, those end-points can be interactive users or services running on a computer.
This is strong authentication so it will not allow a man-in-middle attack in any form. If set up correctly an end point can guarantee they won't be compromised. To the level of the service name (if you are connecting to IIs on a machine it is different than connecting to SQL Server on the same machine). It makes heavy use of modern encryption techniques and requires the use of secure certificates. The details of the authentication protocol are complicated and not worth going into now, but it involves about 20 different distinct steps of confirmation between the two authenticating end points and authentication server (in windows the Domain Controller is the authentication server).
So what the heck is delegation?
Delegation is a Microsoft extension to the Kerberos standard which
allows a trusted source to continue the authentication to another
end-point.
This allows you to act as a "man in the middle" -- however many settings have to be explicitly setup, certificates installed, etc to allow this to work. It is far from simple. (EDIT: Here is another SO answer on the details - https://stackoverflow.com/a/954154/215752)
So, for example, you could have someone authenticate to a website and then have the .NET code connect to an SQL Server AS THE SAME USER to read data with that user's rights.
Now to answer your question, since I'm not sure what you want to do I present three choices:
1) You want to connect to the back end system as the SAME user as the one authenticating at the website.
In this case Kerberos delegation is perfect -- it does exactly what you want.
2) You want to connect to the back end system as a DIFFERENT user than the one authenticating at the website (eg a service account).
In this case you don't want delegation. Kerberos to the website and Kerberos (as a different user) to the back-end will work great.
3) You want to connect to the back end system as the SAME user some of the time and as a DIFFERENT user other times. (For example, you need to validate this is a legal user for the back end system, but want to perform trusted actions as a system account other times. This is (in my experience) the most common use case.)
In this case you use both. Delegation for the connections which need to validate the user identity and then revert to the service account identity for the times when you need system access to the back end. (A previous question of mine went into the details of how to revert to the system identity on the .NET platform see How to "un-impersonate" (un-delegate?) in Kerberos.)

Here is a post describing how Kerberos works and how to set it up.
ASP.NET passing along Windows Authentication credentials

Actually Kerberos delegation is designed exactly for this use case. But the challenge here is craft this on a legacy system and with AD's settings that you do not want to change.
One possible hack is to have the Front End just send the user and the time of authentication but the backend can query the Active Directory Event Logs to determine whether that user has authenticated to the Front end. This requires you to use WIndows Event Log API.and also play around with Event Log settings in AD to log the issue of service tickets. (MY recollection is that this is the default)
-

Related

Should I use keycloak or not?

I'm just starting a new project. The result will be an API server and a progressive web app. The API server is implemented with TypeScript and the NestJS framework, the client with Angular 6.
I've been flirting with keycloak for some time. Still, I'm not quite sure it's right for me yet. But I don't want to worry about things like token renewal anymore and find it sexy that Keycloak tells me how to create user roles.
What bothers me, is the following - integration. For my use case it is necessary that the login and all features like password reset and so on are part of my application. That means I want to create forms myself in order to be able to do this perfectly in my own design and not have a second translation process, etc. Keycloak themes are not an option. So is it possible to hide keycloak in such a way, or is it so complex that I shouldn't use Keyloak in the first place? Afaik there is already an issue with password resets - I can't request it from the user side but have to make an REST call to the admin endpoint - which is okay but not ideal since it requires me to do more server side logic ( and that is not why I want to use Keycloak).
In addition, Keycloak is too much about the GUI - which makes it difficult for me, especially during development. Because I also want to provide my team with a local instance of keycloak during development. But what is the concept to import the initial data into realms, apps and also users into Keycloak? I found some JSON imports - but so far only for realms and apps. Is there also a function to import a whole dumb?
So that my team builds on a pre-built setup and has a user for each role. A reproducible setup with Vagrant or Docker which contains the import of initial data - that would be the goal.
So in short my questions:
Is it still worth the effort using Keycloak if I want to use everything via the API or should I simply use Passport and JWT?
Can I have a reproducible setup during my development that includes realms, apps, users, user roles, etc?
So, the question asked few months ago, but I also faces with that question, and I want to answer on it.
I think that you don't need Keycloak, it is fairly enough for you to use OAuth2 and JWT.
Let's justify my answer:
You have just one client - Angular application. Keycloak useful, when you have many clients (web-js, mobile platforms) and you want to create and manage them dynamically. But, I think that, in your case, you create your client once without modification in the future.
Also, Keycloak very useful, when you have a lot of integration with third part systems (Google, Fb, Twitter and etc) because Keycloak has them out-of-box. Or you need to integrate with some SAML or LDAP provider.
You may use Keycloak, if you need some Identity and User management platform, and when you have complicated user access flow.
In the end, you could consider Keycloak, if you need SSO (Single Sign On) feature. Once logged-in to Keycloak, users don't have to login again to access a different application. But, by your description, you have just one application.
Keycloak offers features such as Single-Sign-On (SSO), Identity Brokering and Social Login, User Federation, Client Adapters, an Admin Console, and an Account Management Console.
It's an out of box solution for rapid security layer development of application.You could have single common security layer for multiple application .
You can implement you security mechanism without using keycloak.

Securing rest app (separate view and server) + social logins

I'm getting into the world of fullstack development and I'm trying to develop app which front is completely separated from backend (front is being served from node server and backend is java).
Now, the issue - how should I get about securing my app?
I'd like to have many fronts and many backend instances connected through load balancers and I'd like to keep all the state on client, so I can without any issue switch to another backend server and continue as nothing happened.
Currently I'm using OAuth2 tokens but I'm concerned about security and stealing the tokens, which are completely stored in cookie on user side. Also, The app (obviously) stores those tokens somewhere, so another instance of my backend app wouldn't accept the token. In best case scenario I can implement some mechanism that would automatically request a new one and in worst case I'd have to login again. I don't want that to happen.
Also, here I have a problem with social auth. Allright, I'm receiving token from Google on front, but giving it to backend and creating a user there is major pain, I have to write a lot of code manually to create such user and save it.
And again, I'm not certain about security level of this solution.
So the question is basically - currently, what is the best way to secure an app which should have completely separate front and backend, which would have no issue with switch backend server between requests?
As regards tokens being stolen from the Client: you can't do anything about this. It is up to the client to protect themselves. What I mean is, if you need a username and password to access a service, and the Client is infected with a key-logger, and a hacker steals those credentials, there is nothing you can do on the server side to protect against this.
As regards your idea of multiple back-ends, this is a common feature of any system with multiple application servers. For example, if you have multiple web servers and want any request to be routable to any server. For this, you need a central database which stores any information which needs to be shared. It's slower, obviously, but much more resilient.

Host my own user authentication service on my own server?

I have tried Google with queries similar to the title of this question, but haven't found anything useful.
Background: I am building a web app and would like to add a user authentication level to it. I cannot imagine anything worse than building a user authentication system from the ground up, so I want a quick solution.
I'm looking for open source software I can host on my server that provides an auth layer I can connect to, with multiple user accounts
Criteria:
I want to host the software on my own server
Provide a log in screen that works with multiple sign in strategies - twitter, facebook, vanilla email, etc.
Persists users to a database (preferably postgres) and persists session data
Preferably lets me store a minimal amount of data per user, like key value store
Has a client-side (Javascript) API, like Facebook's JS, so I can use this auth service on multiple sites. Namely, I want to use it on localhost or my own file system (when allowing file cookies). Client side JS API exposes methods like log in / log out
Has a server side API (such as exposes local RESTful endpoints) so that when I do build out my server side app for other data storage outside of the user, my app can query the auth service for log in status.
I want to run this stack completely independently of my own app - in fact I want to run this auth service and purely communicate to it from my local dev environment without building any server side app of my own.
I have used Firebase and they do many of the things that I want, including log in strategies and the client / server side APIs, but I want to be able to host my own version of this.
I can't imagine anyone takes pleasure out of building user authentication of any kind, so I'm surprised I haven't found anything in research.
I also know this is an open-ended question, but as far as I can tell I haven't found anything satisfying my requirements.
I like Devise (https://github.com/plataformatec/devise), which is for Rails. It has an active community with a boatloads of plugins available that can fulfill many of your requirements.
I didn't see a language specified; most languages and frameworks have their own implementations. Can you provide more information?
Example: I use the Flask framework on python. In addition, I use the Authomatic library which provides Oauth access for twitter, google, facebook, etc.
What I was looking for is something called a Single Sign On solution. According to this list there is nothing currently that meets my criteria.
Instead I have chosen to just run a local webserver and implement a regular auth flow.

Why I should NOT use Facebook Connect or OpenId for logging in users?

Jeff Atwood argues that we should stop asking users to register on our websites because we should rather use their "internet driver's license -- that is, [their] existing Twitter, Facebook, Google, or OpenID credentials" for authenticating them.
While I am beginning to think that he may be right, I could not yet decide and I am looking for arguments against letting foreign sites gain control over personal web pages.
Do you see any dangers of authenticating users like this?
if you want a more in depth response based from someone who has dealt with this technology before, you should listen to the recent .NET Rocks with Rob Connery which was precisely about this topic.
http://www.dotnetrocks.com/default.aspx?showNum=626
After listening to it I decided to NOT use OpenID on my site.
Here is the link to Rob's blog post on the subject:
http://blog.wekeroad.com/thoughts/open-id-is-a-party-that-happened
Here are a number of reasons why not, although each comes with caveats:
If you only authenticate with one external service, anyone who doesn't use that service cannot use yours.
If your external authentication service goes down, users won't be able to use yours until theirs comes back up; similarly, slowdowns in their authentication server will also affect you.
Requiring users to authenticate with another service requires them to accept that service's EULA, which may be a turnoff for some; similarly, it ties you morally to whatever decisions your authenticating service makes. In particular it can make you appear to be a satellite, spinoff or affiliate of the auth site, since users have to see their logo every time they try to use your service.
The external auth domain gets a perfect snapshot of your viewership, giving them a lot of insight into what your company is doing. Since their analytical tools and staff are generally top-notch, they may conceivably know more about your user base than you do.
The major way to avoid this problem is to allow people to use the service of their choice, instead of a single service. If you are limited to developing one, for development time constraints, using OpenID is the best bet because many other authentication domains also qualify as OpenIDs, and therefore ameliorates most of the above problems.
I think using IDs from any of these big names are ok as long as you don't provide service that needs an endpoint like email, IM etc.
However, OpenID is just not trust-worthy. If you have any doubts, try this OpenID
http://opennoid.appspot.com/anyid
This is a disposable ID that doesn't require a password to login.

Confusion about Kerberos, delegation and SPNs

I'm trying to write a proof-of-concept application that performs Kerberos delegation. I've written all the code, and it seems to working (I'm authenticating fine), but the resulting security context doesn't have the ISC_REQ_DELEGATE flag set.
So I'm thinking that maybe one of the endpoints (client or server) is forbidden to delegate. However I'm not authenticating against an SPN. Just one domain user against another domain user. As the SPN for InitializeSecurityContext() I'm passing "someuser#mydomain.lan" (which is the user account under which the server application is running). As I understand, domain users have delegation enabled by default. Anyway, I asked the admin to check, and the "account is sensitive and cannot be delegated" checkbox is off.
I know that if my server was running as a NETWORK SERVICE and I used an SPN to connect to it, then I'd need the computer account in AD to have the "Trust computer for delegation" checkbox checked (off by default), but... this is not the case, right? Or is it?
Also - when the checkbox in the computer account is set, do the changes take place immediately, or must I reboot the server PC or wait for a while?
According to this ISC_REQ_DELEGATE is only ignored if you use constrained delegation. I'm pretty sure for constrained delegation to happen, you have to explicitly state which services the account is allowed to delegate to in Active Directory (delegation tab for a user or computer in the AD snap in).
I'm not sure of the rules using UPNs vs SPNs. Have you tried turning on Kerberos event logging and looking in the event log? The messages are often cryptic but usually possible to decipher.
Your description of the NETWORK SERVICE scenario is accurate. Trust for delegation is off by default, but NETWORK SERVICE might have permission to self register an SPN (I think this can be determined by group policy).
When you tick the box the change takes place immediately, but may have to propogate throughout all the domain controllers in the domain (I typically test in a test domain with a single DC). So, restarting your service app is enough, you don't need to reboot.
The Kerb tickets reside on the client machine. These have an expiry time, and can be flushed manually using klist or kerbtray.