10

We're developing an iOS app, where the user needs to authenticate using email+password (or mobile number). Our backend is made of a couple of microservices using Akka-Http. It needs to be fast, scalable, concurrent, and the authentication+authorization should work across our multiple services. I'm trying to figure out which authentication method to use. Akka-HTTP currently offers Basic Auth and a partial implementation of OAuth2.

So at first we were considering Basic authentication (too simple and not enough functionality), Oauth1 (too complex), so we moved towards OAuth-2.0 because it is sort of a standard.

Then we considered AWS Cognito because it combines Oauth-2.0 and OpenID Connect which gives the authentication mechanism that OAuth2 lacks. http://www.thread-safe.com/2012/01/problem-with-oauth-for-authentication.html

Then we realised that OAuth2 is just for authentication using a third party - when in fact we don't need a third party authentication provider - maybe we need to do it ourselves, and using Cognito is an overkill that would create extra api calls outside our microservices...

So I read a little bit about creating our own custom auth provider, using WSSE specs: http://symfony.com/doc/current/cookbook/security/custom_authentication_provider.html And I also found this example using Spray, but I'm sure it's not that different from Akka-Http: http://danielasfregola.com/2015/06/29/how-to-create-a-spray-custom-authenticator/ It looks too simplified and doesn't have token expiration...

So my question is, am I missing something? What method should I chose and where can I find examples for it?

I feel like I'm going in circles, we're gonna have to write our own custom authentication provider from scratch, which kinda doesn't make sense. After all almost everybody needs authentication and it should be a standard.

Christian Neverdal
  • 5,655
  • 6
  • 38
  • 93
Yossi Chen
  • 226
  • 3
  • 11
  • 2
    Frankly I think you're overcomplicating it unless there are specific requirements that you haven't mentioned. I normally put API behind HTTPS, allow mobile client authenticate with username/email and password and return UUID-like token. I store tokens in some sort of distributed cache (memcached, ehcache, redis or similar). – expert Feb 02 '16 at 13:44
  • Where are your microservices running? – perpil Feb 02 '16 at 22:59
  • I don't think you need OpenID Connect in your scenario at all, so a simple OAuth2-Service that issues accessTokens (see jwt.io) which includes userId, role and expirationTimestamp should be everything your services need to independently authenticate/authorize requests. The only thing that's a bit tricky imo is the refresh-token handling. – felixbr May 07 '17 at 13:38
  • Thats what we did eventually, and we implemented our own simple refresh token behaviour – Yossi Chen May 07 '17 at 14:11

2 Answers2

0

I've recently been using SoftwareMill's akka-http-session library and found it simple and easy to integrate. It has support for case class based sessions, JWTs, refresh tokens with pluggable storage, using headers and CSRF tokens as well as some nice simple directives for use in routes.

Brian Smith
  • 3,383
  • 30
  • 41
0

My solution for user registration has been to use Keycloak, an open source server which can handle user registration and do OIDC, OAuth2 style login. It reduces the amount of code I have to write, and the code is more secure than if it rolled it myself.

I then write my application as Scala backend that's purely a JSON API and a React/Javascript rich frontend in front of that API. In this configuration the authentication is handled completely on the front-end (and can be done in your iOS client). The front-end app redirects the user to Keycloak and when the user comes back they have a signed "JWT" token you can keep in a cookie.

That JWT token is attached to all API calls made the JSON backend as an Authorization Bearer token HTTP header. The token itself contains the users email address and is cryptographically signed by the Keycloak server.

The backend gets the JWT token in the HTTP header, extracts the email address and verifies the token is cryptographically signed by the keycloak server.

It's performing a certificate check on the keycloak server and can cache it's certificate. So it doesn't need to have roundtrips like OAuth, or any upstream calls to make.

This gives us simple, low-chance-of-failure, high speed authorisation in our JSON backend API and means we aren't putting secrets in the iOS client, or rolling too much of our own code.

Philluminati
  • 2,649
  • 2
  • 25
  • 32