19
19
import java .util .concurrent .ArrayBlockingQueue ;
20
20
import java .util .concurrent .BlockingQueue ;
21
21
import java .util .concurrent .TimeUnit ;
22
+ import java .util .function .Consumer ;
22
23
23
24
import org .junit .jupiter .api .Test ;
24
25
import org .junit .jupiter .api .extension .ExtendWith ;
25
26
import reactor .core .publisher .Mono ;
26
27
import reactor .test .StepVerifier ;
27
28
28
29
import org .springframework .beans .factory .annotation .Autowired ;
29
- import org .springframework .context .ApplicationEventPublisher ;
30
- import org .springframework .context .ApplicationListener ;
30
+ import org .springframework .context .ApplicationContext ;
31
31
import org .springframework .context .annotation .Bean ;
32
32
import org .springframework .context .annotation .Configuration ;
33
+ import org .springframework .context .annotation .Import ;
34
+ import org .springframework .context .event .EventListener ;
33
35
import org .springframework .security .access .AccessDeniedException ;
34
36
import org .springframework .security .authentication .AuthenticationTrustResolverImpl ;
35
37
import org .springframework .security .authorization .AuthorizationDecision ;
44
46
import org .springframework .security .test .context .support .ReactorContextTestExecutionListener ;
45
47
import org .springframework .security .test .context .support .WithMockUser ;
46
48
import org .springframework .security .test .context .support .WithSecurityContextTestExecutionListener ;
49
+ import org .springframework .stereotype .Component ;
47
50
import org .springframework .test .context .TestExecutionListeners ;
48
51
import org .springframework .test .context .junit .jupiter .SpringExtension ;
49
52
@@ -62,9 +65,6 @@ public class ReactiveAuthorizationManagerMethodSecurityConfigurationTests {
62
65
@ Autowired
63
66
ReactiveAuthorizationEventPublisher eventPublisher ;
64
67
65
- @ Autowired
66
- MyEventListener eventListener ;
67
-
68
68
AuthenticationTrustResolverImpl trustResolver = new AuthenticationTrustResolverImpl ();
69
69
70
70
@ Test
@@ -73,24 +73,26 @@ void preAuthorizeMonoWhenDeniedThenPublishEvent() {
73
73
StepVerifier .create (this .messageService .monoPreAuthorizeHasRoleFindById (1 ))
74
74
.expectError (AccessDeniedException .class )
75
75
.verify ();
76
- ReactiveAuthorizationDeniedEvent <?> event = this .eventListener .getEvent ();
77
- assertThat (event ).isNotNull ();
78
- assertThat (event .getAuthorizationDecision ().isGranted ()).isFalse ();
79
- StepVerifier .create (event .getAuthentication ()).assertNext (this .trustResolver ::isAnonymous ).verifyComplete ();
76
+ assertEvents ((event ) -> {
77
+ assertThat (event ).isNotNull ();
78
+ assertThat (event .getAuthorizationDecision ().isGranted ()).isFalse ();
79
+ StepVerifier .create (event .getAuthentication ()).assertNext (this .trustResolver ::isAnonymous ).verifyComplete ();
80
+ });
80
81
}
81
82
82
83
@ Test
83
84
@ WithMockUser (roles = "ADMIN" )
84
85
void preAuthorizeMonoWhenGrantedThenPublishEvent () {
85
86
this .spring .register (Config .class , AuthorizationEventPublisherConfig .class ).autowire ();
86
87
StepVerifier .create (this .messageService .monoPreAuthorizeHasRoleFindById (1 )).verifyComplete ();
87
- ReactiveAuthorizationGrantedEvent <?> event = this .eventListener .getEvent ();
88
- assertThat (event ).isNotNull ();
89
- assertThat (event .getAuthorizationDecision ().isGranted ()).isTrue ();
90
- StepVerifier .create (event .getAuthentication ())
91
- .assertNext ((auth ) -> assertThat (auth .getAuthorities ()).extracting (GrantedAuthority ::getAuthority )
92
- .contains ("ROLE_ADMIN" ))
93
- .verifyComplete ();
88
+ assertEvents ((event ) -> {
89
+ assertThat (event ).isNotNull ();
90
+ assertThat (event .getAuthorizationDecision ().isGranted ()).isTrue ();
91
+ StepVerifier .create (event .getAuthentication ())
92
+ .assertNext ((auth ) -> assertThat (auth .getAuthorities ()).extracting (GrantedAuthority ::getAuthority )
93
+ .contains ("ROLE_ADMIN" ))
94
+ .verifyComplete ();
95
+ });
94
96
}
95
97
96
98
@ Test
@@ -99,24 +101,26 @@ void preAuthorizeFluxWhenDeniedThenPublishEvent() {
99
101
StepVerifier .create (this .messageService .fluxPreAuthorizeHasRoleFindById (1 ))
100
102
.expectError (AccessDeniedException .class )
101
103
.verify ();
102
- ReactiveAuthorizationDeniedEvent <?> event = this .eventListener .getEvent ();
103
- assertThat (event ).isNotNull ();
104
- assertThat (event .getAuthorizationDecision ().isGranted ()).isFalse ();
105
- StepVerifier .create (event .getAuthentication ()).assertNext (this .trustResolver ::isAnonymous ).verifyComplete ();
104
+ assertEvents ((event ) -> {
105
+ assertThat (event ).isNotNull ();
106
+ assertThat (event .getAuthorizationDecision ().isGranted ()).isFalse ();
107
+ StepVerifier .create (event .getAuthentication ()).assertNext (this .trustResolver ::isAnonymous ).verifyComplete ();
108
+ });
106
109
}
107
110
108
111
@ Test
109
112
@ WithMockUser (roles = "ADMIN" )
110
113
void preAuthorizeFluxWhenGrantedThenPublishEvent () {
111
114
this .spring .register (Config .class , AuthorizationEventPublisherConfig .class ).autowire ();
112
115
StepVerifier .create (this .messageService .fluxPreAuthorizeHasRoleFindById (1 )).verifyComplete ();
113
- ReactiveAuthorizationGrantedEvent <?> event = this .eventListener .getEvent ();
114
- assertThat (event ).isNotNull ();
115
- assertThat (event .getAuthorizationDecision ().isGranted ()).isTrue ();
116
- StepVerifier .create (event .getAuthentication ())
117
- .assertNext ((auth ) -> assertThat (auth .getAuthorities ()).extracting (GrantedAuthority ::getAuthority )
118
- .contains ("ROLE_ADMIN" ))
119
- .verifyComplete ();
116
+ assertEvents ((event ) -> {
117
+ assertThat (event ).isNotNull ();
118
+ assertThat (event .getAuthorizationDecision ().isGranted ()).isTrue ();
119
+ StepVerifier .create (event .getAuthentication ())
120
+ .assertNext ((auth ) -> assertThat (auth .getAuthorities ()).extracting (GrantedAuthority ::getAuthority )
121
+ .contains ("ROLE_ADMIN" ))
122
+ .verifyComplete ();
123
+ });
120
124
}
121
125
122
126
@ Test
@@ -125,24 +129,26 @@ void postAuthorizeMonoWhenDeniedThenPublishEvent() {
125
129
StepVerifier .create (this .messageService .monoPostAuthorizeFindById (1 ))
126
130
.expectError (AccessDeniedException .class )
127
131
.verify ();
128
- ReactiveAuthorizationDeniedEvent <?> event = this .eventListener .getEvent ();
129
- assertThat (event ).isNotNull ();
130
- assertThat (event .getAuthorizationDecision ().isGranted ()).isFalse ();
131
- StepVerifier .create (event .getAuthentication ()).assertNext (this .trustResolver ::isAnonymous ).verifyComplete ();
132
+ assertEvents ((event ) -> {
133
+ assertThat (event ).isNotNull ();
134
+ assertThat (event .getAuthorizationDecision ().isGranted ()).isFalse ();
135
+ StepVerifier .create (event .getAuthentication ()).assertNext (this .trustResolver ::isAnonymous ).verifyComplete ();
136
+ });
132
137
}
133
138
134
139
@ Test
135
140
@ WithMockUser (roles = "ADMIN" )
136
141
void postAuthorizeMonoWhenGrantedThenPublishEvent () {
137
142
this .spring .register (Config .class , AuthorizationEventPublisherConfig .class ).autowire ();
138
143
StepVerifier .create (this .messageService .monoPostAuthorizeFindById (1 )).expectNext ("user" ).verifyComplete ();
139
- ReactiveAuthorizationGrantedEvent <?> event = this .eventListener .getEvent ();
140
- assertThat (event ).isNotNull ();
141
- assertThat (event .getAuthorizationDecision ().isGranted ()).isTrue ();
142
- StepVerifier .create (event .getAuthentication ())
143
- .assertNext ((auth ) -> assertThat (auth .getAuthorities ()).extracting (GrantedAuthority ::getAuthority )
144
- .contains ("ROLE_ADMIN" ))
145
- .verifyComplete ();
144
+ assertEvents ((event ) -> {
145
+ assertThat (event ).isNotNull ();
146
+ assertThat (event .getAuthorizationDecision ().isGranted ()).isTrue ();
147
+ StepVerifier .create (event .getAuthentication ())
148
+ .assertNext ((auth ) -> assertThat (auth .getAuthorities ()).extracting (GrantedAuthority ::getAuthority )
149
+ .contains ("ROLE_ADMIN" ))
150
+ .verifyComplete ();
151
+ });
146
152
}
147
153
148
154
@ Test
@@ -152,21 +158,30 @@ void postAuthorizeFluxWhenDeniedThenPublishEvent() {
152
158
StepVerifier .create (this .messageService .fluxPostAuthorizeFindById (1 ))
153
159
.expectError (AccessDeniedException .class )
154
160
.verify ();
155
- ReactiveAuthorizationDeniedEvent <?> event = this .eventListener .getEvent ();
156
- assertThat (event ).isNotNull ();
157
- assertThat (event .getAuthorizationDecision ().isGranted ()).isFalse ();
158
- StepVerifier .create (event .getAuthentication ()).assertNext (this .trustResolver ::isAnonymous ).verifyComplete ();
161
+ assertEvents ((event ) -> {
162
+ assertThat (event ).isNotNull ();
163
+ assertThat (event .getAuthorizationDecision ().isGranted ()).isFalse ();
164
+ StepVerifier .create (event .getAuthentication ()).assertNext (this .trustResolver ::isAnonymous ).verifyComplete ();
165
+ });
159
166
}
160
167
161
168
@ Test
162
169
@ WithMockUser
163
170
void postAuthorizeFluxWhenGrantedThenPublishEvent () {
164
171
this .spring .register (Config .class , AuthorizationEventPublisherConfig .class ).autowire ();
165
172
StepVerifier .create (this .messageService .fluxPostAuthorizeFindById (1 )).expectNext ("user" ).verifyComplete ();
166
- ReactiveAuthorizationGrantedEvent <?> event = this .eventListener .getEvent ();
167
- assertThat (event ).isNotNull ();
168
- assertThat (event .getAuthorizationDecision ().isGranted ()).isTrue ();
169
- StepVerifier .create (event .getAuthentication ()).expectNextCount (1 ).verifyComplete ();
173
+ assertEvents ((event ) -> {
174
+ assertThat (event ).isNotNull ();
175
+ assertThat (event .getAuthorizationDecision ().isGranted ()).isTrue ();
176
+ StepVerifier .create (event .getAuthentication ()).expectNextCount (1 ).verifyComplete ();
177
+ });
178
+ }
179
+
180
+ private void assertEvents (Consumer <ReactiveAuthorizationEvent > assertConsumer ) {
181
+ ReactiveAuthorizationEvent event = ImperativeListener .getEvent ();
182
+ ReactiveAuthorizationEvent reactiveEvent = ReactiveListener .getEvent ();
183
+ assertConsumer .accept (event );
184
+ assertConsumer .accept (reactiveEvent );
170
185
}
171
186
172
187
@ Configuration
@@ -185,11 +200,12 @@ Authz authz() {
185
200
186
201
}
187
202
188
- @ Configuration
203
+ @ Configuration (proxyBeanMethods = false )
204
+ @ Import ({ ImperativeListener .class , ReactiveListener .class })
189
205
static class AuthorizationEventPublisherConfig {
190
206
191
207
@ Bean
192
- ReactiveAuthorizationEventPublisher authorizationEventPublisher (ApplicationEventPublisher eventPublisher ) {
208
+ ReactiveAuthorizationEventPublisher authorizationEventPublisher (ApplicationContext eventPublisher ) {
193
209
return new ReactiveAuthorizationEventPublisher () {
194
210
@ Override
195
211
public <T > void publishAuthorizationEvent (Mono <Authentication > authentication , T object ,
@@ -206,18 +222,19 @@ public <T> void publishAuthorizationEvent(Mono<Authentication> authentication, T
206
222
};
207
223
}
208
224
209
- @ Bean
210
- MyEventListener myEventListener () {
211
- return new MyEventListener ();
212
- }
213
-
214
225
}
215
226
216
- public static class MyEventListener implements ApplicationListener <ReactiveAuthorizationEvent > {
227
+ @ Component
228
+ public static class ImperativeListener {
217
229
218
230
static BlockingQueue <ReactiveAuthorizationEvent > events = new ArrayBlockingQueue <>(10 );
219
231
220
- public <T extends ReactiveAuthorizationEvent > T getEvent () {
232
+ @ EventListener
233
+ public void onEvent (ReactiveAuthorizationEvent event ) {
234
+ events .add (event );
235
+ }
236
+
237
+ public static <T extends ReactiveAuthorizationEvent > T getEvent () {
221
238
try {
222
239
return (T ) events .poll (1 , TimeUnit .SECONDS );
223
240
}
@@ -226,9 +243,25 @@ public <T extends ReactiveAuthorizationEvent> T getEvent() {
226
243
}
227
244
}
228
245
229
- @ Override
230
- public void onApplicationEvent (ReactiveAuthorizationEvent event ) {
231
- events .add (event );
246
+ }
247
+
248
+ @ Component
249
+ public static class ReactiveListener {
250
+
251
+ static BlockingQueue <ReactiveAuthorizationEvent > events = new ArrayBlockingQueue <>(10 );
252
+
253
+ @ EventListener
254
+ public Mono <Void > onEvent (ReactiveAuthorizationEvent event ) {
255
+ return event .getAuthentication ().doOnNext ((authentication ) -> events .add (event )).then ();
256
+ }
257
+
258
+ public static <T extends ReactiveAuthorizationEvent > T getEvent () {
259
+ try {
260
+ return (T ) events .poll (1 , TimeUnit .SECONDS );
261
+ }
262
+ catch (InterruptedException ex ) {
263
+ return null ;
264
+ }
232
265
}
233
266
234
267
}
0 commit comments