we are trying to develop a web application where controllers(Servlets) should act as restfully services , initially browser will act as client and then in future there could be third party applications which will be consuming services from the same controllers.
All controllers will return JSON data and angular JS will use this and display content in browser for the web application and for the third party application they will directly invoke rest services.
My question are as follows
If i am developing Restful service then should I not use HTTP-session
i.e should my controllers be completely stateless
If my application should be stateless then how will I overcome the
shortage of HTTP-session object ( how do i carry the user specific
data which could be required in different screen)
How will the authentication be handled for the third party
application , should user provide credentials in each request ?
1) Yes, you need a kind of token based authentication, in other words you have to set header with each request. Angular ngResource is your friend. Example:
i. Login (Basic Authentication)
ii. Get Token from Server and store it e.g. in Cookies
iii. Set header with each request (token: whatever)
iv. If token is valid, server answers with data or enables further interaction
2) User specific data will be stored in your $scope (Angular Term) ist is like a data and operation container for your model. You can persist it locally if you want to. Or send it to the server (with a valid token to store it there)
3) Login, get Token, communicate. User rights and Co. has to be set correctly on the server.
Related
My apologies for my bad english.
I have the tool Apereo CAS using as login SSO. When i'm using with application statefuls this works very well. But i wanna call a API REST (stateless) for specific scenario and validate the logged user (and using your informations on the service). My backend API is developed with Spring Boot. Someone needed a similar situation?
Ps: This API will acess by frontend and services without frontend therefore I'll not be able to use cookies.
Sequence Diagram to exemplify my idea:
enter image description here
Thank's.
Your front-end application needs to ask the CAS server for proxy authentication.
One of the more common use cases of proxy authentication is the ability to obtain a ticket for a back-end [REST-based] service that is also protected by CAS. The scenario usually is:
User is faced with application A which is protected by CAS.
Application A on the backend needs to contact a service S to produce data.
Service S itself is protected by CAS itself.
Because frontend contacts service in the back-end via a server-to-service method where no browser is involved, the backend would not be able to recognize that an SSO session already exists. In these cases, front-end needs to exercise proxying in order to obtain a proxy ticket for the backend. The proxy ticket is passed to the relevant endpoint of the backend so it can retrieve and validate it via CAS and finally produce a response.
The trace route may look like this:
Browser navigates to front-end.
Front-end redirects to CAS.
CAS authenticates and redirects back to front-end with an ST.
Front-end attempts to validate the ST, and asks for a PGT.
CAS confirms ST validation, and issues a proxy-granting ticket PGT.
Front-end asks CAS to produce a PT for back-end API, supplying the PGT in its request.
CAS produces a PT for backend API.
Front-end contacts the service S endpoint, passing along PT in the request.
backend API attempts to validate the PT via CAS.
CAS validates the PT and produces a successful response.
Backend API receives the response, and produces data for front-end.
A receives and displays the data in the browser.
See this for details.
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.
We are now incorporating Restful Web Services in our System and as a result, both Browser and Mobile Clients are able to access our System available in single form (Clients access same code; No different backend code for different clients) successfully via Restful Web Service (i.e.)
REQUEST:
Technically, Restful Web Service API has been built above our existing system (Specifically built above Controller of MVC). Mobile Clients (be it Android (or) iOS (or) Windows) and Browser Client (Web forms) make uses the Restful API built, for ACCESSING our system and transmitting DATA to our system.
RESPONSE:
So, once we get data inside our system (Controller), it gets processed by moving back and forth from DAO and business layer and finally the processed data lands in Controller for it to be get returned to respective client. So, at this place, currently we determine the type of client from where the request is made (Mobile App or Browser) and
RETURN only processed DATA
IF
Client is 'Mobile App' (or)
RETURN both processed DATA + Name of Web View
ELSE
Client is 'Browser'
Note1: We are returning javax.ws.rs.core.Response object in both the cases.
Note2: processed DATA can be PlainText (or) XML (or) JSON (or) String
TO CLARIFY:
Now our question is, whether can we eliminate this IF-ELSE condition for returning the stuff (i.e.) is there a way to have only one RETURN statement returning generic stuff, irrespective of Client to which the stuff is returned? If so, then how does different Clients (in our case, Mobile App and Browser) interpretes the returned stuff and renders view to us?
We have an existing legacy web application(Servlet+jsp+spring+hibernate) and we are going to develop some new features of the application using a new stack (angularjs+Spring mvc). Currently suggested approach is to register a new servlet and develop the new features in the same codebase, so the authenticated users will have access to the new functionality we develop in the system. Is there a better way of doing this as a two different web applications (without SSO) ? Can two web applications be secured under the same form based authentication settings ?
I think architecture and security usability is very important before dive into something.
If both apps use same login, then I assume the newer application is more likely a service oriented application. Ex: RESTful
Authorization may be an issue. Ex: Legacy app is used by user set A, new one is used by both user set A and B.
Otherwise you can use a shared database for example MongoDB to store your login info i.e token.
When you log in, return that token and use for the other service via angular client. When you log out remove any token for that user session. You may also need to concern about token expiration.
However you have to refactor your legacy system in someway to use a token. If it is not possible, you can use session sharing which is handled by the the container if the the both apps are running under same container. Ex: Tomcat. But now it may very hard to integrate with a native mobile app if you are hoping to do so.
Sharing session data between contexts in Tomcat
From the point of Spring security and angularjs, authenticating via form is just an http POST with content type being application/x-www-form-urlencoded. One difference is the response to a non authenticated request, for one response should be a http redirect (jsp, to a login page), one with an unauthorized code (for angularjs). That could be handled with a custom AuthenticationFailureHandler or on the client side. A similar difference may occur for the successful login redirection.
I have created Java Web Application by using Netbeans IDE. I have created entities with relationships. Webpages are simple dashboards where I can add new entities, change them and delete them.
I have added Restful web services to my entities. So web page will be available only for admin and I want to create client application that will have access only for his own data. That means client must login or register to my server.
When user logins/registers on website, server will create session for this user. I know that in RESTful service there is no sessions. My thought is to pass login and password every time when client wants to do some operation with server.
Question: is there any other method to create something like session between client and server? I hope it is not connected with encryption.
There are many options for authentication as well as authorization. If you want to use simple authentication then 'Basic Auth' of HTTP. Check out https://www.rfc-editor.org/rfc/rfc2617 for details. Remember that this is unsafe because the username/password flows on wire. Anyone can sniff username/password. This is updated by new RFC7235 - https://www.rfc-editor.org/rfc/rfc7235#section-4
Safer choice is oAuth. Explained in RFC6749 https://www.rfc-editor.org/rfc/rfc6749. In this case an access token goes with each request.
In both the cases the credential details travel with headers. No interference with parameters.