How to implement token based authentication for my API? - rest

I have a Django backend which will be served as my API endpoints. Users are identified by username and password and have some extra information and should be able to consume my same API, so I want to grant tokens for them.
How to create API keys for them to use? (Would a uuid serve a good purpose here?)
How to generate tokens for them? (I could imagine that some way like sha256(api_key + password + some_salt), where salt is some timestamp object would do the trick and also help in expiration)
How to generate a refresh token to be used for refreshing an expired token? (I have no idea here)
I took a look at Oauth 2.0 but TBH I could not figure it out completely and it is overly complicated as my API server will also be my authentication server.

I would not recommend to build your own authentication scheme, nor deploy your own cryptographic functions. Nowadays the industry standard for API authentication and authorization is OAuth 2.0, it provides all the requirements you've described in a robust but rather simple to implement solution.
If the mentioned application does not require any of the OAuth 2.0 authorization concepts, using OpenID Connect is certainly a great approach. OpenID Connect is a protocol built on top of OAuth 2.0:
It allows Clients to verify the identity of the End-User based on the
authentication performed by an Authorization Server, as well as to
obtain basic profile information about the End-User in an
interoperable and REST-like manner.
API authentication technologies are widely available in different forms, even SAML 2.0 can be implemented for such scenarios (more infrastructure is required), anyhow for what you have described, OpenID Connect certainly cover all requirements.

The easiest way to solve this is a classical Session-Cookie, Django directly offers this functionality.
If you do not want to hold state on the server side you may look into JSON Web Tokens.

Related

Is it possible to have two type of auth flow?

Background information: The REST API will be used by a web application and server
We are thinking to have the code flow for the web application and client credential flow for the server part (machine to machine authentication). As tool, we will be using keycloak
But the problem is now that we are not sure if it is possible to have two oauth flow on one REST API.
Is it possible to have two oauth flow for one REST API?
And if it's possible, how can you do it?
This is fine. In both cases the clients will perform OAuth flows using Keycloak, and these can be completely different. Your API needs to knows nothing about how clients authenticated, and in both cases receives a JWT access token.
The two different clients will not always call the same API endpoints. They are likely to use different scopes and claims, and your API authorization design needs to deal with this. The server client will not provide a user identity via a subject claim, whereas the web app will.
The way to cope with these differences is usually to design a ClaimsPrincipal during JWT processing, then apply authorization rules based on the data received within the API's business logic.
In some cases, operations designed for the server client should not be callable from the web app, and vice versa. Scopes and claims will enable you to achieve this.
EXAMPLE API
Maybe have a look at this code sample of mine and the blog post. The key point is that the API performs these steps. If you do the same steps you will be in good shape:
Validates JWT access tokens
Builds a claims principal
Enforces scopes for each operation
Uses the claims principal to apply business authorization rules
My API does some slightly advanced stuff like look up extra claims, which you can ignore. Note that the API doesn't know or care which flow clients used - there could be 5 different flows. The API's job is just to work with scopes and claims.

OAuth2 for REST API with tightly coupled SPA as only client

