1
1
/*
2
- * Copyright 2002-2022 the original author or authors.
2
+ * Copyright 2002-2023 the original author or authors.
3
3
*
4
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
5
* you may not use this file except in compliance with the License.
46
46
import org .springframework .security .core .userdetails .UserDetails ;
47
47
import org .springframework .security .oauth2 .client .OAuth2AuthorizeRequest ;
48
48
import org .springframework .security .oauth2 .client .OAuth2AuthorizedClient ;
49
- import org .springframework .security .oauth2 .client .OAuth2AuthorizedClientManager ;
50
49
import org .springframework .security .oauth2 .client .ReactiveOAuth2AuthorizedClientManager ;
51
50
import org .springframework .security .oauth2 .client .authentication .OAuth2AuthenticationToken ;
52
51
import org .springframework .security .oauth2 .client .registration .ClientRegistration ;
52
+ import org .springframework .security .oauth2 .client .web .DefaultReactiveOAuth2AuthorizedClientManager ;
53
+ import org .springframework .security .oauth2 .client .web .OAuth2AuthorizedClientRepository ;
53
54
import org .springframework .security .oauth2 .client .web .reactive .result .method .annotation .OAuth2AuthorizedClientArgumentResolver ;
54
55
import org .springframework .security .oauth2 .client .web .server .ServerOAuth2AuthorizedClientRepository ;
55
56
import org .springframework .security .oauth2 .client .web .server .WebSessionServerOAuth2AuthorizedClientRepository ;
@@ -214,8 +215,8 @@ public static OidcLoginMutator mockOidcLogin() {
214
215
* tokens to be valid.
215
216
*
216
217
* <p>
217
- * The support works by associating the authorized client to the ServerWebExchange via
218
- * the {@link WebSessionServerOAuth2AuthorizedClientRepository }
218
+ * The support works by associating the authorized client to the ServerWebExchange
219
+ * using a {@link ServerOAuth2AuthorizedClientRepository }
219
220
* </p>
220
221
* @return the {@link OAuth2ClientMutator} to further configure or use
221
222
* @since 5.3
@@ -230,8 +231,8 @@ public static OAuth2ClientMutator mockOAuth2Client() {
230
231
* tokens to be valid.
231
232
*
232
233
* <p>
233
- * The support works by associating the authorized client to the ServerWebExchange via
234
- * the {@link WebSessionServerOAuth2AuthorizedClientRepository }
234
+ * The support works by associating the authorized client to the ServerWebExchange
235
+ * using a {@link ServerOAuth2AuthorizedClientRepository }
235
236
* </p>
236
237
* @param registrationId The registration id associated with the
237
238
* {@link OAuth2AuthorizedClient}
@@ -715,8 +716,6 @@ public static final class OAuth2LoginMutator implements WebTestClientConfigurer,
715
716
716
717
private Supplier <OAuth2User > oauth2User = this ::defaultPrincipal ;
717
718
718
- private final ServerOAuth2AuthorizedClientRepository authorizedClientRepository = new WebSessionServerOAuth2AuthorizedClientRepository ();
719
-
720
719
private OAuth2LoginMutator (OAuth2AccessToken accessToken ) {
721
720
this .accessToken = accessToken ;
722
721
this .clientRegistration = clientRegistrationBuilder ().build ();
@@ -776,12 +775,8 @@ public OAuth2LoginMutator oauth2User(OAuth2User oauth2User) {
776
775
/**
777
776
* Use the provided {@link ClientRegistration} as the client to authorize.
778
777
* <p>
779
- * The supplied {@link ClientRegistration} will be registered into an
780
- * {@link WebSessionServerOAuth2AuthorizedClientRepository}. Tests relying on
781
- * {@link org.springframework.security.oauth2.client.annotation.RegisteredOAuth2AuthorizedClient}
782
- * annotations should register an
783
- * {@link WebSessionServerOAuth2AuthorizedClientRepository} bean to the
784
- * application context.
778
+ * The supplied {@link ClientRegistration} will be registered into a
779
+ * {@link ServerOAuth2AuthorizedClientRepository}.
785
780
* @param clientRegistration the {@link ClientRegistration} to use
786
781
* @return the {@link OAuth2LoginMutator} for further configuration
787
782
*/
@@ -866,8 +861,6 @@ public static final class OidcLoginMutator implements WebTestClientConfigurer, M
866
861
867
862
private Collection <GrantedAuthority > authorities ;
868
863
869
- ServerOAuth2AuthorizedClientRepository authorizedClientRepository = new WebSessionServerOAuth2AuthorizedClientRepository ();
870
-
871
864
private OidcLoginMutator (OAuth2AccessToken accessToken ) {
872
865
this .accessToken = accessToken ;
873
866
this .clientRegistration = clientRegistrationBuilder ().build ();
@@ -942,12 +935,8 @@ public OidcLoginMutator oidcUser(OidcUser oidcUser) {
942
935
/**
943
936
* Use the provided {@link ClientRegistration} as the client to authorize.
944
937
* <p>
945
- * The supplied {@link ClientRegistration} will be registered into an
946
- * {@link WebSessionServerOAuth2AuthorizedClientRepository}. Tests relying on
947
- * {@link org.springframework.security.oauth2.client.annotation.RegisteredOAuth2AuthorizedClient}
948
- * annotations should register an
949
- * {@link WebSessionServerOAuth2AuthorizedClientRepository} bean to the
950
- * application context.
938
+ * The supplied {@link ClientRegistration} will be registered into a
939
+ * {@link ServerOAuth2AuthorizedClientRepository}.
951
940
* @param clientRegistration the {@link ClientRegistration} to use
952
941
* @return the {@link OidcLoginMutator} for further configuration
953
942
*/
@@ -1037,8 +1026,6 @@ public static final class OAuth2ClientMutator implements WebTestClientConfigurer
1037
1026
private OAuth2AccessToken accessToken = new OAuth2AccessToken (OAuth2AccessToken .TokenType .BEARER ,
1038
1027
"access-token" , null , null , Collections .singleton ("read" ));
1039
1028
1040
- private ServerOAuth2AuthorizedClientRepository authorizedClientRepository = new WebSessionServerOAuth2AuthorizedClientRepository ();
1041
-
1042
1029
private OAuth2ClientMutator () {
1043
1030
}
1044
1031
@@ -1116,16 +1103,15 @@ public void afterConfigurerAdded(WebTestClient.Builder builder,
1116
1103
private Consumer <List <WebFilter >> addAuthorizedClientFilter () {
1117
1104
OAuth2AuthorizedClient client = getClient ();
1118
1105
return (filters ) -> filters .add (0 , (exchange , chain ) -> {
1119
- ReactiveOAuth2AuthorizedClientManager authorizationClientManager = OAuth2ClientServerTestUtils
1120
- .getOAuth2AuthorizedClientManager (exchange );
1121
- if (!(authorizationClientManager instanceof TestReactiveOAuth2AuthorizedClientManager )) {
1122
- authorizationClientManager = new TestReactiveOAuth2AuthorizedClientManager (
1123
- authorizationClientManager );
1124
- OAuth2ClientServerTestUtils .setOAuth2AuthorizedClientManager (exchange , authorizationClientManager );
1106
+ ServerOAuth2AuthorizedClientRepository authorizedClientRepository = OAuth2ClientServerTestUtils
1107
+ .getAuthorizedClientRepository (exchange );
1108
+ if (!(authorizedClientRepository instanceof TestOAuth2AuthorizedClientRepository )) {
1109
+ authorizedClientRepository = new TestOAuth2AuthorizedClientRepository (authorizedClientRepository );
1110
+ OAuth2ClientServerTestUtils .setAuthorizedClientRepository (exchange , authorizedClientRepository );
1125
1111
}
1126
- TestReactiveOAuth2AuthorizedClientManager .enable (exchange );
1127
- exchange . getAttributes (). put ( TestReactiveOAuth2AuthorizedClientManager . TOKEN_ATTR_NAME , client );
1128
- return chain .filter (exchange );
1112
+ TestOAuth2AuthorizedClientRepository .enable (exchange );
1113
+ return authorizedClientRepository . saveAuthorizedClient ( client , null , exchange )
1114
+ . then ( chain .filter (exchange ) );
1129
1115
});
1130
1116
}
1131
1117
@@ -1142,30 +1128,28 @@ private ClientRegistration.Builder clientRegistrationBuilder() {
1142
1128
}
1143
1129
1144
1130
/**
1145
- * Used to wrap the {@link OAuth2AuthorizedClientManager } to provide support for
1146
- * testing when the request is wrapped
1131
+ * Used to wrap the {@link OAuth2AuthorizedClientRepository } to provide support
1132
+ * for testing when the request is wrapped
1147
1133
*/
1148
- private static final class TestReactiveOAuth2AuthorizedClientManager
1149
- implements ReactiveOAuth2AuthorizedClientManager {
1134
+ private static final class TestOAuth2AuthorizedClientManager implements ReactiveOAuth2AuthorizedClientManager {
1150
1135
1151
- static final String TOKEN_ATTR_NAME = TestReactiveOAuth2AuthorizedClientManager .class .getName ()
1152
- .concat (".TOKEN" );
1153
-
1154
- static final String ENABLED_ATTR_NAME = TestReactiveOAuth2AuthorizedClientManager .class .getName ()
1136
+ static final String ENABLED_ATTR_NAME = TestOAuth2AuthorizedClientManager .class .getName ()
1155
1137
.concat (".ENABLED" );
1156
1138
1157
1139
private final ReactiveOAuth2AuthorizedClientManager delegate ;
1158
1140
1159
- private TestReactiveOAuth2AuthorizedClientManager (ReactiveOAuth2AuthorizedClientManager delegate ) {
1141
+ private ServerOAuth2AuthorizedClientRepository authorizedClientRepository ;
1142
+
1143
+ TestOAuth2AuthorizedClientManager (ReactiveOAuth2AuthorizedClientManager delegate ) {
1160
1144
this .delegate = delegate ;
1161
1145
}
1162
1146
1163
1147
@ Override
1164
1148
public Mono <OAuth2AuthorizedClient > authorize (OAuth2AuthorizeRequest authorizeRequest ) {
1165
1149
ServerWebExchange exchange = authorizeRequest .getAttribute (ServerWebExchange .class .getName ());
1166
1150
if (isEnabled (exchange )) {
1167
- OAuth2AuthorizedClient client = exchange . getAttribute ( TOKEN_ATTR_NAME );
1168
- return Mono . just ( client );
1151
+ return this . authorizedClientRepository . loadAuthorizedClient (
1152
+ authorizeRequest . getClientRegistrationId (), authorizeRequest . getPrincipal (), exchange );
1169
1153
}
1170
1154
return this .delegate .authorize (authorizeRequest );
1171
1155
}
@@ -1180,6 +1164,62 @@ boolean isEnabled(ServerWebExchange exchange) {
1180
1164
1181
1165
}
1182
1166
1167
+ /**
1168
+ * Used to wrap the {@link OAuth2AuthorizedClientRepository} to provide support
1169
+ * for testing when the request is wrapped
1170
+ */
1171
+ static final class TestOAuth2AuthorizedClientRepository implements ServerOAuth2AuthorizedClientRepository {
1172
+
1173
+ static final String TOKEN_ATTR_NAME = TestOAuth2AuthorizedClientRepository .class .getName ().concat (".TOKEN" );
1174
+
1175
+ static final String ENABLED_ATTR_NAME = TestOAuth2AuthorizedClientRepository .class .getName ()
1176
+ .concat (".ENABLED" );
1177
+
1178
+ private final ServerOAuth2AuthorizedClientRepository delegate ;
1179
+
1180
+ TestOAuth2AuthorizedClientRepository (ServerOAuth2AuthorizedClientRepository delegate ) {
1181
+ this .delegate = delegate ;
1182
+ }
1183
+
1184
+ @ Override
1185
+ public <T extends OAuth2AuthorizedClient > Mono <T > loadAuthorizedClient (String clientRegistrationId ,
1186
+ Authentication principal , ServerWebExchange exchange ) {
1187
+ if (isEnabled (exchange )) {
1188
+ return Mono .just (exchange .getAttribute (TOKEN_ATTR_NAME ));
1189
+ }
1190
+ return this .delegate .loadAuthorizedClient (clientRegistrationId , principal , exchange );
1191
+ }
1192
+
1193
+ @ Override
1194
+ public Mono <Void > saveAuthorizedClient (OAuth2AuthorizedClient authorizedClient , Authentication principal ,
1195
+ ServerWebExchange exchange ) {
1196
+ if (isEnabled (exchange )) {
1197
+ exchange .getAttributes ().put (TOKEN_ATTR_NAME , authorizedClient );
1198
+ return Mono .empty ();
1199
+ }
1200
+ return this .delegate .saveAuthorizedClient (authorizedClient , principal , exchange );
1201
+ }
1202
+
1203
+ @ Override
1204
+ public Mono <Void > removeAuthorizedClient (String clientRegistrationId , Authentication principal ,
1205
+ ServerWebExchange exchange ) {
1206
+ if (isEnabled (exchange )) {
1207
+ exchange .getAttributes ().remove (TOKEN_ATTR_NAME );
1208
+ return Mono .empty ();
1209
+ }
1210
+ return this .delegate .removeAuthorizedClient (clientRegistrationId , principal , exchange );
1211
+ }
1212
+
1213
+ static void enable (ServerWebExchange exchange ) {
1214
+ exchange .getAttributes ().put (ENABLED_ATTR_NAME , Boolean .TRUE );
1215
+ }
1216
+
1217
+ boolean isEnabled (ServerWebExchange exchange ) {
1218
+ return Boolean .TRUE .equals (exchange .getAttribute (ENABLED_ATTR_NAME ));
1219
+ }
1220
+
1221
+ }
1222
+
1183
1223
private static final class OAuth2ClientServerTestUtils {
1184
1224
1185
1225
private static final ServerOAuth2AuthorizedClientRepository DEFAULT_CLIENT_REPO = new WebSessionServerOAuth2AuthorizedClientRepository ();
@@ -1188,14 +1228,47 @@ private OAuth2ClientServerTestUtils() {
1188
1228
}
1189
1229
1190
1230
/**
1191
- * Gets the {@link ReactiveOAuth2AuthorizedClientManager } for the specified
1231
+ * Gets the {@link ServerOAuth2AuthorizedClientRepository } for the specified
1192
1232
* {@link ServerWebExchange}. If one is not found, one based off of
1193
1233
* {@link WebSessionServerOAuth2AuthorizedClientRepository} is used.
1194
1234
* @param exchange the {@link ServerWebExchange} to obtain the
1195
1235
* {@link ReactiveOAuth2AuthorizedClientManager}
1196
1236
* @return the {@link ReactiveOAuth2AuthorizedClientManager} for the specified
1197
1237
* {@link ServerWebExchange}
1198
1238
*/
1239
+ static ServerOAuth2AuthorizedClientRepository getAuthorizedClientRepository (ServerWebExchange exchange ) {
1240
+ ReactiveOAuth2AuthorizedClientManager manager = getOAuth2AuthorizedClientManager (exchange );
1241
+ if (manager == null ) {
1242
+ return DEFAULT_CLIENT_REPO ;
1243
+ }
1244
+ if (manager instanceof DefaultReactiveOAuth2AuthorizedClientManager ) {
1245
+ return (ServerOAuth2AuthorizedClientRepository ) ReflectionTestUtils .getField (manager ,
1246
+ "authorizedClientRepository" );
1247
+ }
1248
+ if (manager instanceof TestOAuth2AuthorizedClientManager ) {
1249
+ return ((TestOAuth2AuthorizedClientManager ) manager ).authorizedClientRepository ;
1250
+ }
1251
+ return DEFAULT_CLIENT_REPO ;
1252
+ }
1253
+
1254
+ static void setAuthorizedClientRepository (ServerWebExchange exchange ,
1255
+ ServerOAuth2AuthorizedClientRepository repository ) {
1256
+ ReactiveOAuth2AuthorizedClientManager manager = getOAuth2AuthorizedClientManager (exchange );
1257
+ if (manager == null ) {
1258
+ return ;
1259
+ }
1260
+ if (manager instanceof DefaultReactiveOAuth2AuthorizedClientManager ) {
1261
+ ReflectionTestUtils .setField (manager , "authorizedClientRepository" , repository );
1262
+ return ;
1263
+ }
1264
+ if (!(manager instanceof TestOAuth2AuthorizedClientManager )) {
1265
+ manager = new TestOAuth2AuthorizedClientManager (manager );
1266
+ setOAuth2AuthorizedClientManager (exchange , manager );
1267
+ }
1268
+ TestOAuth2AuthorizedClientManager .enable (exchange );
1269
+ ((TestOAuth2AuthorizedClientManager ) manager ).authorizedClientRepository = repository ;
1270
+ }
1271
+
1199
1272
static ReactiveOAuth2AuthorizedClientManager getOAuth2AuthorizedClientManager (ServerWebExchange exchange ) {
1200
1273
OAuth2AuthorizedClientArgumentResolver resolver = findResolver (exchange ,
1201
1274
OAuth2AuthorizedClientArgumentResolver .class );
0 commit comments