I am searching for the best approach of authenticating users of mobile clients when accessing my RESTful API. For example, how approximately AirBnb uses it's auth module.
Should the authentication be different for RESTful and basic session-based resource, working with the same data?
I am not a mobile developer therefore, I am interested in what is the best way to provide authentication from server-side, so the mobile-platform developers could use it simply.
I googled for few approaches using OAuth, OAuth2, HTTPBasic authentication and still wonder how the mobile developers can use such API, how they will store this token (cookie is stored by browser in browser-oriented apps).
Could you please suggest me some links/code samples/techiques that you used in production or pet-projects or something?
An easy and manageable alternative to OAuth(2) for authentication is JWT.
You don't need additional infrastructure, the workflow and use is straightforward and there are ready to use libraries for all major languages already available.
Compared to HTTP Basic Authentication JWT is more flexible by transmitting additional information not just credentials, you can store the JWT token as JSON or you can use cookies, you don't need to store the credentials on client side and you don't transmit the credentials on every request.
Also based on JWT you can realize very easy a single sign on function. So if you need more than just a simple system user then you should definitely try JWT.
Related
What I'm trying to do is to create an application with Angular frontend and Spring Boot backend with OAuth2 authentication.
The issue is that I don't know how to get on the frontend the ROLES user has so that I'll be able, for instance, to show something role-based on the page. Yes, there are scopes that OAuth provides in the response but the problem is that these scopes are for the CLIENT but not for the specific USER itself. And that CLIENT is my frontend side (correct me if I'm wrong) which basically means that every user operating my application(client) going to have the same scopes(roles). Moreover, I can specify roles on the backend with the help of Spring and UserDetailsService and then use those roles with #PreAuthorize, etc. But not on the frontend side.
Just as an example, if I simply used single JWT then with a token itself I'd return both the username and roles to frontend. And then I could store that data and use it on the frontend side according to my needs.
So what I'm asking is if it's actually possible and if this is correct to do so?
And how can I possibly implement such behavior?
OAuth doesn't solve this problem and it is best solved via claims in your API. OAuth should deal with authentication only. My below post may help you to think about the best separation: https://authguidance.com/2017/10/03/api-tokens-claims/
In a nutshell you will have to look up user rights such as roles after the OAuth processing completes.
There is a great video from Spring developer on YouTube about OAuth2/OpenID Connect. It shows how to implement the resource server using the newest Spring Security 5 solution.
Probably the easiest and the best way to achieve this is to use an OpenID Connect server which will provide all user management stuff. On the market there are many solutions. Auth0 and Okta are Identity Clouds which provides their services for small amount of money. On the other hand you have Keycloak, which is a server which you can install in Docker or even on bare metal - it's free and open-source.
I have a Java Spring driven REST API server connecting with PostgreSQL database and a Spring Web Server in Java that is serving content from the REST API to the client using JavaScript (now browsers, but in the future also mobile apps).
I've read a number of articles and topics how one can secure a REST API, but I haven't been able to make a final decision yet. I don't want to have Basic Authorization, because it doesn't make sense as I would need to store credentials in JavaScript that can be easily accessed and read by anyone entering the webpage and developer console. I'd like not to show any credentials to the end user so I can't keep them on the client's side.
I've read a lot about JWT and almost decided to implement it, but I've heard it has some drawbacks and haven't been so sure since then if it's the option I would like to choose. I know there is also oAuth 1.0 or oAuth 2.0 but I don't know if I want to have something this complicated. I would also like to store hashed user credentials in my own database in order not to be depended to any other credential providers like social media or Google.
Now I'm making another layer on my web server as a proxy hoping that it will allow me to authenticate user on this proxy level using Spring Security and having some kind or cookies or something to authenticate, but I'm not so sure if its doable this way and it increases the respond time, adds complexity and needs me to write controller methods for these endpoints. My architecture now is of the following:
Client (browser) -> Webserver -> REST API server -> db
I've also denied all external connections and allowed only localhost access to REST API on tomcat level so that I'd have to implement the security level only on the web server allowing free information transit between the webserver and REST API as it is not reachable anyway.
Web server and REST API are on the same server running as Tomcat instances.
I'm also not so sure if this kind of architecture will allow me to authenticate mobile app clients through the web server.
I would be very grateful for any piece of advice you would have for me in this matter. I'm not so experienced in security, so I'm a bit lost what I should do. Does this kind of architecture any sense or should I simply ask REST API directly from any type of clients, be it a webpage or a mobile app from different IPs and secure Rest API only? And if I want to secure some subpages of my webpage or parts of mobile app should that be an completely other layer?
Thank you for your help.
You have already gone through OAuth, JWT tokens etc. If you don't want to use them,then you can create your own token based authentication system.(say 'TokenHandler').
How this TokenHandler will work ?
TokenHandler will be like a gateway server i.e your every REST API request will route through this server application. So you will address your confusion of mobile and web application call with a authToken in header. Main responsibility of this server applciation is to accept the token and validate against the database where all token details are maintain. This DB will have information regarding timestamp when token was last used to validate, to decide your validation rule .
How Token will get generated ?
Token can be any random 64 digit alphanumeric string and will be generated and updated in DB during every single login activity. Login webservice returns this token in response body.
What can be rules for validation ?
It can be depending on your business logic. I preferred to keep active session window of 15 mins. Means if you access the webservice you will get active window of 15 more minutes. If you didn't access any service for 15 consecutive minutes then from 16th Minute you will need to login again to access further calls. This part can change according to requirements.
How client side will handle this ?
Client side will store this token and pass this token with every request call. Token Handler will validate and redirects it's request to the application server . So your one token handler can be used to server authentication of multiple applcation servers. This you can achieve by application end point identifer.
I will like to discuss further if you have any questions or suggestions .
Use API Gateway Architecture Pattern for your use case -
http://microservices.io/patterns/apigateway.html .
The API Gateway (The webserver in your question) can act as single entry point for all desktop/mobile clients. You can use either session cookies or jwts to authenticate clients at gateway.
With respect to authentication between gateway and micro services, and between micro services, i would suggest mutual ssl - https://www.codeproject.com/Articles/326574/An-Introduction-to-Mutual-SSL-Authentication. If you are using spring boot, this might help - http://www.opencodez.com/java/implement-2-way-authentication-using-ssl.htm
The problem with IP white-listing approach is that - it's not well suitable for cloud architecture as the IPs might change with every server reboot. Even if you are using dedicated IPs, you should be careful to secure the communication with SSL/TLS, else attackers can easily sniff your traffic.
I am developing a REST API using Java Spring Boot framework. Purpose of this API is to connect mobile and web applications so they can work together.
My question is, what are the best practices to develop login functions or the login process. Shall I generate a token or what should I do?
You could follow the best practices as described in OWASP, here.
Most APIs nowadays use token based security. Here are a few guidelines:
You need one service (which is itself public) that authenticates the user.
In order to authenticate the user, it might use a username and a password, and/or other means.
As the result of authenticating the user, this service returns an authorization token.
Your backend should keep track of issued tokens.
Each token will have an expiration time.
Every time the client uses an API, it should send along the token. Usually, the token is sent as an HTTP header.
Every service in the API should validate the token before anything else. If the token is invalid, it should return an appropiate HTTP code.
All communications should be sent over SSL.
OAuth and OAuth2 are two very well known protocols for this very goal. OAuth is a little more complicated than OAuth2.
This is a very high level description, not technically deep, but it should get you started.
I am new to OAuth2 concept.I ahve to implement this in my application. This application provides REST APIs. I follwed some tutorial ,done some research and kind of implemented it in working state in my application.
But while doing some search I read about different type of grant_type in OAuth2. I tried to learn about that but didn't get actual differences and which should I use for securing REST APIs.
So I want to know that for grant_type types "password","client_credential"etc which should be used and in which scenario, or which should be used for securing REST APIs?
Also at some places I found that the request for /oauth/token is different.
Some places the Authorization header is given as Basic 'some_encoded_string' .
And at some place it is Bearer 'some_encoded_string'. Whats the difference in these request?
Summarizing this I have 2 question -
For grant_type types "password","client_credential"etc which should be used and in which scenario, or which should be used for securing REST APIs?
What is the difference in ways of requesting token from /oauth/token .
Enlight my knowledge in implementing spring-security-oauth2.
The grant you need to use depends on your use case and the nature of the client application accessing your resources. There isn't a grant that applies a REST APIresource in general. You'd need to provide more information on what the APIs are and how you interact with them.
If a user has to give their permissions for a client to access an API, then you would normally use an "authorization code" grant. If the client accesses the resource directly without the intervention of an end user then it would normally use the "client credentials" grant.
You should avoid using the password grant in most cases, since it means the user has to provide their username and password to the client application. If the application can use another grant, such as authorization code, then that is preferable. A trusted application, such as a native application which the user installs on their computer, would be one situation where the password grant might be used.
A client would normally use "Basic" authentication to access the token endpoint. "Bearer" authentication is use to access a protected resource (such as your API), passing the access token it obtained from the authorization server.
Why do you think you need to use OAuth2 at all? I'm curious since you say you don't understand what the grant types are for. You really need to understand this before you can make a judgement about how you would use OAuth2 or why.
I am currently in the early stages of creating a web application (HTML5, JS, etc.) that uses a REST API on the backend (Java, specifically Jersey v1.18). The nature of the data that will be stored is highly sensitive, so security is something that I’ve started looking at, even though the application is only in the early stages. The eventual goal will be to have native mobile applications as well, and to potentially provide access to the data for external clients via the same API.
In my research thus far, I have identified a variety of authentication methods, including HTTP Basic, token-based, session cookie, OAuth, HMAC, etc. The key component here is that the REST API will be primarily accessed by users, rather than other applications or backends. Thus, having a “login/logout” equivalent is important, and this boils down to user level authentication.
So far, HMAC authentication looks to be the most promising, as we have no plans to integrate with any OAuth provider at this moment.
I have already read through dozens of SO posts, as well as articles such as:
http://www.thebuzzmedia.com/designing-a-secure-rest-api-without-oauth-authentication/
http://www.errant.me.uk/blog/2013/04/authenticating-restful-web-applications/ (note: this is clearly bad, as salting with the username is not recommended)
Ideally, HMAC seems like the way to go, but I have yet to see a recommended approach to handling the shared secret. The idea of using a resource to validate credentials, which then provides a token/nonce to be used with the HMAC scheme, seems to be an option, but I’m questioning the advantages over just using this token/nonce strictly as a token.
I know that HMAC authentication for a REST API has been discussed at length, but when used in conjunction with the authentication details that users have come to expect (username, email, password, etc.), is there any recommended approach that doesn’t require a pre-shared secret key?
This is primarily an opinion-based question, but I'll offer my two cents: just go for a session cookie.
If your primary audience is humans, and you don't need to integrate with third parties, don't bother with OAuth. Just make sure your API is only available over HTTPS, and issue a session token that the server can revoke after login. Strictly speaking it doesn't need to be a cookie; I've seen APIs that stash the token in HTML5 session storage and provide it in the Authorization header or as a query param.
If you have SSL set up properly, your users will get the expected padlock in the browser, and you'll be safe from anyone in between you and the client. If the client is compromised, you're screwed anyways. And since the client can't keep a secret, there aren't a lot of advantages to more complex HMAC schemes.