|
37 | 37 | import org.springframework.security.config.annotation.web.configurers.CsrfConfigurer;
|
38 | 38 | import org.springframework.security.config.annotation.web.configurers.ExceptionHandlingConfigurer;
|
39 | 39 | import org.springframework.security.config.http.SessionCreationPolicy;
|
| 40 | +import org.springframework.security.core.Authentication; |
40 | 41 | import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
|
41 | 42 | import org.springframework.security.oauth2.jwt.Jwt;
|
42 | 43 | import org.springframework.security.oauth2.jwt.JwtDecoder;
|
|
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 | +import org.springframework.security.oauth2.server.resource.web.authentication.BearerTokenAuthenticationConverter; |
54 | 55 | import org.springframework.security.oauth2.server.resource.web.authentication.BearerTokenAuthenticationFilter;
|
55 | 56 | import org.springframework.security.web.AuthenticationEntryPoint;
|
56 | 57 | import org.springframework.security.web.access.AccessDeniedHandler;
|
57 | 58 | import org.springframework.security.web.access.AccessDeniedHandlerImpl;
|
58 | 59 | import org.springframework.security.web.access.DelegatingAccessDeniedHandler;
|
| 60 | +import org.springframework.security.web.authentication.AuthenticationConverter; |
59 | 61 | import org.springframework.security.web.csrf.CsrfException;
|
60 | 62 | import org.springframework.security.web.util.matcher.AndRequestMatcher;
|
61 | 63 | import org.springframework.security.web.util.matcher.MediaTypeRequestMatcher;
|
@@ -156,7 +158,7 @@ public final class OAuth2ResourceServerConfigurer<H extends HttpSecurityBuilder<
|
156 | 158 |
|
157 | 159 | private AuthenticationManagerResolver<HttpServletRequest> authenticationManagerResolver;
|
158 | 160 |
|
159 |
| - private BearerTokenResolver bearerTokenResolver; |
| 161 | + private AuthenticationConverter authenticationConverter; |
160 | 162 |
|
161 | 163 | private JwtConfigurer jwtConfigurer;
|
162 | 164 |
|
@@ -196,7 +198,19 @@ public OAuth2ResourceServerConfigurer<H> authenticationManagerResolver(
|
196 | 198 |
|
197 | 199 | public OAuth2ResourceServerConfigurer<H> bearerTokenResolver(BearerTokenResolver bearerTokenResolver) {
|
198 | 200 | Assert.notNull(bearerTokenResolver, "bearerTokenResolver cannot be null");
|
199 |
| - this.bearerTokenResolver = bearerTokenResolver; |
| 201 | + this.authenticationConverter = new BearerTokenResolverHoldingAuthenticationConverter(bearerTokenResolver); |
| 202 | + return this; |
| 203 | + } |
| 204 | + |
| 205 | + /** |
| 206 | + * Sets the {@link AuthenticationConverter} to use. |
| 207 | + * @param authenticationConverter the authentication converter |
| 208 | + * @return the {@link OAuth2ResourceServerConfigurer} for further configuration |
| 209 | + * @since 7.0 |
| 210 | + */ |
| 211 | + public OAuth2ResourceServerConfigurer<H> authenticationConverter(AuthenticationConverter authenticationConverter) { |
| 212 | + Assert.notNull(authenticationConverter, "authenticationConverter cannot be null"); |
| 213 | + this.authenticationConverter = authenticationConverter; |
200 | 214 | return this;
|
201 | 215 | }
|
202 | 216 |
|
@@ -271,16 +285,15 @@ public void init(H http) {
|
271 | 285 |
|
272 | 286 | @Override
|
273 | 287 | public void configure(H http) {
|
274 |
| - BearerTokenResolver bearerTokenResolver = getBearerTokenResolver(); |
275 |
| - this.requestMatcher.setBearerTokenResolver(bearerTokenResolver); |
276 | 288 | AuthenticationManagerResolver resolver = this.authenticationManagerResolver;
|
277 | 289 | if (resolver == null) {
|
278 | 290 | AuthenticationManager authenticationManager = getAuthenticationManager(http);
|
279 | 291 | resolver = (request) -> authenticationManager;
|
280 | 292 | }
|
281 | 293 |
|
282 |
| - BearerTokenAuthenticationFilter filter = new BearerTokenAuthenticationFilter(resolver); |
283 |
| - filter.setBearerTokenResolver(bearerTokenResolver); |
| 294 | + AuthenticationConverter converter = getAuthenticationConverter(); |
| 295 | + this.requestMatcher.setAuthenticationConverter(converter); |
| 296 | + BearerTokenAuthenticationFilter filter = new BearerTokenAuthenticationFilter(resolver, converter); |
284 | 297 | filter.setAuthenticationEntryPoint(this.authenticationEntryPoint);
|
285 | 298 | filter.setSecurityContextHolderStrategy(getSecurityContextHolderStrategy());
|
286 | 299 | filter = postProcess(filter);
|
@@ -363,16 +376,33 @@ AuthenticationManager getAuthenticationManager(H http) {
|
363 | 376 | return http.getSharedObject(AuthenticationManager.class);
|
364 | 377 | }
|
365 | 378 |
|
| 379 | + AuthenticationManagerResolver<HttpServletRequest> getAuthenticationManagerResolver() { |
| 380 | + return this.authenticationManagerResolver; |
| 381 | + } |
| 382 | + |
| 383 | + AuthenticationConverter getAuthenticationConverter() { |
| 384 | + if (this.authenticationConverter != null) { |
| 385 | + return this.authenticationConverter; |
| 386 | + } |
| 387 | + if (this.context.getBeanNamesForType(AuthenticationConverter.class).length > 0) { |
| 388 | + this.authenticationConverter = this.context.getBean(AuthenticationConverter.class); |
| 389 | + } |
| 390 | + else if (this.context.getBeanNamesForType(BearerTokenResolver.class).length > 0) { |
| 391 | + BearerTokenResolver bearerTokenResolver = this.context.getBean(BearerTokenResolver.class); |
| 392 | + this.authenticationConverter = new BearerTokenResolverHoldingAuthenticationConverter(bearerTokenResolver); |
| 393 | + } |
| 394 | + else { |
| 395 | + this.authenticationConverter = new BearerTokenAuthenticationConverter(); |
| 396 | + } |
| 397 | + return this.authenticationConverter; |
| 398 | + } |
| 399 | + |
366 | 400 | BearerTokenResolver getBearerTokenResolver() {
|
367 |
| - if (this.bearerTokenResolver == null) { |
368 |
| - if (this.context.getBeanNamesForType(BearerTokenResolver.class).length > 0) { |
369 |
| - this.bearerTokenResolver = this.context.getBean(BearerTokenResolver.class); |
370 |
| - } |
371 |
| - else { |
372 |
| - this.bearerTokenResolver = new DefaultBearerTokenResolver(); |
373 |
| - } |
| 401 | + AuthenticationConverter authenticationConverter = getAuthenticationConverter(); |
| 402 | + if (authenticationConverter instanceof OAuth2ResourceServerConfigurer.BearerTokenResolverHoldingAuthenticationConverter bearer) { |
| 403 | + return bearer.bearerTokenResolver; |
374 | 404 | }
|
375 |
| - return this.bearerTokenResolver; |
| 405 | + return null; |
376 | 406 | }
|
377 | 407 |
|
378 | 408 | public class JwtConfigurer {
|
@@ -560,21 +590,41 @@ AuthenticationManager getAuthenticationManager(H http) {
|
560 | 590 |
|
561 | 591 | private static final class BearerTokenRequestMatcher implements RequestMatcher {
|
562 | 592 |
|
563 |
| - private BearerTokenResolver bearerTokenResolver; |
| 593 | + private AuthenticationConverter authenticationConverter; |
564 | 594 |
|
565 | 595 | @Override
|
566 | 596 | public boolean matches(HttpServletRequest request) {
|
567 | 597 | try {
|
568 |
| - return this.bearerTokenResolver.resolve(request) != null; |
| 598 | + return this.authenticationConverter.convert(request) != null; |
569 | 599 | }
|
570 | 600 | catch (OAuth2AuthenticationException ex) {
|
571 | 601 | return false;
|
572 | 602 | }
|
573 | 603 | }
|
574 | 604 |
|
575 |
| - void setBearerTokenResolver(BearerTokenResolver tokenResolver) { |
576 |
| - Assert.notNull(tokenResolver, "resolver cannot be null"); |
577 |
| - this.bearerTokenResolver = tokenResolver; |
| 605 | + void setAuthenticationConverter(AuthenticationConverter authenticationConverter) { |
| 606 | + Assert.notNull(authenticationConverter, "authenticationConverter cannot be null"); |
| 607 | + this.authenticationConverter = authenticationConverter; |
| 608 | + } |
| 609 | + |
| 610 | + } |
| 611 | + |
| 612 | + private static final class BearerTokenResolverHoldingAuthenticationConverter implements AuthenticationConverter { |
| 613 | + |
| 614 | + private final BearerTokenResolver bearerTokenResolver; |
| 615 | + |
| 616 | + private final AuthenticationConverter authenticationConverter; |
| 617 | + |
| 618 | + BearerTokenResolverHoldingAuthenticationConverter(BearerTokenResolver bearerTokenResolver) { |
| 619 | + this.bearerTokenResolver = bearerTokenResolver; |
| 620 | + BearerTokenAuthenticationConverter authenticationConverter = new BearerTokenAuthenticationConverter(); |
| 621 | + authenticationConverter.setBearerTokenResolver(bearerTokenResolver); |
| 622 | + this.authenticationConverter = authenticationConverter; |
| 623 | + } |
| 624 | + |
| 625 | + @Override |
| 626 | + public Authentication convert(HttpServletRequest request) { |
| 627 | + return this.authenticationConverter.convert(request); |
578 | 628 | }
|
579 | 629 |
|
580 | 630 | }
|
|
0 commit comments