7

In my work we've been tasked with implementing two factor authentication across a number of our web applications which currently share a credentials database (asp.net forms authentication) but have their own code for collecting and validating credentials etc.

In thinking through this problem I've reasoned that this might be a good time to consolidate all our authentication into one web service (FWIW I'm looking at IdentityServer) which all our various web applications could use.

To my mind this follows the DRY principle, will make implementing and testing the 2FA itself easier, and lead to a more maintainable system in the future. However in discussing my plan with a colleague he has suggested that I'm introducing a single point of failure to the system, and that if a bug were introduced to the Authentication service it would bring all our applications down. To be clear we're not talking about service availability (The service would be hosted with the same level of resilient infrastructure as our other applications which my colleague accepts as reasonable), but about the potential of a single bug to take down all our applications. His suggestion is that we either write the authentication into the individual applications or we should provide some sort of redundant auth system for if the primary system fails.

To me this argument just feels the wrong way round. If we're depending on different implementations to stop all our services failing then we're doing it wrong. However I've been unable to put a convincing case to make colleague. Some of the arguments I've put forward:

  • This is no different to using libraries between projects - If a critical bug in some of these libraries were to reach production it could take down a number of our applications - but we're not suggesting that we shouldn't be sharing code here. Is this conceptually any different?
  • Whilst there is room for improvement we don't have a terrible testing/deployment process. We use continuous integration, we have automated unit tests, a reasonable test environment and manual test scripts (not to mention the ability to revert a production deployment if we do get a bug through). Whilst bugs are always going to get through, this process is the mitigation against that, not writing things twice.
  • By its nature the authentication process is not the sort of thing that's going to be undergoing major changes regularly. Once we have an authentication system that works we're likely to leave it be, making the risk of breaking anything fairly low.
  • The DRY principle - Isn't writing the same thing multiple times more likely to lead to bugs and be a nightmare to maintain than having one service?
  • The idea of a redundant authentication implementation is pretty crazy to me. Maybe if we were writing autopilot software for an airliner, but not for non safety critical web applications.

My colleague remains unconvinced. Am I wrong? If I'm not, what is the killer argument that I'm missing here?

  • 2
    The arguments you've already listed should be perfectly sufficient to convince any sane person. Your colleagues logic makes no sense whatsoever. – Sean Burton Apr 5 '18 at 15:57
  • In case there will be a bug in a centralized authentification system, I am pretty sure it will be quickly noted by testers or users after the bug was introduced, so people can take measures against it. If there is a bug in the authentification of one of the applications, whilst the others work fine, the bug may stay undetected for weeks. That does not sound really better, I guess? – Doc Brown Jul 11 '18 at 8:04
9

Consolidating authentication into a single service is called Single Sign-On and it's been a thing, even a best practice, for like thirty years.

His suggestion is that we either write the authentication into the individual applications or we should provide some sort of redundant auth system for if the primary system fails.

You already have your ASP.net authentication in the individual applications, so, to be fair, “write the authentication into the individual applications” (with a lot of cut and paste, or shared libraries, or whatever) is probably the least amount of work.

The redundant auth system suggestion is a security problem as well as a maintenance problem and is clearly bananas. It's not a serious suggestion.

It looks to me like you have a people problem, not a programming problem. Your people problem is that you need to figure out your colleague's real reason for objecting. It probably isn't anything he's actually said.

Some possibilities:

  1. he feels that rewriting the whole auth stack for each application will be too much work.
  2. he feels that rewriting the whole auth stack for each application is too risky, in terms of possibly breaking the existing credentials authentication.
  3. he doesn't understand the IdentityServer solution and because of that isn't comfortable with it.
  4. he didn't come up with the IdentityServer solution himself and because of that isn't comfortable with it.
  5. he feels like taking on 2FA is enough new technology to deal with and enough new complexity to add to the apps, without taking on OpenID/OAuth/etc., etc.
  6. something else I haven't thought of

You need to find that underlying objection and evaluate it fairly. (He might even be right!)

One approach would be to step back from the specific solutions you've each advocated and try to at least agree on the criteria that should be used to choose a solution, taking into account each of your preferences regarding technical risk, short-term vs. long-term workload, etc. (In negotiation school, they call this distinguishing interests from positions.)

