REST Authentication in practice - rest

According to the REST there is no such term as "logged-in" user, so each request Authentication should be passed, to enable user authentication on the server.
The questions are:
What are the approved techniques in practice which make sense to use? AWS? OAuth?
How to obtain the initial token which can be then resend with each request?
Are there any vulnerabilities if someone get access to this token, and can identify him as a different person, using this auth token.

There is no approval body for REST, so there's no mandated or standardized technique. The closest thing to an "approved technique" is HTTPS.
Use HTTPS and have the client send their credentials securely each time within each request. Avoid having the server dictate any kind of token to the client for the purpose of session management because that's more data the server will have to manage.
Sure, just as it would be bad to have someone get your email password...

Related

Facebook oauth2 - secure after-login use

I would like to ask little theoretically.
I have an angular6 + spring app that has its own client, app-specific client data.
These data can be divided into two groups
managment-data: Like client roles that allow client to visit different parts of app
client-data: personal settings, history of activities etc.
Because I would like to make login as user-friendly as possible, I would like to implement facebook login.
After user click "FB login button", facebook returns me some-user info and mainly a security token. How could I use this to securely communicate with my BE.
When someone sends request to BE, I need to be sure, that its the same person that logged in to facebook.
If I send this token as part of request, what stops possible attacker to somehow obtain token and then impersonate original user?
In what form I should send data I got from Facebook to my own server?
How should I work with token on server?
How can I validate its authenticity?
Thank you for answers
Filip Širc
You should look into the usage of OpenID Connect along with OAuth protocol. It allows you to authenticate the user to your client application (Angular6 + Spring app) to verify the user details.
When you are sending an access token to access a certain resource, you should avoid sending it as a request parameter. Usually it is encouraged to send it under the Authorization header of the request as a bearer token. However, if you want it to be extra secure, you could encode the token before sending so that it would be difficult to decode it and steal any valuable information.
Also, when you are sending sensitive information, it ise better to send them in the form of a JSON Web Token (JWT). You can use a third party library to create a jwt to include the information that need to be sent to the server. You can sign the jwt with your own signature which can be validated later. Refer https://www.rfc-editor.org/rfc/rfc7519 for detailed information about jwts.
You should use the claims in your access token to grant a user access to the resource you are protecting. Since most of the tokens are sent in the form of jwts, you can decode them and get check the necessary claims such as scopes, audience (client app), subject (user), etc.
Most importantly, you should validate the signature of the token sent from Facebook to make sure its an authentic one. For this, you have to get the public key details from Facebook's jwks endpoint and validate the signature using a third party library (auth0, nimbusds, etc.). Facebook's digital signature will be unique and this verification process is the best way to ensure the security. Also, you can check whether certain claims in the token match your expected values to validate the token. This can also be done through libraries such as ones mentioned above. Here's auth0 repo for you to get a general idea.

How to communicate frontend with microservice architecture?

I'm struggling with setting up reliable and performant solution to communicate frontend with different microservices. I do not really now how to maintain (maybe not need) CSRF between my frontend and end services
Solutions stack: PHP, Laravel Passport, JWT, oAuth 2.0, Axios
Current approach:
Actually I've started up with approach from Laravel's passport
https://laravel.com/docs/5.4/passport#consuming-your-api-with-javascript
Using oAuth 2.0 to authorize user from website A to service B.
JWT token is returned for further communication.
Token is saved in cookie within website A
Once user is authorized website A uses JWT token to manage requests without additional to oAuth server, by sending JWT token as cookie using HTTP headers (withCredentials) to authorize user.
For each website A's request there was CSRF token created from service B since user is authorized and cookie could be applied by another unauthorized website to access service B. That was killing my performance since it has to retrieve CSRF for each request made. (that what I actually assume from laravel passport approach and need to create CSRF with JWT token - maybe that was mistake)
My concerns:
Regarding to of James Ward post:
http://www.jamesward.com/2013/05/13/securing-single-page-apps-and-rest-services
The easiest way to do authentication without risking CSRF
vulnerabilities is to simply avoid using cookies to identify the user.
Cookies themselves are not the cause of CSRF vulnerabilities. It’s
using the cookies on the server to validate a user that is the cause
of CSRF. Just putting an authentication token into a cookie doesn’t
mean it must be used as the mechanism to identify the user.
From my understanding setting JWT with website A's cookie with its domain set could not be accessed via any other site from outside. Since that there is no possible way to make request to service B without accessing JWT.
So do we really need CSRF then to secure potential attack to service B while using JWT?
If so, how could I achieve the best (in term of performant) way to generate CSRF through different services to be sure that communication would not be vulnerable for attack from different sites?
Any advice will be appreciated!

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

