Introduce Spring Session MongoDB

* Migrate the module's code back into this project.
* Fold the documentation in.
* Update to current Gradle conventions.
* Reformat to match styling.
This commit is contained in:
Greg L. Turnquist
2021-08-13 13:40:28 -05:00
committed by Eleftheria Stein
parent d10c18eb88
commit bf139dbbb3
63 changed files with 5773 additions and 17 deletions

View File

@@ -6,6 +6,7 @@
***** {gh-samples-url}spring-session-sample-boot-redis-json[JSON serialization]
***** {gh-samples-url}spring-session-sample-boot-redis-simple[Simple Redis]
***** xref:guides/boot-redis.adoc[Redis with Events]
**** xref:guides/boot-mongo.adoc[MongoDB]
**** xref:guides/boot-jdbc.adoc[JDBC]
**** {gh-samples-url}spring-session-sample-boot-hazelcast[HttpSession with Hazelcast]
*** xref:guides/boot-findbyusername.adoc[Find by Username]

View File

@@ -0,0 +1,174 @@
= Spring Session - MongoDB Repositories
Jakub Kubrynski, Greg Turnquist
:stylesdir: ../
:highlightjsdir: ../js/highlight
:docinfodir: guides
This guide describes how to use Spring Session backed by MongoDB.
NOTE: The completed guide can be found in the <<mongo-sample, mongo sample application>>.
[#index-link]
link:../index.html[Index]
== Updating Dependencies
Before you use Spring Session MongoDB, you must ensure to update your dependencies.
We assume you are working with a working Spring Boot web application.
If you are using Maven, ensure to add the following dependencies:
====
[source,xml]
[subs="verbatim,attributes"]
.pom.xml
----
<dependencies>
<!-- ... -->
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-mongodb</artifactId>
</dependency>
</dependencies>
----
====
ifeval::["{version-snapshot}" == "true"]
Since We are using a SNAPSHOT version, we need to ensure to add the Spring Snapshot Maven Repository.
Ensure you have the following in your pom.xml:
====
[source,xml]
.pom.xml
----
<repositories>
<!-- ... -->
<repository>
<id>spring-snapshot</id>
<url>https://repo.spring.io/libs-snapshot</url>
</repository>
</repositories>
----
====
endif::[]
ifeval::["{version-milestone}" == "true"]
Since We are using a Milestone version, we need to ensure to add the Spring Milestone Maven Repository.
Ensure you have the following in your pom.xml:
====
[source,xml]
.pom.xml
----
<repository>
<id>spring-milestone</id>
<url>https://repo.spring.io/libs-milestone</url>
</repository>
----
====
endif::[]
[[mongo-spring-configuration]]
== Spring Configuration
After adding the required dependencies, we can create our Spring configuration.
The Spring configuration is responsible for creating a Servlet Filter that replaces the `HttpSession` implementation with an implementation backed by Spring Session.
// tag::config[]
All you have to do is to add the following Spring Configuration:
====
[source,java]
----
include::{samples-dir}spring-session-sample-boot-mongodb-traditional/src/main/java/org/springframework/session/mongodb/examples/config/HttpSessionConfig.java[tag=class]
----
<1> The `@EnableMongoHttpSession` annotation creates a Spring Bean with the name of `springSessionRepositoryFilter` that implements Filter.
This filter is what replaces the default `HttpSession` with the MongoDB-backed bean.
<2> Configures the session timeout to 30 minutes.
====
// end::config[]
[[boot-mongo-configuration]]
== Configuring the MongoDB Connection
Spring Boot automatically creates a `MongoClient` that connects Spring Session to a MongoDB Server on localhost on port 27017 (default port).
In a production environment you need to ensure to update your configuration to point to your MongoDB server.
For example, you can include the following in your *application.properties*
====
.src/main/resources/application.properties
----
spring.data.mongodb.host=mongo-srv
spring.data.mongodb.port=27018
spring.data.mongodb.database=prod
----
====
For more information, refer to https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-connecting-to-mongodb[Connecting to MongoDB] portion of the Spring Boot documentation.
[[boot-servlet-configuration]]
== Servlet Container Initialization
Our <<boot-mongo-configuration,Spring Configuration>> created a Spring Bean named `springSessionRepositoryFilter` that implements `Filter`.
The `springSessionRepositoryFilter` bean is responsible for replacing the `HttpSession` with a custom implementation that is backed by Spring Session.
In order for our `Filter` to do its magic, Spring needs to load our `Config` class.
Last we need to ensure that our Servlet Container (i.e. Tomcat) uses our `springSessionRepositoryFilter` for every request.
Fortunately, Spring Boot takes care of both of these steps for us.
[[mongo-sample]]
== MongoDB Sample Application
The MongoDB Sample Application demonstrates how to use Spring Session to transparently leverage MongoDB to back a web application's `HttpSession` when using Spring Boot.
[[mongo-running]]
=== Running the MongoDB Sample Application
You can run the sample by obtaining the {download-url}[source code] and invoking the following command:
====
----
$ ./gradlew :samples:mongo:bootRun
----
====
You should now be able to access the application at http://localhost:8080/
[[boot-explore]]
=== Exploring the security Sample Application
Try using the application. Enter the following to log in:
* **Username** _user_
* **Password** _password_
Now click the **Login** button.
You should now see a message indicating your are logged in with the user entered previously.
The user's information is stored in MongoDB rather than Tomcat's `HttpSession` implementation.
[[mongo-how]]
=== How does it work?
Instead of using Tomcat's `HttpSession`, we are actually persisting the values in Mongo.
Spring Session replaces the `HttpSession` with an implementation that is backed by Mongo.
When Spring Security's `SecurityContextPersistenceFilter` saves the `SecurityContext` to the `HttpSession` it is then persisted into Mongo.
When a new `HttpSession` is created, Spring Session creates a cookie named SESSION in your browser that contains the id of your session.
Go ahead and view the cookies (click for help with https://developer.chrome.com/devtools/docs/resources#cookies[Chrome] or https://getfirebug.com/wiki/index.php/Cookies_Panel#Cookies_List[Firefox]).
If you like, you can easily inspect the session using mongo client. For example, on a Linux based system you can type:
[NOTE]
====
The sample application uses an embedded MongoDB instance that listens on a randomly allocated port.
The port used by embedded MongoDB together with exact command to connect to it is logged during application startup.
====
$ mongo --port ...
> use test
> db.sessions.find().pretty()
Alternatively, you can also delete the explicit key. Enter the following into your terminal ensuring to replace `60f17293-839b-477c-bb92-07a9c3658843` with the value of your SESSION cookie:
> db.sessions.remove({"_id":"60f17293-839b-477c-bb92-07a9c3658843"})
Now visit the application at http://localhost:8080/ and observe that we are no longer authenticated.

View File

@@ -41,6 +41,68 @@ You can read the basic steps for integration in the next few sections, but we en
include::guides/xml-redis.adoc[tags=config,leveloffset=+2]
[[httpsession-mongo]]
=== HttpSession with Mongo
Using Spring Session with `HttpSession` is enabled by adding a Servlet Filter before anything that uses the `HttpSession`.
This section describes how to use Mongo to back `HttpSession` using Java based configuration.
NOTE: The <<samples, HttpSession Mongo Sample>> provides a working sample on how to integrate Spring Session and `HttpSession` using Java configuration.
You can read the basic steps for integration below, but you are encouraged to follow along with the detailed HttpSession Guide when integrating with your own application.
include::guides/boot-mongo.adoc[tags=config,leveloffset=+3]
==== Session serialization mechanisms
To be able to persist session objects in MongoDB we need to provide the serialization/deserialization mechanism.
By default, Spring Session MongoDB will use `JdkMongoSessionConverter`.
However, you may switch to `JacksonMongoSessionConverter` by merely adding the following code to your Boot app:
[source,java]
----
@Bean
JacksonMongoSessionConverter mongoSessionConverter() {
return new JacksonMongoSessionConverter();
}
----
===== JacksonMongoSessionConverter
This mechanism uses Jackson to serialize session objects to/from JSON.
By creating the following bean:
[source,java]
----
@Bean
JacksonMongoSessionConverter mongoSessionConverter() {
return new JacksonMongoSessionConverter();
}
----
...you are able to switch from the default (JDK-based serialization) to using Jackson.
IMPORTANT: If you are integrating with Spring Security (by storing your sessions in MongoDB), this configuration will
register the proper whitelisted components so Spring Security works properly.
If you would like to provide custom Jackson modules you can do it by explicitly registering modules as shown below:
[source,java,indent=0]
----
include::{code-dir}/src/test/java/org/springframework/session/data/mongo/integration/MongoRepositoryJacksonITest.java[tag=sample]
----
===== JdkMongoSessionConverter
`JdkMongoSessionConverter` uses standard Java serialization to persist session attributes map to MongoDB in a binary form.
However, standard session elements like id, access time, etc are still written as a plain Mongo objects and can be read and queried without additional effort.
`JdkMongoSessionConverter` is used if no explicit `AbstractMongoSessionConverter` Bean has been defined.
There is also a constructor taking `Serializer` and `Deserializer` objects, allowing you to pass custom implementations, which is especially important when you want to use non-default classloader.
[[httpsession-jdbc]]
== `HttpSession` with JDBC

View File

@@ -4,20 +4,19 @@
In Spring Session 1.x, all of the Spring Session's `SessionRepository` implementations were available within the `spring-session` artifact.
While convenient, this approach was not sustainable long-term as more features and `SessionRepository` implementations were added to the project.
Starting with Spring Session 2.0, the project has been split into Spring Session Core module and several other modules that carry `SessionRepository` implementations and functionality related to the specific data store.
Users of Spring Data should find this arrangement familiar, with Spring Session Core module taking a role equivalent to Spring Data Commons and providing core functionalities and APIs, with other modules containing data store specific implementations.
As part of this split, the Spring Session Data MongoDB and Spring Session Data GemFire modules were moved to separate repositories.
Now the situation with project's repositories/modules is as follows:
With Spring Session 2.0, several modules were split off to be separate modules as well as managed repositories.
Spring Session for MongoDB was retired, but was later reactivated as a separate module.
As of Spring Session 2.6, Spring Session for MongoDB was merged back into Spring Session.
Now the situation with the various repositories and modules is as follows:
* https://github.com/spring-projects/spring-session[`spring-session` repository]
** Hosts the Spring Session Core, Spring Session Data Redis, Spring Session JDBC, and Spring Session Hazelcast modules
* https://github.com/spring-projects/spring-session-data-mongodb[`spring-session-data-mongodb` repository]
** Hosts the Spring Session Data MongoDB module. Spring Session Data MongoDB has its own user guide, which you can find at the [https://spring.io/projects/spring-session-data-mongodb#learnSpring site].
** Hosts the Spring Session Core, Spring Session for MongoDB, Spring Session for Redis, Spring Session JDBC, and Spring Session Hazelcast modules.
* https://github.com/spring-projects/spring-session-data-geode[`spring-session-data-geode` repository]
** Hosts the Spring Session Data Geode modules. Spring Session Data Geode has its own user guide, which you can find at the [https://spring.io/projects/spring-session-data-geode#learn site].
Finally, Spring Session now also provides a Maven BOM ("`bill of materials`") module in order to help users with version management concerns:
Finally, Spring Session also provides a Maven BOM ("`bill of materials`") module in order to help users with version management concerns:
* https://github.com/spring-projects/spring-session-bom[`spring-session-bom` repository]
** Hosts the Spring Session BOM module

View File

@@ -43,6 +43,14 @@ To get started with Spring Session, the best place to start is our Sample Applic
| Demonstrates how to use Spring Session to replace the `HttpSession` with Redis using `RedisSessionRepository`.
|
| {gh-samples-url}spring-session-sample-boot-mongodb-traditional[Spring Session with MongoDB Repositories (servlet-based)]
| Demonstrates how to back Spring Session with traditional MongoDB repositories.
| link:guides/boot-mongo.html[Spring Session with MongoDB Repositories]
| {gh-samples-url}spring-session-sample-boot-mongodb-reactive[Spring Session with MongoDB Repositories (reactive)]
| Demonstrates how to back Spring Session with reactive MongoDB repositories.
| link:guides/boot-mongo.html[Spring Session with MongoDB Repositories]
|===
.Sample Applications that use Spring Java-based configuration

View File

@@ -16,19 +16,15 @@ The `spring-session-core` module holds only the common set of APIs and component
This applies to several existing modules that were previously a simple dependency aggregator helper module.
With new module arrangement, the following modules actually carry the implementation:
* Spring Session Data Redis
* Spring Session for MongoDB
* Spring Session for Redis
* Spring Session JDBC
* Spring Session Hazelcast
Also, the following modules were removed from the main project repository:
Also, the following were removed from the main project repository:
* Spring Session Data MongoDB
* Spring Session Data GemFire
Note that these two have moved to separate repositories and continue to be available under new artifact names:
* https://github.com/spring-projects/spring-session-data-mongodb[`spring-session-data-mongodb`]
* https://github.com/spring-projects/spring-session-data-geode[`spring-session-data-geode`]
** https://github.com/spring-projects/spring-session-data-geode[`spring-session-data-geode`]
== Replaced and Removed Packages, Classes, and Methods