23
23
import org .junit .jupiter .api .Test ;
24
24
import reactor .core .publisher .Mono ;
25
25
26
+ import org .springframework .mock .web .server .MockWebSession ;
26
27
import org .springframework .security .core .Authentication ;
27
28
import org .springframework .security .core .session .ReactiveSessionInformation ;
28
29
import org .springframework .security .web .server .authentication .InvalidateLeastUsedServerMaximumSessionsExceededHandler ;
34
35
import static org .mockito .Mockito .atLeastOnce ;
35
36
import static org .mockito .Mockito .mock ;
36
37
import static org .mockito .Mockito .spy ;
38
+ import static org .mockito .Mockito .times ;
37
39
import static org .mockito .Mockito .verify ;
38
40
import static org .mockito .Mockito .verifyNoMoreInteractions ;
39
41
@@ -59,18 +61,21 @@ void handleWhenInvokedThenInvalidatesLeastRecentlyUsedSessions() {
59
61
ReactiveSessionInformation session2 = mock (ReactiveSessionInformation .class );
60
62
given (session1 .getLastAccessTime ()).willReturn (Instant .ofEpochMilli (1700827760010L ));
61
63
given (session2 .getLastAccessTime ()).willReturn (Instant .ofEpochMilli (1700827760000L ));
64
+ given (session1 .getSessionId ()).willReturn ("session1" );
62
65
given (session2 .getSessionId ()).willReturn ("session2" );
63
66
given (session2 .invalidate ()).willReturn (Mono .empty ());
64
67
65
68
MaximumSessionsContext context = new MaximumSessionsContext (mock (Authentication .class ),
66
- List .of (session1 , session2 ), 2 , null );
69
+ List .of (session1 , session2 ), 2 , createWebSession () );
67
70
68
71
this .handler .handle (context ).block ();
69
72
70
73
verify (session2 ).invalidate ();
71
74
verify (session1 ).getLastAccessTime (); // used by comparator to sort the sessions
72
75
verify (session2 ).getLastAccessTime (); // used by comparator to sort the sessions
73
- verify (session2 ).getSessionId (); // used to invalidate session against the
76
+ verify (session1 ).getSessionId ();
77
+ verify (session2 , times (2 )).getSessionId (); // used to invalidate session against
78
+ // the
74
79
// WebSessionStore
75
80
verify (this .webSessionStore ).removeSession ("session2" );
76
81
verifyNoMoreInteractions (this .webSessionStore );
@@ -90,16 +95,18 @@ void handleWhenMoreThanOneSessionToInvalidateThenInvalidatesAllOfThem() {
90
95
given (session2 .invalidate ()).willReturn (Mono .empty ());
91
96
given (session1 .getSessionId ()).willReturn ("session1" );
92
97
given (session2 .getSessionId ()).willReturn ("session2" );
98
+ given (session3 .getSessionId ()).willReturn ("session3" );
93
99
94
100
MaximumSessionsContext context = new MaximumSessionsContext (mock (Authentication .class ),
95
- List .of (session1 , session2 , session3 ), 2 , null );
101
+ List .of (session1 , session2 , session3 ), 2 , createWebSession () );
96
102
this .handler .handle (context ).block ();
97
103
98
104
// @formatter:off
99
105
verify (session1 ).invalidate ();
100
106
verify (session2 ).invalidate ();
101
- verify (session1 ).getSessionId ();
102
- verify (session2 ).getSessionId ();
107
+ verify (session1 , times (2 )).getSessionId ();
108
+ verify (session2 , times (2 )).getSessionId ();
109
+ verify (session3 ).getSessionId ();
103
110
verify (session1 , atLeastOnce ()).getLastAccessTime (); // used by comparator to sort the sessions
104
111
verify (session2 , atLeastOnce ()).getLastAccessTime (); // used by comparator to sort the sessions
105
112
verify (session3 , atLeastOnce ()).getLastAccessTime (); // used by comparator to sort the sessions
@@ -112,4 +119,33 @@ void handleWhenMoreThanOneSessionToInvalidateThenInvalidatesAllOfThem() {
112
119
// @formatter:on
113
120
}
114
121
122
+ @ Test
123
+ void handleWhenCurrentSessionIsRegisteredThenDoNotInvalidateCurrentSession () {
124
+ ReactiveSessionInformation session1 = mock (ReactiveSessionInformation .class );
125
+ ReactiveSessionInformation session2 = mock (ReactiveSessionInformation .class );
126
+ MockWebSession currentSession = createWebSession ();
127
+ given (session1 .getLastAccessTime ()).willReturn (Instant .ofEpochMilli (1700827760010L ));
128
+ given (session2 .getLastAccessTime ()).willReturn (Instant .ofEpochMilli (1700827760000L ));
129
+ given (session1 .getSessionId ()).willReturn ("session1" );
130
+ given (session2 .getSessionId ()).willReturn (currentSession .getId ());
131
+ given (session1 .invalidate ()).willReturn (Mono .empty ());
132
+
133
+ MaximumSessionsContext context = new MaximumSessionsContext (mock (Authentication .class ),
134
+ List .of (session1 , session2 ), 1 , currentSession );
135
+
136
+ this .handler .handle (context ).block ();
137
+
138
+ verify (session1 ).invalidate ();
139
+ verify (session2 ).getSessionId ();
140
+ verify (session1 , times (2 )).getSessionId ();
141
+ verify (this .webSessionStore ).removeSession ("session1" );
142
+ verifyNoMoreInteractions (this .webSessionStore );
143
+ verifyNoMoreInteractions (session2 );
144
+ verifyNoMoreInteractions (session1 );
145
+ }
146
+
147
+ private MockWebSession createWebSession () {
148
+ return new MockWebSession ();
149
+ }
150
+
115
151
}
0 commit comments