Advantages of sending API authentication_token via headers vs. parameters - ruby-on-rails

This tutorial for building API's with Devise recommends using headers to send over the login email and API token vs. embeding them as URL parameters.
Rather than sending the data over parameters, we're expecting the client application to send it via two headers: "X-API-EMAIL" and "X-API-TOKEN"; this cleans up the endpoint URIs.
Can someone elaborate on what it means to "clean up" theWhat are the the advantages of requiring authentication via headers vs. having the client embed them as parameters in the URL?

I think by "clean up" they just mean that the URLs are tidier and only contain information about the resource being requested/updated/...
It's common to use this approach -- it can be argued that it's conceptually nicer to keep what you are requesting somewhat separate from the details of your credentials for making the request. The "Authorization" HTTP header is a standard one to use for credentials (e.g. HTTP Basic Auth http://en.wikipedia.org/wiki/Basic_access_authentication#Client_side, AWS API http://docs.aws.amazon.com/AmazonS3/latest/dev/RESTAuthentication.html#ConstructingTheAuthenticationHeader and many more).
It also removes the possibility of clashes between your credential parameters and other parameters. For a trivial example, imagine you use password for your credential password and also want a normal parameter called password for a particular API call (when you're updating another user perhaps). You can't have that - one of them has to be named differently. Ok, you can easily do that, but it's a little artificial, and if you instead supply the password for the credentials in the Authorization header, you are free to have a parameter called password which relates to the actual request you are making (e.g. the new password you're setting for some other user).

Related

OpenID Connect, oAuth2 - Where to start?

I am not sure which approach I should be taking in our implementation and need some guidance.
I have a REST API (api.mysite.com) built in the Yii2 Framework (PHP) that accesses data from mysite.com (database). On mysite.com our users will be able to create Connected Apps that will provision a client id + secret - granting access to their account (full scope?).
Based on my research, the next step seems to be setting up something to actually provide the bearer tokens to be passed to the api - I have been leaning towards oAuth2, but then I read that oAuth2 does not provide authentication. Based on this I think I need OpenID Connect in order to also provide user tokens because my API needs to restrict data based on the user context.
In this approach, it is my understanding that I need to have an Authentication Server - so a few questions:
Is there software I can install to act as an OpenID Connect/oAuth2 authentication server?
Are there specific Amazon Web Services that will act as an OpenID Connect/oAuth2 Authentication Server?
I am assuming the flow will be: App makes a request to the auth server with client id + secret and receives an access token. Access token can be used to make API calls. Where are these tokens stored (I am assuming a database specific to the service/software I am using?)
When making API calls would I pass a bearer token AND a user token?
Any insight is greatly appreciated.
your understanding is not very far from reality.
Imagine you have two servers one for Authentication, this one is responsible for generating the tokens based on a Authorization Basic and base64 encoded CLientID / ClientSecret combo. This is application authentication basically. If you want to add user data as well, simply pass username / password in the post body, authenticate on the server side and then add some more data to the tokens, like the usernames, claims, roles, etc
You can control what you put in these tokens, if you use something like JWT ( Json Web Tokens ) then they are simply json bits of data.
then you have a Resource server, you hit it with a Authorization Bearer and the token you obtained from the Authorization one.
Initially the tokens are not stored anywhere, they are issued for a period of time you control. You can however do something else and store them in a db if you really want to. The expiration is much safer though, even if someone gets their hands on them they won't be available for long! In my case I used 30 minutes for token validity.
Now, you haven't specified what languages/frameworks you are looking into. If you use something like dot net then look into IdentityServer, version 4 is for Dot net core, 3 for anything below.
I also have a pretty long article on this subject if you are interested:
https://eidand.com/2015/03/28/authorization-system-with-owin-web-api-json-web-tokens/
Hopefully all this clarifies some of the questions you have.
-- Added to answer a question in comments.
The tokens contain all the information they need to be authenticated by the resource server correctly, you don't need to store them in a database for that. As I already said, you can store them but in my mind this makes them less secure. Don't forget you control what goes into a token so you can add usernames if that's what you need.
Imagine this scenario, you want to authenticate the application and the user in the same call to the Authorization Server. Do the OAuth2 in the standard way, which means authenticate the application first based on the client id / client secret. If that passes then next do the user authentication. Add the username or userid to the token you generate and any other bits of information you need. What this means that the resource server can safely assume that the username passed to it in the token has already been validated by the authentication server otherwise no token would have been generated in the the first place.
I prefer to keep these two separate myself, meaning let the AS ( Authorization Server) to deal with the application level security. Then on the RS (Resource Server) side you have an endpoint point like ValidateUser for example, which takes care of the user validation, after which you can do whatever you need. Pick whichever feels more appropriate for your project I'd say.
One final point, ALWAYS make sure all your api calls ( both AS and RS are just apis really ) are made over HTTPS and never ever have any important information transmitted via a GET call which means the URL can be intercepted. Both Headers and POST body are encrypted and secure over HTTPS.
This should address both your questions, I believe.

Customizing the TokenEndpoint in spring security OAuth2

I would like to customize how the TokenEndpoint works so that I can add additional parameters to to incoming /oauth/token rest call that I will capture and process.
Ok, to perhaps help explain what I want to do, here are some additional aspects to it.
Lets say, in the oauth/token request I want to add another request parameter entry. So instead of sending the oauth/token with grant_type=client_credentials (for example), I want to add grant_type=client_credentials&extraInfo=xxxx.
So my my token endpoint that I have running at request mapping /oauth/token instead of the builtin one (TokenEndpoint), I do everything that the original does PLUS, I parse the extraInfo=xxx and set it as a key/value in the additional info section of the token.
Later in my backend, I extract this extra info and use it to provide some functionality that I need. Various clients will use this extraInfo parameter to send some specific type of information that I was to be aware of.
So basically, ow do I substitute my own token endpoint in place of the regular one? Is this in token services and if so which specific part?
I figured out an alternative to what i want to do without any of the messiness of trying to create and hook in my custom Token Endpoint.
I put an aspect around (#Around ...) the TokenEndpoint and captured the incoming parameters and resultant token, etc. I then used the spring session framework to put in a structure that I can access (created from what came in) and now I can get at it in my resultant code.
This does what I want without needing to do something more complex.

Is this method of opening an endpoint secure? (rails)

I'm thinking through how to open an endpoint to my customer so he/she can trigger changes in their model from an external website (aka an API i think?)
I plan on creating an action in my controller where I skip authentication and authenticity token check. I would create a long random string to give to my customer so when they submit a POST request, they would include the random string in the params to confirm identity.
Is this a secure way of doing what I'm trying to do? Is there another/better way of doing this?
I just want my customer to be able to pass me values and my app take actions based on these values.
what you are talking about is usually called client token authentication.
i use it for my app as well: https://github.com/phoet/on_ruby/blob/master/app/controllers/api_controller.rb#L23-L29
my implementation uses a header-field to exchange the token.
if you want to have a more sophisticated variant you should look at oauth.
in terms of security, you might take additional measures by whitelisting ip ranges etc.
of course, use SSL connections only!

How should I secure my SPA and Web.API?

I have to implement a web site (MVC4/Single Page Application + knockout + Web.API) and I've been reading tons of articles and forums but I still can't figure out about some points in security/authentication and the way to go forward when securing the login page and the Web.API.
The site will run totally under SSL. Once the user logs on the first time, he/she will get an email with a link to confirm the register process. Password and a “salt” value will be stored encrypted in database, with no possibility to get password decrypted back. The API will be used just for this application.
I have some questions that I need to answer before to go any further:
Which method will be the best for my application in terms of security: Basic/ SimpleMembership? Any other possibilities?
The object Principal/IPrincipal is to be used just with Basic Authentication?
As far as I know, if I use SimpleMembership, because of the use of cookies, is this not breaking the RESTful paradigm? So if I build a REST Web.API, shouldn't I avoid to use SimpleMembership?
I was checking ThinkTecture.IdentityModel, with tokens. Is this a type of authentication like Basic, or Forms, or Auth, or it's something that can be added to the other authentication types?
Thank you.
Most likely this question will be closed as too localized. Even then, I will put in a few pointers. This is not an answer, but the comments section would be too small for this.
What method and how you authenticate is totally up to your subsystem. There is no one way that will work the best for everyone. A SPA is no different that any other application. You still will be giving access to certain resources based on authentication. That could be APIs, with a custom Authorization attribute, could be a header value, token based, who knows! Whatever you think is best.
I suggest you read more on this to understand how this works.
Use of cookies in no way states that it breaks REST. You will find ton of articles on this specific item itself. Cookies will be passed with your request, just the way you pass any specific information that the server needs in order for it to give you data. If sending cookies breaks REST, then sending parameters to your API should break REST too!
Now, a very common approach (and by no means the ONE AND ALL approach), is the use of a token based system for SPA. The reason though many, the easiest to explain would be that, your services (Web API or whatever) could be hosted separately and your client is working as CORS client. In which case, you authenticate in whatever form you choose, create a secure token and send it back to the client and every resource that needs an authenticated user, is checked against the token. The token will be sent as part of your header with every request. No token would result in a simple 401 (Unauthorized) or a invalid token could result in a 403 (Forbidden).
No one says an SPA needs to be all static HTML, with data binding, it could as well be your MVC site returning partials being loaded (something I have done in the past). As far as working with just HTML and JS (Durandal specifically), there are ways to secure even the client app. Ultimately, lock down the data from the server and route the client to the login screen the moment you receive a 401/403.
If your concern is more in the terms of XSS or request forging, there are ways to prevent that even with just HTML and JS (though not as easy as dropping anti-forgery token with MVC).
My two cents.
If you do "direct" authentication - meaning you can validate the passwords directly - you can use Basic Authentication.
I wrote about it here:
http://leastprivilege.com/2013/04/22/web-api-security-basic-authentication-with-thinktecture-identitymodel-authenticationhandler/
In addition you can consider using session tokens to get rid of the password on the client:
http://leastprivilege.com/2012/06/19/session-token-support-for-asp-net-web-api/

ASP.NET MVC 3 Web API - Securing with token

I'm trying to find the simplest way of implementing token based authentication for a number of ASP.NET MVC actions.
The Api controllers sit alongside a web app, so I need to be able to specify which actions/controllers are subject to Api authentication.
I already have a membership provider that is used for forms authentication so I'd like to reuse this to validate the user and build the returned token.
I've read several articles on implementing OAuth, but most seem really complex. I've seen several examples of using an API key, but I want to request a token and then pass it back as a parameter not necessarily as a value in the HTTP header.
Essentially process needs to be:
User requests token from auth action passing in username and
password.
Service returns enc token
User passes enc token to future calls as a parameter to auth
What's the typical way this is done, does the client (say ajax call) need to compute a hash of the user name/pass in 1)? or plain text ok over TLS/SSL?
Any advice appreciated.
What are you concerned about with what you described?
The process you described seems viable. Typically systems will have an expiration on how long the token will be valid for, after which they need to get a new token. There are many variations for expiration though (fixed time, sliding time, etc..).
To your question regarding the username / password, the client shouldn't hash them. Just make sure they are transmitted via a secure method (SSL).

Resources