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
Related
The architecture of the system is like this
User can log into the website using either username-password approach (after registration) or a google-sign-in.
I want to know how can I implement authentication and authorization for this scenario.
Here is what I am thinking of implementing :
Have an REST API server built over NodeJS and Express.
The login and registration processes are handled by this server as well.
The authentication is done by using JWT Tokens stored in the client side. And these tokens are then used again for authorization of endpoints as well.
How much secure is this approach? And how can google sign in be added to this architecture.
And also if a seperate server for making auth requests is needed as mentioned in OAuth 2.0?
It would be better if the system remains Stateless to follow the principles of RESTFul APIs.
This post that I have written might give you some insight.
https://dev.to/ralphwjz/login-management-for-spa-and-everyone-else-12o6
The post covers Github login but if you replace GitHub with google, the rest of the flow is exactly the same.
I can answer more questions once in context
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.
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.
When I use public APIs from web applications, I am provided with an API key that I use inside my client, as a string.
Now suppose I design a REST API for internal consumption. Let's say for a mobile app eshop. The user of the eshop logs in with a username and a password.
Does that mean that my client won't use API key authentication but username and password? I also see OAuth2 a lot in REST APIs, which also seems like a key-oriented authentication. Are they just different types, all valid ones? The API keys are usually issued for developers though, could that work with customers?
It could work and it's also what you will be seeing in many cases. You login with username and password (POST request) and the server returns you an authentication token which you store in a Cookie through response headers. When user specific information is being required you would be using that token to authenticate, similar to how OAuth2 and dev keys work.
Based on my understanding on your question -
There are methods or way on how you can authenticate your api. Some of the common ones are through Oauth, Token authentication and Basic auth (username and password).
You can read some of the concepts here - http://www.django-rest-framework.org/api-guide/authentication/
Hope this helps
I would like to build my own REST app.
I'm planning to use oAuth as a main auth approach.
The question is: Can I use login and password as client_id and client_secret (in terms oAuth spec) ?
I don't have any third side applications, companies, sites etc... which will authenteficate my users.
I have my own REST server and JS-application.
Whole site will be made in usual(RPC) approach, but some private part will be done as RESTfull service, with enough stand-alone JS application.
UPDATED: I'm not sure that I even need full oAuth support. It seems to me that I can ask login and password on https page and then generate some token. Later i could use it to check is this user authenticated already or not. But in this case this oAuth become almost the same what we have in web aplications. I do not need oAuth to athorize users ?
I'm not consider HTTP(s) authotization because i don't want to send evrytime user and password to server.
No.
One if the main reasons OAuth exists is to allow integrations without users compromising their usernames and passwords.
If you plan on using username and password, look into xAuth as an option if you still want to sign your requests. More info: https://dev.twitter.com/docs/oauth/xauth.
But you could likely just as well go for HTTP Basic Authentication. At least if you publish your API over SSL. More info: http://en.wikipedia.org/w/index.php?title=Basic_access_authentication
I think you might get a better answer on the security site. See, for example, this question.
In any case, you need to start with a detailed assessment of what attacks you are trying to prevent and what attacks are "acceptable.". For example, if you are using HTTPS then you can probably accept the remaining danger of a man-in-the-middle attack, because it would require forging an SSL certificate. It is harder to say in general if a replay attack is acceptable.
One reasonable solution would be to create a time-limited temporary token by having the user authenticate over HTTPS with the username and password, generating a secure token with an expiration date, and then sending that token and expiration date back to the client. For example, you can create a (reasonably) secure token by taking the SHA1 hash of a secret plus the user name plus the expiration timestamp. Then the client can include the token, the user name, and the authentication timestamp in future requests and you can validate it using your secret and your clock. These need not be sent as 3 parameters; they can be concatenated into one string user|timestamp|token.
Register your application with SLI. SLI grants a unique client ID and a client secret that enables your application to authenticate to the SLI API. You must also register the redirect URI of your application for use in authentication and authorization flows.
Enable your application with specific education organizations so that the application can be approved for use in those districts.
Configure and implement the appropriate OAuth 2.0 authentication and authorization flow in your application, which includes managing sessions and authorization timeouts.