41
41
import org .springframework .security .oauth2 .jwt .Jwt ;
42
42
import org .springframework .security .oauth2 .jwt .JwtDecoder ;
43
43
import org .springframework .security .oauth2 .jwt .NimbusJwtDecoder ;
44
+ import org .springframework .security .oauth2 .server .resource .authentication .BearerTokenAuthenticationConverter ;
44
45
import org .springframework .security .oauth2 .server .resource .authentication .JwtAuthenticationConverter ;
45
46
import org .springframework .security .oauth2 .server .resource .authentication .JwtAuthenticationProvider ;
46
47
import org .springframework .security .oauth2 .server .resource .authentication .OpaqueTokenAuthenticationProvider ;
49
50
import org .springframework .security .oauth2 .server .resource .introspection .SpringOpaqueTokenIntrospector ;
50
51
import org .springframework .security .oauth2 .server .resource .web .BearerTokenAuthenticationEntryPoint ;
51
52
import org .springframework .security .oauth2 .server .resource .web .BearerTokenResolver ;
52
- import org .springframework .security .oauth2 .server .resource .web .DefaultBearerTokenResolver ;
53
53
import org .springframework .security .oauth2 .server .resource .web .access .BearerTokenAccessDeniedHandler ;
54
54
import org .springframework .security .oauth2 .server .resource .web .authentication .BearerTokenAuthenticationFilter ;
55
55
import org .springframework .security .web .AuthenticationEntryPoint ;
56
56
import org .springframework .security .web .access .AccessDeniedHandler ;
57
57
import org .springframework .security .web .access .AccessDeniedHandlerImpl ;
58
58
import org .springframework .security .web .access .DelegatingAccessDeniedHandler ;
59
+ import org .springframework .security .web .authentication .AuthenticationConverter ;
59
60
import org .springframework .security .web .csrf .CsrfException ;
60
61
import org .springframework .security .web .util .matcher .AndRequestMatcher ;
61
62
import org .springframework .security .web .util .matcher .MediaTypeRequestMatcher ;
68
69
import org .springframework .web .accept .HeaderContentNegotiationStrategy ;
69
70
70
71
/**
71
- *
72
72
* An {@link AbstractHttpConfigurer} for OAuth 2.0 Resource Server Support.
73
- *
73
+ * <p>
74
74
* By default, this wires a {@link BearerTokenAuthenticationFilter}, which can be used to
75
75
* parse the request for bearer tokens and make an authentication attempt.
76
76
*
84
84
* authentication failures are handled
85
85
* <li>{@link #bearerTokenResolver(BearerTokenResolver)} - customizes how to resolve a
86
86
* bearer token from the request</li>
87
+ * <li>{@link #authenticationConverter(AuthenticationConverter)} - customizes how to
88
+ * convert a request to authentication</li>
87
89
* <li>{@link #jwt(Customizer)} - enables Jwt-encoded bearer token support</li>
88
90
* <li>{@link #opaqueToken(Customizer)} - enables opaque bearer token support</li>
89
91
* </ul>
96
98
* <li>supply a {@link JwtDecoder} instance via {@link JwtConfigurer#decoder}, or</li>
97
99
* <li>expose a {@link JwtDecoder} bean</li>
98
100
* </ul>
99
- *
101
+ * <p>
100
102
* Also with {@link #jwt(Customizer)} consider
101
103
*
102
104
* <ul>
111
113
* </p>
112
114
*
113
115
* <h2>Security Filters</h2>
114
- *
116
+ * <p>
115
117
* The following {@code Filter}s are populated when {@link #jwt(Customizer)} is
116
118
* configured:
117
119
*
120
122
* </ul>
121
123
*
122
124
* <h2>Shared Objects Created</h2>
123
- *
125
+ * <p>
124
126
* The following shared objects are populated:
125
127
*
126
128
* <ul>
127
129
* <li>{@link SessionCreationPolicy} (optional)</li>
128
130
* </ul>
129
131
*
130
132
* <h2>Shared Objects Used</h2>
131
- *
133
+ * <p>
132
134
* The following shared objects are used:
133
135
*
134
136
* <ul>
@@ -158,6 +160,8 @@ public final class OAuth2ResourceServerConfigurer<H extends HttpSecurityBuilder<
158
160
159
161
private BearerTokenResolver bearerTokenResolver ;
160
162
163
+ private AuthenticationConverter authenticationConverter ;
164
+
161
165
private JwtConfigurer jwtConfigurer ;
162
166
163
167
private OpaqueTokenConfigurer opaqueTokenConfigurer ;
@@ -200,6 +204,12 @@ public OAuth2ResourceServerConfigurer<H> bearerTokenResolver(BearerTokenResolver
200
204
return this ;
201
205
}
202
206
207
+ public OAuth2ResourceServerConfigurer <H > authenticationConverter (AuthenticationConverter authenticationConverter ) {
208
+ Assert .notNull (authenticationConverter , "authenticationConverter cannot be null" );
209
+ this .authenticationConverter = authenticationConverter ;
210
+ return this ;
211
+ }
212
+
203
213
/**
204
214
* @deprecated For removal in 7.0. Use {@link #jwt(Customizer)} or
205
215
* {@code jwt(Customizer.withDefaults())} to stick with defaults. See the <a href=
@@ -271,16 +281,25 @@ public void init(H http) {
271
281
272
282
@ Override
273
283
public void configure (H http ) {
274
- BearerTokenResolver bearerTokenResolver = getBearerTokenResolver ();
275
- this .requestMatcher .setBearerTokenResolver (bearerTokenResolver );
276
284
AuthenticationManagerResolver resolver = this .authenticationManagerResolver ;
277
285
if (resolver == null ) {
278
286
AuthenticationManager authenticationManager = getAuthenticationManager (http );
279
287
resolver = (request ) -> authenticationManager ;
280
288
}
281
-
282
289
BearerTokenAuthenticationFilter filter = new BearerTokenAuthenticationFilter (resolver );
283
- filter .setBearerTokenResolver (bearerTokenResolver );
290
+
291
+ BearerTokenResolver bearerTokenResolver = getBearerTokenResolver ();
292
+ if (bearerTokenResolver != null ) {
293
+ this .requestMatcher .setBearerTokenResolver (bearerTokenResolver );
294
+ filter .setBearerTokenResolver (bearerTokenResolver );
295
+ }
296
+ else {
297
+ AuthenticationConverter converter = getAuthenticationConverter ();
298
+ this .requestMatcher .setAuthenticationConverter (converter );
299
+ filter .setAuthenticationConverter (converter );
300
+ }
301
+
302
+ filter .setAuthenticationConverter (getAuthenticationConverter ());
284
303
filter .setAuthenticationEntryPoint (this .authenticationEntryPoint );
285
304
filter .setSecurityContextHolderStrategy (getSecurityContextHolderStrategy ());
286
305
filter = postProcess (filter );
@@ -368,11 +387,20 @@ BearerTokenResolver getBearerTokenResolver() {
368
387
if (this .context .getBeanNamesForType (BearerTokenResolver .class ).length > 0 ) {
369
388
this .bearerTokenResolver = this .context .getBean (BearerTokenResolver .class );
370
389
}
390
+ }
391
+ return this .bearerTokenResolver ;
392
+ }
393
+
394
+ AuthenticationConverter getAuthenticationConverter () {
395
+ if (this .authenticationConverter == null ) {
396
+ if (this .context .getBeanNamesForType (AuthenticationConverter .class ).length > 0 ) {
397
+ this .authenticationConverter = this .context .getBean (AuthenticationConverter .class );
398
+ }
371
399
else {
372
- this .bearerTokenResolver = new DefaultBearerTokenResolver ();
400
+ this .authenticationConverter = new BearerTokenAuthenticationConverter ();
373
401
}
374
402
}
375
- return this .bearerTokenResolver ;
403
+ return this .authenticationConverter ;
376
404
}
377
405
378
406
public class JwtConfigurer {
@@ -562,10 +590,15 @@ private static final class BearerTokenRequestMatcher implements RequestMatcher {
562
590
563
591
private BearerTokenResolver bearerTokenResolver ;
564
592
593
+ private AuthenticationConverter authenticationConverter ;
594
+
565
595
@ Override
566
596
public boolean matches (HttpServletRequest request ) {
567
597
try {
568
- return this .bearerTokenResolver .resolve (request ) != null ;
598
+ if (this .bearerTokenResolver != null ) {
599
+ return this .bearerTokenResolver .resolve (request ) != null ;
600
+ }
601
+ return this .authenticationConverter .convert (request ) != null ;
569
602
}
570
603
catch (OAuth2AuthenticationException ex ) {
571
604
return false ;
@@ -577,6 +610,11 @@ void setBearerTokenResolver(BearerTokenResolver tokenResolver) {
577
610
this .bearerTokenResolver = tokenResolver ;
578
611
}
579
612
613
+ void setAuthenticationConverter (AuthenticationConverter authenticationConverter ) {
614
+ Assert .notNull (authenticationConverter , "authenticationConverter cannot be null" );
615
+ this .authenticationConverter = authenticationConverter ;
616
+ }
617
+
580
618
}
581
619
582
620
}
0 commit comments