Rest application and authorization

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.

How do I implement authentication the restful way?

I'm building a picture diary on web application google app engine using python. Users can sign up and post pictures to their diary.
Also, I'm trying to conform as much as I can to the REST architecture of doing things.
The authentication scheme is based like this for the web application:
1. Post username/password from the frontend
2. Backend sets up a cookie if authentication is successful
3. The rest of the AJAX calls made are authenticated using this cookie.
Is there any way to conform to REST without using cookies ?
Now, I'm also building an android application where users can sign in and post/view their picture diary. I need to expose the data from web application's datastore so I'll be building a webservice to fetch data from the datastore.
The authentication scheme for the android client:
OPTION a
1. Post username/password over https to the web service
2. Web service returns a unique authorization token (store the token in the username/pwd table on the datastore)
3. Request subsequent services by adding this token to the Request Header of the request
4. Server maps the token to the username/pwd table and returns data if token is found
5. Authorization token expires after a certain period of time
OPTION b
1. Set up a secret key on the client and server side
2. Use "username:hash of password and secret key" in the authorization header of every request
3. server generates the password by extracting the password from the hash value using the same hash algorithm ; if successful returns data
btw, I didn't wanna use basic authorization because of its security vulnerabilities.
Which is better ?
Are there other significantly better ways to accomplish what I'm trying to do ? Security is quite a concern for me btw.
I'd appreciate if anyone has any insight into this issue. thanks.
I've been doing some research myself as to what would be the best solution. I think the 2-legged oauth might work in my case as Leonm suggested.
In this case the server has to provide the client with a consumer key/secret which in my case is hardcoded in the app.
The steps now would be:
1. Generate a signature using the oauth_parameters(consumer_key, signature_method, timestamp), request url, request parameters, and the SECRET.
2. Include the signature, oauth parameters when making a request.
3. Server verifies the request by generating the signature again except in this case it uses the SECRET that corresponds to the key
I think this way I am pretty much confirming to the REST principles. The server is statless as I far I understand now.
What are the pros/cons on doing things this way?
If "security is a concern" then I would say that you'd be a lot better off using open standards and a library to achieve what you want. The main reason for this is that if you do it yourself, you're very likely to forget something; these standards have had a lot of eyes looking at them, looking for holes.
Your options include (in increasing level of complexity)
Basic authentication and HTTPS
Everything is encrypted, which makes it impossible to compress or look into, it increases the overhead somewhat, using more horsepower on the server, and more perhaps battery power on the client. Simple to implement, since it's well supported by libraries.
Digest authentication
Unencrypted messages pass the wire, but the authentication is securely managed in the Authorization headers. See the wikipedia entry for more information.
OAuth
See how Google is providing OAuth for installed applications. I believe it isn't what you're looking for, since you're not asking to share data between applications, just authenticating users.
Roll your own
If you want to roll your own, I suggest looking at e.g. how Google's (now deprecated ?) ClientLogin used to work.
Clients would GET a protected resource, and get a 401 with instructions to perform a GoogleLogin authentication, including a URI for where to perform the login itself
Clients (knowing how to do this) POST a request in a specific manner to that URI
The server responds with a specific response including a (long) token
The client can now perform GET requests to the protected resource with that token.
Statelessness
You cite REST, which dictates that requests should not specifically depend on prior interaction: "... each request from client to server must contain all of the information necessary to understand the request, and cannot take advantage of any stored context on the server." (fielding) This means that a server shouldn't store conversational context (like an authentication token) in a table.
One way of fixing this is by using any of the token based approaches (where the server tells the client about a token it should use for future requests) where the token is not a random number, but a message to the server itself. To protect yourself from client tampering, it can be signed, and if you're afraid of clients looking at it, you can encrypt it.
Edit: Although I'm not certain, it seems unlikely that Google has a table of all authentication tokens ever issued; The length of their tokens suggests that the token is some encrypted message proving that whoever holds this token actually provided real credentials in some realm at some time.
OAuth does exactly what you want to do in a standard way.
You could use a combination of HTTPS and HTTP Basic Auth. Both are existing standards and should be secure enough when used together.