Should I pass Credentials via HTTP Header or Post body as JSON to REST Api? - rest

I am trying to create a Rest Api using a token based Authentication.
Is there any best practice in passing credentials from client to server for generating the token. As a HTTP Header or as a JSON String in post body?
I have been searching around but was not able to find any concrete answers.

Don't try to reinvent the wheel. For a good starting point look here:
best-practices-for-securing-a-rest-api-web-service
For my API implementation and my needs, I choose a simple BasicAuth (send credentials with the header) and any other tokens, and security related data I added to the JSON payload with each request.
Dont forget to set SSL as mandatory.

I would recommend using the Open ID Connect authentication protocol, and more specifically using a third party service or solid library that implements this protocol. Open ID Connect builds on OAuth 2 and is now widely used with support for various development languages and frameworks: http://openid.net/developers/libraries/
A successful authentication step results in an "access token" that can then be passed to your REST API where it is validated for authenticity. In Open ID Connect this token is passed as an HTTP header vs. the POST body.
If you roll your own protocol, or even develop your own Open ID Connect implementation, be aware of the details as it is very easy to overlook something small and thus create an insecure API. See the OAuth 2.0 Threat Model and Security Considerations for examples of what I am referring to. Due to this concern I always recommend use of an existing, well-vetted implementation.

Related

REST API Design: Should I use a custom header or Authorization for some sensible information?

