I am fairly new in microservices architecture. I've been trying to build a microservices stack using Spring Boot, Spring Cloud and Netflix OSS libraries.
I want to know what is the correct way and place to store session.
Here is an overview of the infrastructure that I created:
OAuth2 backed Authorization/Authentication Server
UI Service (Spring Boot, Front end service)
Backend Service-1
Backend Service-2
Redis Server to store session and other cachable data
Discovery Server (eureka)
Currently, I'm trying to store session in Redis by configuring UI service to perform it. It seems to be working fine, although I haven't had the chance to try it for multiple service instances. However, I'm already having serialization/deserialization issues while developing.
By the way, trying to store the session on front end app is the correct place to do or it should be done in Authorization/Authentication service as authentication is processed in that service?
Here is my Session config in UI service (front end service)
#Configuration
#EnableRedisHttpSession
public class SessionConfig extends
AbstractHttpSessionApplicationInitializer {
public SessionConfig() {
super(RedisConfig.class);
}
}
To sum up, I'm expecting to achieve and use best practices on this project. Your kind assistance would be appreciated.
The idea of a general server side user session and a microservices style architecture don't go together well. The reason being that you are likely to break the separation of concern that you use separate the domain boundaries of your services.
Remember, every service is supposed to service a specific domain problem autonomously - including all required data persistence. So for example if there is anything to remember for a users connected devices you would do that in the one service that is responsible for those device connections and nowhere else. The service would be responsible for processing those request and persisting any status that the devices require. Similarly when there is anything to remember about he users authorization you would do that in the authorization service.
And regarding the question to use Redis or not - In a microservices architecture the choice of storage system would be up to the service architect. Maybe one service stores its data in a relational database, maybe another uses a key-value-store and yet another may use an event queue system or a time series database.
So in summary you have to ask yourself what your session really is used for and make the corresponding services responsible to persist that information in a domain specific way. (If you give some more details in your question about this, I can give you my opinion).
Related
I recently have learnt and practicing Microservice using Spring technology. I am currently writing a small program that has Eureka Server, Configuration Server, Gateway and Account service. I have all of my services register its instance to Eureka and have my Gateway gets its configuration from Configuration Server. After that, I got some question, should I my Account Service fetch its configuration directly from Configuration Server, or from Gateway because it can be done in both way. I think, if I decide to fetch it through Gateway, it might be better because Gateway is a load balancer, so in case if there are multiple Configuration Servers out there, I don't need to worry if any of them failed or down as Gateway can handle this for me. But, doing so, isn't I put too much weight on Gateway because it need to handle this and another requests. Furthermore, I am not sure and I can't find any information about if there is a way to load balancing Gateway or is it makes sense to do so?
Please advice and explain. Thank you.
Only user's requests from UI need to be passed via Gateway. Services should be able to fetch their configuration during startup disregarding whether gateway is online or doesn't exist at all.
Also I'd advise you to avoid registering config service in Discovery (Eureka). I suppose there is no need for your users to send requests to config service.
Along with spring cloud config and gateway documentation I'd recommend you to get familiar with these 2 books:
https://www.manning.com/books/enterprise-java-microservices
https://www.manning.com/books/spring-microservices-in-action
I wanna refactor a monolithic spring boot application basically a web app with login and functionalities for customers. We already have a Security implementation which works with a session id stored as a cookie but I dont have much knowledge about it at all and im completetly new to this topic. It seems JWT is a better solution for Microservices because of an independent authentication service.
So my questions are:
is it alot of work to create a JWT authentication service and exchange the session id implemenation? (since im doing it for my bachelor thesis and have a clear deadline)
can I stay at the session ids while using microservices?
are there maybe other ways to implement authentication?
is it alot of work to create a JWT authentication service and exchange
the session id implemenation? (since im doing it for my bachelor
thesis and have a clear deadline)
This question is hard to answer, as it depends how tightly coupled your particular implementation is. It's certainly not trivial.
can I stay at the session ids while using microservices?
Yes, but you need to figure out how to federate sessions across the microservices (i.e. how to get the information in the session from one service to the other). Overall, this represents a risk of tight coupling between services, so I'd recommend treating this as a transitionary step only.
are there maybe other ways to implement authentication?
As many as the day is long. That being said, without specific reason to do otherwise, I generally prefer to stick to the middle of the road.
Typical user sessions is not recommended in microservices.You should use Stateless architecture and tokens (Tokens stored in database or JWT).
It's better to use Spring Boot OAuth2.
You should implement an Authorization server and Resource servers with Spring Boot.
Authorization server:
Choose the token storage method (JWT,Jdbc,...)
Configure client details
Add a RESTful Api for user info or enable /oauth/check_token api.(Called by Resource servers)
Resource servers:
Set user-info-uri or token-info-uri in Spring boot OAuth2 properties.
Extends ResourceServerConfigurerAdapter class for securing url mappings.
I have serveral microservices communicating with each other.
For general configuration I use Spring Cloud Config which works well.
Some of the services need to access database resources of a legacy system. So they need to know where the database (databases in a multi-tenant environment) is located and which credentials to use.
Using Spring Cloud Config I see two possibilities:
application.properties: This would expose the db settings to all services. That´s no option.
my-crazy-service.properties: This would work fine but I would have to configure any service which needs db access. Doesn´t scale well.
So my idea is to implement another microservice which is responsible for any connection infomation. This service exposes a rest endpoint using spring-data-rest.
In case Service A wants to use the legacy db it can call the new service and ask for the required data.
Now I wonder when the best time is to request the connection info from the remote service.
On startup of each microservice? Where should such startup code be located?
In general where should initialization stuff be done?
I'm developing a new application based on Spring MVC and Hibernate for data access.
I want the data access layer to be running on a separate application server, preferably JBOSS.
I want the data access layer to be running behind a firewall.
How can I achieve this?
Right now I'm concerned about hibernate lazy initialization in this scenario. Would there really be any problems with Hibernate lazy initialization?
There could be some performance penalties to this approach - the IO will be a bottleneck. However, Spring Remoting allows you to easily achieve this.
Create an interface for you DAO.
Implement the concrete implementation.
Use spring remoting to export the interface.
Inject the interface - from your apps point of view its just something that implements the interface. It doesn't care the the calls are being fired off to the remote server.
The mechanism for achieving this is called DynamicProxies - a Java SE feature. DynamicProxies allow you to provide a class that responds to the method calls on an interface at runtime. In this case the method calls are dispatched across to the corresponding methods on the remote server.
Both the service layer and DAO layer servers should be behind the firewall on the same domain.
From the UI, use REST web services to fetch the data from application server (hosting the DAO's and Transactional services). Annotate the entity classes with #Proxy(lazy=false) to avoid lazy loads of entities. For the server to validate the clients (web application querying the business layer behind firewall), use client identity certificates, you can use Bouncy Castle CMS APIs to validate the identity, trust and message integrity. If you have SSL offloaders in network, use detached signatures in http(s) headers.
How can we flow user session from one spring application context to another?
Basically I have one spring application representing Web Layer and another spring application representing REST layer. I want when Web Layer access the REST layer the session containing user info to be available from to Web at REST layer for authentication.
Please suggest.
Edit after receiving first ans:
At present we do have Web Layer in place along with security and all the other flows. What we are about to intended is to introduce REST layer. This REST layer is suppose to be called by present Web Layer and by other APIs. We do not want to make any changes for Web Layer, but at the same time need security to be placed at REST Layer that should work for Web Layer too when calling REST services.
Differentiate between SSO and session sharing. If you just want the authentication to carry between application (user only has to log in once), then you want some form of Single-Sign-On (SSO), CAS is one example, but there are numerous.
If, on the other hand, you need to have access to the full session (and everything the application has put in it) across different nodes (or applications), you could look into something like Memcached or Terracotta. Worth noting is that session replication is fairly I/O intensive and for larger sites it often requires a dedicated network interface for the replication.
I would put it to you, however, that if your applications are so tightly coupled that they need to share the same exact session state, then perhaps they should not be separated in the first place? This smells of faulty design and architecture assumptions.