If, in the end, he's still convinced that he's right and you're wrong, and you're still convinced that you're right and he's wrong, you need to kick it up a level to where you can each present your preferred options to someone empowered to make the call. And then you both need to accept the decision.

  • Thanks for this, I think you're spot on here. People problems are far more tricky than technical ones, especially when you have no superiors with the technical knowledge to make an informed decision! I'll try your suggestion to agree criteria and see if that can get us closer to agreement. – Slappywag Apr 5 '18 at 18:07
  • @Slappywag Ideally, it shouldn't matter whether your superiors have the technical knowledge to make an informed decision, as they should be able to make it on non-technical grounds such as workload, schedule, priorities, risk tolerance, etc. Of course this depends on you and your coworker being able to honestly agree on things like effort and risks. – David Moles Apr 6 '18 at 17:53
7

That line of thinking that because you're depending on the same code, that counts as single point of failure is not necessarily wrong but absurd. With that logic, you can keep thinking up random things that follow that rule -- why use the same routers, switches, web servers, programming language, frameworks, etc?

The reality is that you are already using the same credentials database and you already have a single point of failure. In fact, if each of your systems have direct access to this database you might interact with it in a way that interferes with other applications. Going by the logic that you're no longer trusting code, you could argue that by having N number of authentication systems, you actually have N number of single point of failures. Whereas if you had a single API, you can control access and reduce your N to just 1.

  • +1 for pointing out the DB as a single point of failure – David Moles Apr 5 '18 at 17:45
  • Thanks for reassuring me that I haven't gone completely crazy, and this makes no sense! I did use the argument that we were using the same database whichever way we went, but to no avail. – Slappywag Apr 5 '18 at 18:11
  • 1
    Although to be fair, systems that require a high degree of fault tolerance do use different routers, switches, servers, programming languages, etc. E.g. the Airbus A380 has 5 primary flight computers performing the same calculations using two different CPUs, two different motherboards and two different Operating Systems, running two different sets of flight software, developed by two different contractors in two different programming languages. – Jörg W Mittag Apr 9 '18 at 7:49
  • That's pretty interesting to know @JörgWMittag! However, I imagine that in this case, those redundant systems are specced bottom up for redundancy. Making 1 or 2 libraries different really doesn't do very much for the overall fault tolerance of the system. If one of OP's db code fails, there is no particular redundancy there as a part of the system will completely fail to work. – Kevin Raoofi Apr 9 '18 at 14:44
2

We've had similar discussions where I work and your co-worker is not wrong. We came to the conclusion (we use Atalasian’s Crowd but the idea is the same as IdentityServer) that we could mitigate the risk using high availability architecture. There is a risk that if the service goes down users won’t be able to authenticate. To mitigate this risk I’d suggest looking at making IdentityServer highly available. Essentially you would run a load balancer (I like HA Proxy or Nginx) and have more than one instance of IdentityServer running. The instances would then connect to a cluster of databases.

This high availability would provide a couple of benefits. The first being that if a node or database goes down, functionality persists and availability is unaffected. The second being that it will distribute the load of users across the nodes. It’s a little more work up front but worth it in the end.

Here is the docs page that shows a typical deployment for high availability: http://docs.identityserver.io/en/release/topics/deployment.html

  • 1
    Agree with all of this and whichever way we go we will be running a load balancer and multiple instances running, unfortunately my colleague has a problem with the idea of those nodes running the same code! – Slappywag Apr 5 '18 at 18:10
  • 2
    It's not as if it's the space shuttle. – Robert Harvey Apr 5 '18 at 18:13
  • If I were working this issue I'd go with everything you've said so far. HA would be ideal and if you don't want to mess with managing applications on different servers look at Dockerizing the application so you only have to get the code running once inside of a container. You can then deploy the container to multiple hosts which would cutdown on overall application maintenance (do it once and then deploy multiple times). – Thomas Hastings Apr 5 '18 at 18:35
1

For what it's worth, the architecture that you're suggesting is what most sane large organizations wind up with. The fact that authentication is its own service makes it easy to create new features, such as OAuth2 authentication for third parties to use your APIs.

In fact the OAuth2 specification reveals this internal design in the fact that the authorization server is assumed to be separate from the resource server. If you don't know what I'm talking about, see http://search.cpan.org/~tilly/LWP-Authen-OAuth2-0.07/lib/LWP/Authen/OAuth2/Overview.pod for an explanation that I wrote a few years back about how OAuth2 works.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.