I'm developing a REST API with a tightly coupled SPA as the only client of the mentioned REST API.
Let's say the SPA is available at myservice.com and api is under myservice.com/api. They're basically one service, just split at code level, and deployed at different root paths.
What I'm using for security right now is OAuth2 with ROPC (username/password) grant type.
Here comes the problem. I keep reading everywhere that ROPC is not secure and should not be used. What should I use then?
My REST API acts as an authorization server but it doesn't have any web interface itself. So any flow involving redirect doesn't really make sense. The SPA and API are so tightly coupled that for an end user they're basically one application. There's no 3rd party.
I could add simple login form to the API available at let's say myservice.com/login. But I'm struggling to see the difference that would make.
Security in this application is very important.
Here are my questions:
Is using ROPC really dangerous in this scenario?
What would be the perfect way for authentication and authorization?
Or maybe OAuth2 is completely redundant without a third party?
Technologies used:
Server: Spring Boot
Is using ROPC really dangerous in this scenario?
No, not really providing:
a) You don't store a user's password - maybe only use it to get the initial access and refresh token - although that could be tricky with an SPA.
b) Your SPA client and the resource API are owned by you, so you don't need the user to consent to specific scoped access for the SPA.
What would be the perfect way for authentication and authorization?
It depends on lots of things. Not enough info to try to answer that. OAuth2.0 (with a probably implemented Authorisation server) is a pretty good way for the example you have here.
Or maybe OAuth2 is completely redundant without a third party?
If other applications will use your API in time then OAuth2.0 is probably a good call. Otherwise you could probably use a more simple solution e.g. session cookies as all sits on same domain.
Answer to this can be taken out from OAuth 2.0 specification (RFC6749) itself. It define when ROPC grant is suitable for,
4.3. Resource Owner Password Credentials Grant
The resource owner password credentials grant type is suitable in
cases where the resource owner has a trust relationship with the
client, such as the device operating system or a highly privileged
application. The authorization server should take special care when
enabling this grant type and only allow it when other flows are not
viabl.
According to your explanation, you have tight coupling with SPA and backend. Also you have both authorization server and resource server built as one. This is completely acceptable implementation.
The authorization server
may be the same server as the resource server or a separate entity.
So what matter now is to clear out why you use OAuth 2.0 in your scenario.
If you are using OAuth 2.0 to obtain tokens, maintain them as defined through OAuth 2.0 specification, then this is completely oaky. But if you are doing this to follow a trend, think twice.
OAuth 2.0 implementation comes with it's own complexity. You have to maintain user identities, maintain tokens and renew them. You are building a complete authorization server by yourself. But this also have some advantages as well.
For example, same authorization server can be used to issue token for future integrations/secondary app. IMO, usage of OAuth 2.0 make integrations easy as it define a protocol for issuing tokens, renew and revoke them.! But in such integration scenario, may be you will require to use a different grant. Still, your API being authorized on token, you only need to worry about how new integration/application obtain tokens. This is better than using authenticated sessions
Going back to your questions,
Q : Is using ROPC really dangerous in this scenario?
As explained, if there is a correct trust relationship between client and authorization server, then it is fine. But be mindful about complexity comes with having a authorization server.
Q : What would be the perfect way for authentication and authorization?
OAuth 2.0 is for authorization. You obtain access token and use them to authorize against your protected APIs. From APIs you do a token validation to detect correct access levels/permissions.
If you want authenticaiton, then you must use OpenID Connect. It is a protocol extended from OAuth 2.0. And allows your application to authenticate the end user based on ID Token. You can use ROPC grant to obtain an ID token.!
Q : Or maybe OAuth2 is completely redundant without a third party?
Not necessarily. It allows you to design your APIs in a modern, standard way. Who know what future hold (again the integration scenario). Following a protocol allows that easy.
Only advice, follow specifications closely. Do not invent your own protocol/adaptation. It makes things harder to maintain.

Authentication with Akka-Http

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.
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.
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.

Authenticating REST API clients for just my App

What is the best way to authenticate clients that uses my private REST API? I will not be opening this to outside public. Is there a easy and secure way to do this?
Note: I'm running SSL already. I've looked at HTTP Basic Auth over SSL, but I don't want to ask the user to send the password every time, and it seems not good practice to store the user/pass in the client to be send automatically.
Any ideas or best practices?
You can use the most adopted authentication approach which is OAuth
You select the best suited one between OAuth 1.0a and OAuth 2.0
Here is a comparison between the above two ways : How is OAuth 2 different from OAuth 1?
There are several levels to implement security / authentication in RESTful services:
Basic authentication. Username and password are sent for each call within the Authentication header encoded with based 64.
Token-based authentication. This implies a dedicated authentication resource that will provide temporary token based on credentials. Once received there is no need to use again credentials since this resource also gives a refresh token to a new authentication token when the previous expired.
OAuth2. It provides different flows according to the use cases. It allows to let the end user to authenticate through a third-part provider (google, facebook, ...). The application doesn't manage username / password (and even know the password). The drawback of this technology is that it provides high-level hints and it's not so simple to implement.
Here are some links that could provide you some additional hints:
Implementing authentication with tokens for RESTful applications - https://templth.wordpress.com/2015/01/05/implementing-authentication-with-tokens-for-restful-applications/
OAuth2 flows - http://www.bubblecode.net/en/2013/03/10/understanding-oauth2/
Hope it helps you,
Thierry

Secure RESTful web service using Symfony2

We are in the process of planning an iOS application in which users will need to be authenticated and authorized before they can interact with data provided by a Symfony2 web service.
Authorization will be implemented with ACLs, it's the authentication I'm not sure about.
From what I found in my research, there are a few ways to achieve the authentication part, but since there won't be any third parties accessing the data it sounds like basic HTTP authentication paired with a SSL certificate is the way to go. Is this correct?
Additionally, is a simple username and password secure enough, or is it better to add some sort of API key for identification?
If a key is needed and considering our users will be part of a group, should a key be bound to every user individually or to the group as a whole?
Finally, and slightly off topic, Symfony2 has FOSRestBundle, is there a defacto REST library for iOS?
For securing REST applications in symfony the FOSOAuthServerBundle is very useful. With it you can implement easy OAuth authentication for your app. OAuth is de facto standard for securing REST web services.
As https/ssl is pretty secure you can go for basic http authentication and/or the api key solution.
Wether to use a key and/or username/password is your personal choice.
If somehow requests can be catched in cleartext either one is compromised.
Keys in addition to username/password auth can have the advantage of seperating i.e. user contingents.
Basic http authentication is mostly used, therefore the chance of your client having already available methods to integrate it from his side are high.
You should always give out unique keys or username/passwords to every user in order to be able to log who did exactly what.
I'm not that much into iOS, sorry.