For projects that will take place in the future, it is important that my own REST server will be created. Now, I have been working on this for a few weeks, and everything concerning the REST server is ready. I can give requests and receive responses. I am just missing the security through OAuth2.
After some research, I found the authorization server from carlosHE. Now, I have everything installed in Delphi, but I do not understand how I can get the authorization workable for my REST server.
Are there people who have experience with applying the OAuth2 protocol to REST servers using carlosHE/oauth2-server? Or, maybe there are other ways that work?
Draft answer:
The client must get an access token from the OAuth2 server. (how to authenticate the client is a different question)
The access token must be stored server-side, so that the REST server can validate client REST requests.
The client then can send REST requests which contain the access token. (typically sent as a HTTP header value)
Related
I am learning about CSRF Tokens and how they help secure your web application. I understand the basics of it, but I am confused as to how it works in practice when the web server and api are separate. In practice how is the token generated, added to the HTML and known by the API?
For example, if I host my web app on something like Nginx or S3 and serve APIs via Spring Boot, how does the HTML with the embedded token get generated and passed to the client? Would the Sprint Boot API need to generate the token and HTML and return that to the client? Is there a different flow that am I missing? If this is the case, what is the point of it being embedded in HTML at all?
All of the documentation I have read assumes you are using something like MVC or skips over this entirely.
CSRF protection is only necessary for requests made by a client (for example, a browser) that silently adds credentials for the current user, by sending a session cookie, resending username and password that were previously typed in ("Basic Authentication") or by including a client certificate. This is because users may be tricked into making unwanted such requests by visiting a malicious web page, and these unwanted requests are then made with their credentials, that is, on their behalf.
For requests made by your web server to an API endpoint, this does not apply, therefore the API endpoint need not offer CSRF protection. A web server cannot be tricked into making unwanted requests.
Or can it? Imagine that the web server offers a "proxy" endpoint that converts incoming requests into requests to the API endpoint, and that sends the API response back to the client:
Client --request--> web server --converted request--> API endpoint
Client <--converted response-- web server <--response-- API endpoint
Further imagine that, as part of the request conversion, credentials from the client are forwarded to the API. For example, a session cookie coming from the browser is converted into an Authorization: Bearer <jwt> header that is sent to the API endpoint. Then an unwanted request to the web server endpoint with credentials effectively becomes a request to the API, and a new CSRF vulnerability has appeared: this time on the web server.
The web server must then protect its own "proxy" endpoint against CSRF by issuing and validating a CSRF token.
I am in the process of setting up a central JWT authentication / authorization service. We will have multiple APIs that a client will need to communicate to and be authenticated against.
My thought was to have the user login, which would authenticate against the JWT server. It then uses that token to communicate with the other resource APIs. Those APIs would validate the token against the JWT server before sending the request back.
Is this a pretty decent approach to the problem? Has anyone implemented something like this? One issue I see right away is there is a lot of communication to the JWT server.
This sounds like a decent approach. I have implemented a solution where the JWT service was a part of my API. As i understand from your question, you want to have this JWT service separately so that a user can interact with different services/application using the same token. This is called Single Sign On.
If you think your JWT service is getting a lot of traffic, you can always spin up more instances to handle the additional load.
As long as your service is just getting token from a database and responding to request quickly and not doing any calculations, i do not see it getting affected by a lot of traffic.
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.
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...
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.