this is my first question on StackOverflow. 😀
I'm currently creating a Discord Bot with a Dashboard and a private API for my service.
The flow I'm trying to create is the following
User logs in with Discord OAuth2 and gets his access_token
-> Client stores his access_token
-> When doing an action on the Dashboard and commit it, make an API call and pass his access_token
-> My API then check if he has the permission to commit it
(by doing a request to Discord's API with his access_token)
-> Realise the action if allowed
Because the user needs to send his access_token, I need to know how I'm supposed to recieve and use it safely, and following the best practices.
Those are the two way I found :
Use a custom HTTP Header like Discord-Access-Token: <access_token> and then process-it easly
to use Authorization: Baerer <access_token> (even tho this is not
an Authorization but something I need to check if the user is allowed
to use the API). + This is not really following the flow in FastAPI...
Does someone knows what is the best thing to use? Thanks in advance!
even tho this is not an Authorization but something I need to check if
the user is allowed to use the API
So Authorization in simple terms...
Think of your service as something that covers everything you do even doing stuff with tokens on Discord.
I would use the Authorization header, because it is standard, unless you have another token, because you cannot send multiple ones in a single request except if you package them together. If you have a different header, then the request can be modified or cached by proxies. https://stackoverflow.com/a/43164958/607033
As far as I understand Basic and Bearer are not the only types of Authorization, you can have a custom type too. If Bearer does not cover the term you need, then write something like DiscordOAuth2.
The Authorization header name is a misnomer, in the same category as the misspelling as 'Referrer'. The purpose of the Authorization header is actually authentication.
Also not that it's Bearer not Baerer.

What value do I put for SAMLRequest? WSO2 IS Skipping Login.do

My sectoken is authorized but I don't know how to formulate a URL so that I can bypass the WSO2 IS sign-in page (login.do).
I read online it can be passed through a link in this format:
localhost:9443/samlsso?SAMLRequest=[SAMLRequest]&sectoken=[SECTOKEN]
I'm just not sure what to put in for [SAMLRequest].
As for the answer, you may try to use OneLogin PHP module to generate a SAML Request.
Here is an example SAML Authn Request however you may need to change the issuer, destination, AssertionConsumerURL, and issue timestamp.
Please note there's difference when sending SAML Request as GET and POST. GET (Redirect-Binding) uses deflate and encode, signature is a separate request parameter, POST (POST-Binding) uses signed XML and only encoded XML, not deflated.
SAML is great protocol (very well designed and secure when implemented properly), but it may look difficult for people who hasn't use it before, it may require using external libraries to properly create requests and validate responses. That's why you may be as well looking for option which would may make your life simpler, such as using WSO2IS for SSO (single-sign-on) e.g. using simpleSAMLphp or direct OAuth authorization request.

How to send a password in a GET request to access a REST resource

I have a REST service that is already secured with basic authentication using the Authorization header. This is used to access the service in general and is required for any request. i.e. "User1", "password1".
I have a "file" resource which can have an additional password associated with it (i.e a password protected Word document, PDF, etc), "docpassword". What is the best way to send sensitive information like this? I'm especially interested in how to send the password for a GET request, but I'd like to have a universal solution that will also work for POST requests.
Maybe a custom header?
The HTTP protocol defines the standard Authorization header for sending authentication data (credentials) to the server. This header is defined in the RFC 7235 (which makes the old RFC 2616 obsolete and updates the RFC 2617):
4.2. Authorization
The Authorization header field allows a user agent to authenticate
itself with an origin server -- usually, but not necessarily, after
receiving a 401 (Unauthorized) response. Its value consists of
credentials containing the authentication information of the user
agent for the realm of the resource being requested.
Authorization = credentials
[...]
Please note that the name of this HTTP header is unfortunate because it carries authentication data instead of authorization. Anyways, this is the standard headers for sending credentials in the HTTP protocol.
Once you are already using the HTTP Basic Authentication Scheme to authenticate the users in your application, I believe you are already using the standard Authorization header.
I usually do not recommend custom headers, especially when the standard headers can be used instead, but your scenario seems not so common: You need to perform two authentications on the same request.
So, maybe a custom header such as X-Auth-Document or Document-Authentication with the document's password will be fine for GET requests. If you decide not using GET and decide using POST to access this resource, you can consider sending the document's password in the request paylod.
Anyways, don't forget using HTTPS: is highly advisable once you are sending sensitive data, such as credentials, over the wire. And HTTPS will protect you against the man-in-the-middle attack.
HTTP already has an authentication method, see for example this RFC: https://www.rfc-editor.org/rfc/rfc2617
Edit after clarification of question: There is nothing preventing the server to make additional challenges, even based on single resource basis. I must admit I did not implement such a thing yet, but each authorization can have its own realm. You could specify different realms, even down to document level if you really want to. The server then can potentially make multiple challenges in each realm (first login, then document). Remember, you can cache successful authentications, either on the client (for a realm, like a browser does), or giving out cookies with a cached token.
This would have the advantage of avoiding a custom header, and be completely HTTP/REST conform. There may be some performance disadvantage, but it could be mitigated with some targeted caching.
Of course you can go with custom header if you want to, but normally REST would imply that the client goes in with no prior knowledge other than mime-types and the HTTP protocol. A custom header implies out-of-band prior knowledge.

How to secure RESTful Web Services (PROVIDER)

I need secure Restfull services in the provider. I want that the user must have the authorization for use the REST service and I can generate use stadistic or simply dont allow call the REST services if isn´t a register developer.
I have been thinking about that the user send the email and password in the URL (http://autor.derf.com/api/search/email?=dsdfd#gmail.com&passwd=dasffsdf;) but isnt very safe.
Also I have read about oauth 2.0 but the documentation is very very bad for Java.
Are there any other way to have an RESTful api with authorization?
I want a Restfull API access by Iphone, Android, Windows Phone and web
Thanks in advance ;)
If you plan to write all the clients for the service yourself (iPhone, android etc) then sending email and password is a decent alternative, as long as the provider communicates over a secure transport layer (e.g SSL/HTTPS).
You can always add support for OAuth 1 or 2 later if you feel that you want to make your APIs public. (The whole idea with OAUth is to protect user's passwords, and also to get a more fine grained control over which APIs a client can use, and for how long).
But, in your case I would at least consider using basic authentication, in which a typical HTTP request looks somewhat like this:
GET /path/to/api HTTP/1.1
Host: www.example.com
Authorization: Basic aHR0cHdhdGNoOmY=
The hash after "Basic" is simply base64 encoded "username:password", or in your case "email:password". If anyone intercepts it, it is easy to simply un-encode to get the plain text user credentials. So HTTPS is a must.
» More information on basic authentication at wikipedia.

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.