I have two instances of spring boot services running. let's say 'app1:8080' and another instance 'app2:7070'. Where as 'app1:8080' is hosting a html page , which tries to connect a web-socket connection with 'app2:7070', whenever it get launched.
Something like this :
var webSocket = new WebSocket("ws://app2:7070/socket-endpoint");
But i am always getting 403 error message. I have read about the cross-domain and have tried to register the 'app1:8080' in 'app2:7070'.
But couldn't find any solution.
Server technology : spring boot
client technology : HTML5
Most probably this results from cross origin calls. You have different options to solve this:
put a load balancer like nginx in front of both applications and serve them with the same base URL
serve the html from the same application (the easiest solution if its a small application)
or allow cross origin calls in app2 from app1 in your case, like documented here
Related
I want to put SCDF's dashboard behind zuul (or just assume any proxy, really), but when I do that, Spring Cloud Data Flow will redirect to what it thinks it's actual host is.
Example:
Zuul is http://zuul/. It's configured to route any /dashboard requests to http://scdf/host
In a browser, I go to http://zuul/dashboard.
As soon as the request routes through zuul, and then hits SCDF, SCDF will redirect to http://scdfhost/dashboard, which won't work in a locked down environment. (scdfhost will not be visible through the outside)
I've looked for any properties that would work here, but I can't figure it out.
Anyone tried this? Or tips?
Thanks for your question! The issue is the redirect 302 from http://localhost:9393/dashboard to the absolute URI of the dashboard (http://localhost:9393/dashboard/index.html). If you are running Spring Cloud Data Flow Server behind a proxy server, such as Zuul, you will have to specify the property
server.use-forward-headers and set it to true. That way Spring Boot is aware of the HTTP forward headers from the proxy. See also the Spring Boot reference guide ("Running Behind a Front-end Proxy Server").
You can find a basic example at:
https://github.com/spring-cloud/spring-cloud-dataflow-samples/tree/master/dataflow-zuul
In order to clarify the reference documentation, I have created a follow-up issue:
https://github.com/spring-cloud/spring-cloud-dataflow/issues/2929
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 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'm trying to make this example work
But when I deploy the war file to Tomcat and start it, the connection cannot be established.
In browser console I see that the client tries to connect to http://localhost:8080/Spring4WebSocket/add/info and receives 404, though the specified in start.jsp URL for connecting is /Spring4WebSocket/add (without that "/info" part in the end).
Why is this strange "/info" suffix added to the url and what can I do to change this and make this example work fine?
This solution wasn't helpful for me:
SockJs - 'info' path not found
The /info URL is called by SockJS (see docs):
...before the client starts the session. It's used to check server capabilities (websocket support, cookies requirement) and to get the value of "origin" setting (currently not used).
I looked at the example you are following and I don't see anything wrong with it. It follows closely a Spring guide: Using WebSocket to build an interactive web application so it should work.
Just one question though. Did you exactly follow the instructions or downloaded the zip file from the page or did you create it on your own? You get that error on the first SockJS request here:
var socket = new SockJS('/Spring4WebSocket/add');
Is your application also called Spring4WebSocket or something else? If it's called something else then use that instead:
var socket = new SockJS('/YourAppNameGoesHere/add');
I have two different spring web applications with authentication,
My first application has to get some responses from second application in order to show the required details to the user. Now the problem is, Since the second app also secured I'm unable to get responses from it. Suggest me how can I authenticate second app from server code at first app.
Note: I tried to use CAS server, It returned me the login page's html text when I made a request.
Refer to this https://stackoverflow.com/a/24486898/3487801. Services could be secured using CAS. All you need to do is to add restlet module on your cas server and build a simple Java client to get the ticket and authenticate to your service.
Some says, there is no working Java client for headless CAS. But groovy example on the CAS restful API https://wiki.jasig.org/display/casum/restful+api is actually working. You need to get it modified just a little bit to get it work.