1
1
/*
2
- * Copyright 2002-2023 the original author or authors.
2
+ * Copyright 2002-2024 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.
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>
@@ -156,6 +158,8 @@ public final class OAuth2ResourceServerConfigurer<H extends HttpSecurityBuilder<
156
158
157
159
private BearerTokenResolver bearerTokenResolver ;
158
160
161
+ private AuthenticationConverter authenticationConverter ;
162
+
159
163
private JwtConfigurer jwtConfigurer ;
160
164
161
165
private OpaqueTokenConfigurer opaqueTokenConfigurer ;
@@ -198,6 +202,12 @@ public OAuth2ResourceServerConfigurer<H> bearerTokenResolver(BearerTokenResolver
198
202
return this ;
199
203
}
200
204
205
+ public OAuth2ResourceServerConfigurer <H > authenticationConverter (AuthenticationConverter authenticationConverter ) {
206
+ Assert .notNull (authenticationConverter , "authenticationConverter cannot be null" );
207
+ this .authenticationConverter = authenticationConverter ;
208
+ return this ;
209
+ }
210
+
201
211
/**
202
212
* @deprecated For removal in 7.0. Use {@link #jwt(Customizer)} or
203
213
* {@code jwt(Customizer.withDefaults())} to stick with defaults. See the <a href=
@@ -269,16 +279,25 @@ public void init(H http) {
269
279
270
280
@ Override
271
281
public void configure (H http ) {
272
- BearerTokenResolver bearerTokenResolver = getBearerTokenResolver ();
273
- this .requestMatcher .setBearerTokenResolver (bearerTokenResolver );
274
282
AuthenticationManagerResolver resolver = this .authenticationManagerResolver ;
275
283
if (resolver == null ) {
276
284
AuthenticationManager authenticationManager = getAuthenticationManager (http );
277
285
resolver = (request ) -> authenticationManager ;
278
286
}
279
-
280
287
BearerTokenAuthenticationFilter filter = new BearerTokenAuthenticationFilter (resolver );
281
- filter .setBearerTokenResolver (bearerTokenResolver );
288
+
289
+ BearerTokenResolver bearerTokenResolver = getBearerTokenResolver ();
290
+ if (bearerTokenResolver != null ) {
291
+ this .requestMatcher .setBearerTokenResolver (bearerTokenResolver );
292
+ filter .setBearerTokenResolver (bearerTokenResolver );
293
+ }
294
+ else {
295
+ AuthenticationConverter converter = getAuthenticationConverter ();
296
+ this .requestMatcher .setAuthenticationConverter (converter );
297
+ filter .setAuthenticationConverter (converter );
298
+ }
299
+
300
+ filter .setAuthenticationConverter (getAuthenticationConverter ());
282
301
filter .setAuthenticationEntryPoint (this .authenticationEntryPoint );
283
302
filter .setSecurityContextHolderStrategy (getSecurityContextHolderStrategy ());
284
303
filter = postProcess (filter );
@@ -366,11 +385,20 @@ BearerTokenResolver getBearerTokenResolver() {
366
385
if (this .context .getBeanNamesForType (BearerTokenResolver .class ).length > 0 ) {
367
386
this .bearerTokenResolver = this .context .getBean (BearerTokenResolver .class );
368
387
}
388
+ }
389
+ return this .bearerTokenResolver ;
390
+ }
391
+
392
+ AuthenticationConverter getAuthenticationConverter () {
393
+ if (this .authenticationConverter == null ) {
394
+ if (this .context .getBeanNamesForType (AuthenticationConverter .class ).length > 0 ) {
395
+ this .authenticationConverter = this .context .getBean (AuthenticationConverter .class );
396
+ }
369
397
else {
370
- this .bearerTokenResolver = new DefaultBearerTokenResolver ();
398
+ this .authenticationConverter = new BearerTokenAuthenticationConverter ();
371
399
}
372
400
}
373
- return this .bearerTokenResolver ;
401
+ return this .authenticationConverter ;
374
402
}
375
403
376
404
public class JwtConfigurer {
@@ -560,10 +588,15 @@ private static final class BearerTokenRequestMatcher implements RequestMatcher {
560
588
561
589
private BearerTokenResolver bearerTokenResolver ;
562
590
591
+ private AuthenticationConverter authenticationConverter ;
592
+
563
593
@ Override
564
594
public boolean matches (HttpServletRequest request ) {
565
595
try {
566
- return this .bearerTokenResolver .resolve (request ) != null ;
596
+ if (this .bearerTokenResolver != null ) {
597
+ return this .bearerTokenResolver .resolve (request ) != null ;
598
+ }
599
+ return this .authenticationConverter .convert (request ) != null ;
567
600
}
568
601
catch (OAuth2AuthenticationException ex ) {
569
602
return false ;
@@ -575,6 +608,11 @@ void setBearerTokenResolver(BearerTokenResolver tokenResolver) {
575
608
this .bearerTokenResolver = tokenResolver ;
576
609
}
577
610
611
+ void setAuthenticationConverter (AuthenticationConverter authenticationConverter ) {
612
+ Assert .notNull (authenticationConverter , "authenticationConverter cannot be null" );
613
+ this .authenticationConverter = authenticationConverter ;
614
+ }
615
+
578
616
}
579
617
580
618
}
0 commit comments