mirror of
				https://github.com/spring-projects/spring-security.git
				synced 2025-10-30 22:28:46 +00:00 
			
		
		
		
	Polish OAuth2AuthorizationManagers
- Add OAuth2ReactiveAuthorizationManagers - Code to interfaces - Align error message with the same in AuthorityAuthorizationManager - Adjust expectations in tests to confirm an appropriately constructed authorizaion manager - Add JavaDoc and reference documentation Issue gh-13654
This commit is contained in:
		
							parent
							
								
									2ee8f27997
								
							
						
					
					
						commit
						a3227f041c
					
				| @ -165,11 +165,13 @@ Java:: | |||||||
| + | + | ||||||
| [source,java,role="primary"] | [source,java,role="primary"] | ||||||
| ---- | ---- | ||||||
|  | import static org.springframework.security.oauth2.core.authorization.OAuth2ReactiveAuthorizationManagers.hasScope; | ||||||
|  | 
 | ||||||
| @Bean | @Bean | ||||||
| SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) { | SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) { | ||||||
| 	http | 	http | ||||||
| 		.authorizeExchange(exchanges -> exchanges | 		.authorizeExchange(exchanges -> exchanges | ||||||
| 			.pathMatchers("/message/**").hasAuthority("SCOPE_message:read") | 			.pathMatchers("/message/**").access(hasScope("message:read")) | ||||||
| 			.anyExchange().authenticated() | 			.anyExchange().authenticated() | ||||||
| 		) | 		) | ||||||
| 		.oauth2ResourceServer(oauth2 -> oauth2 | 		.oauth2ResourceServer(oauth2 -> oauth2 | ||||||
| @ -183,11 +185,13 @@ Kotlin:: | |||||||
| + | + | ||||||
| [source,kotlin,role="secondary"] | [source,kotlin,role="secondary"] | ||||||
| ---- | ---- | ||||||
|  | import org.springframework.security.oauth2.core.authorization.OAuth2ReactiveAuthorizationManagers.hasScope | ||||||
|  | 
 | ||||||
| @Bean | @Bean | ||||||
| fun springSecurityFilterChain(http: ServerHttpSecurity): SecurityWebFilterChain { | fun springSecurityFilterChain(http: ServerHttpSecurity): SecurityWebFilterChain { | ||||||
|     return http { |     return http { | ||||||
|         authorizeExchange { |         authorizeExchange { | ||||||
|             authorize("/message/**", hasAuthority("SCOPE_message:read")) |             authorize("/message/**", hasScope("message:read")) | ||||||
|             authorize(anyExchange, authenticated) |             authorize(anyExchange, authenticated) | ||||||
|         } |         } | ||||||
|         oauth2ResourceServer { |         oauth2ResourceServer { | ||||||
| @ -682,12 +686,14 @@ Java:: | |||||||
| + | + | ||||||
| [source,java,role="primary"] | [source,java,role="primary"] | ||||||
| ---- | ---- | ||||||
|  | import static org.springframework.security.oauth2.core.authorization.OAuth2ReactiveAuthorizationManagers.hasScope; | ||||||
|  | 
 | ||||||
| @Bean | @Bean | ||||||
| SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) { | SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) { | ||||||
| 	http | 	http | ||||||
| 		.authorizeExchange(exchanges -> exchanges | 		.authorizeExchange(exchanges -> exchanges | ||||||
| 			.mvcMatchers("/contacts/**").hasAuthority("SCOPE_contacts") | 			.mvcMatchers("/contacts/**").access(hasScope("contacts")) | ||||||
| 			.mvcMatchers("/messages/**").hasAuthority("SCOPE_messages") | 			.mvcMatchers("/messages/**").access(hasScope("messages")) | ||||||
| 			.anyExchange().authenticated() | 			.anyExchange().authenticated() | ||||||
| 		) | 		) | ||||||
| 		.oauth2ResourceServer(OAuth2ResourceServerSpec::jwt); | 		.oauth2ResourceServer(OAuth2ResourceServerSpec::jwt); | ||||||
| @ -699,12 +705,14 @@ Kotlin:: | |||||||
| + | + | ||||||
| [source,kotlin,role="secondary"] | [source,kotlin,role="secondary"] | ||||||
| ---- | ---- | ||||||
|  | import org.springframework.security.oauth2.core.authorization.OAuth2ReactiveAuthorizationManagers.hasScope | ||||||
|  | 
 | ||||||
| @Bean | @Bean | ||||||
| fun springSecurityFilterChain(http: ServerHttpSecurity): SecurityWebFilterChain { | fun springSecurityFilterChain(http: ServerHttpSecurity): SecurityWebFilterChain { | ||||||
|     return http { |     return http { | ||||||
|         authorizeExchange { |         authorizeExchange { | ||||||
|             authorize("/contacts/**", hasAuthority("SCOPE_contacts")) |             authorize("/contacts/**", hasScope("contacts")) | ||||||
|             authorize("/messages/**", hasAuthority("SCOPE_messages")) |             authorize("/messages/**", hasScope("messages")) | ||||||
|             authorize(anyExchange, authenticated) |             authorize(anyExchange, authenticated) | ||||||
|         } |         } | ||||||
|         oauth2ResourceServer { |         oauth2ResourceServer { | ||||||
|  | |||||||
| @ -214,6 +214,8 @@ Java:: | |||||||
| + | + | ||||||
| [source,java,role="primary"] | [source,java,role="primary"] | ||||||
| ---- | ---- | ||||||
|  | import static org.springframework.security.oauth2.core.authorization.OAuth2ReactiveAuthorizationManagers.hasScope; | ||||||
|  | 
 | ||||||
| @Configuration | @Configuration | ||||||
| @EnableWebFluxSecurity | @EnableWebFluxSecurity | ||||||
| public class MyCustomSecurityConfiguration { | public class MyCustomSecurityConfiguration { | ||||||
| @ -221,7 +223,7 @@ public class MyCustomSecurityConfiguration { | |||||||
|     SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) { |     SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) { | ||||||
|         http |         http | ||||||
|             .authorizeExchange(exchanges -> exchanges |             .authorizeExchange(exchanges -> exchanges | ||||||
|                 .pathMatchers("/messages/**").hasAuthority("SCOPE_message:read") |                 .pathMatchers("/messages/**").access(hasScope("message:read")) | ||||||
|                 .anyExchange().authenticated() |                 .anyExchange().authenticated() | ||||||
|             ) |             ) | ||||||
|             .oauth2ResourceServer(oauth2 -> oauth2 |             .oauth2ResourceServer(oauth2 -> oauth2 | ||||||
| @ -238,11 +240,13 @@ Kotlin:: | |||||||
| + | + | ||||||
| [source,kotlin,role="secondary"] | [source,kotlin,role="secondary"] | ||||||
| ---- | ---- | ||||||
|  | import org.springframework.security.oauth2.core.authorization.OAuth2ReactiveAuthorizationManagers.hasScope | ||||||
|  | 
 | ||||||
| @Bean | @Bean | ||||||
| fun springSecurityFilterChain(http: ServerHttpSecurity): SecurityWebFilterChain { | fun springSecurityFilterChain(http: ServerHttpSecurity): SecurityWebFilterChain { | ||||||
|     return http { |     return http { | ||||||
|         authorizeExchange { |         authorizeExchange { | ||||||
|             authorize("/messages/**", hasAuthority("SCOPE_message:read")) |             authorize("/messages/**", hasScope("message:read")) | ||||||
|             authorize(anyExchange, authenticated) |             authorize(anyExchange, authenticated) | ||||||
|         } |         } | ||||||
|         oauth2ResourceServer { |         oauth2ResourceServer { | ||||||
| @ -442,6 +446,8 @@ Java:: | |||||||
| + | + | ||||||
| [source,java,role="primary"] | [source,java,role="primary"] | ||||||
| ---- | ---- | ||||||
|  | import static org.springframework.security.oauth2.core.authorization.OAuth2ReactiveAuthorizationManagers.hasScope; | ||||||
|  | 
 | ||||||
| @Configuration | @Configuration | ||||||
| @EnableWebFluxSecurity | @EnableWebFluxSecurity | ||||||
| public class MappedAuthorities { | public class MappedAuthorities { | ||||||
| @ -449,8 +455,8 @@ public class MappedAuthorities { | |||||||
|     SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) { |     SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) { | ||||||
|         http |         http | ||||||
|             .authorizeExchange(exchange -> exchange |             .authorizeExchange(exchange -> exchange | ||||||
|                 .pathMatchers("/contacts/**").hasAuthority("SCOPE_contacts") |                 .pathMatchers("/contacts/**").access(hasScope("contacts")) | ||||||
|                 .pathMatchers("/messages/**").hasAuthority("SCOPE_messages") |                 .pathMatchers("/messages/**").access(hasScope("messages")) | ||||||
|                 .anyExchange().authenticated() |                 .anyExchange().authenticated() | ||||||
|             ) |             ) | ||||||
|             .oauth2ResourceServer(ServerHttpSecurity.OAuth2ResourceServerSpec::opaqueToken); |             .oauth2ResourceServer(ServerHttpSecurity.OAuth2ResourceServerSpec::opaqueToken); | ||||||
| @ -463,12 +469,14 @@ Kotlin:: | |||||||
| + | + | ||||||
| [source,kotlin,role="secondary"] | [source,kotlin,role="secondary"] | ||||||
| ---- | ---- | ||||||
|  | import org.springframework.security.oauth2.core.authorization.OAuth2ReactiveAuthorizationManagers.hasScope | ||||||
|  | 
 | ||||||
| @Bean | @Bean | ||||||
| fun springSecurityFilterChain(http: ServerHttpSecurity): SecurityWebFilterChain { | fun springSecurityFilterChain(http: ServerHttpSecurity): SecurityWebFilterChain { | ||||||
|     return http { |     return http { | ||||||
|         authorizeExchange { |         authorizeExchange { | ||||||
|             authorize("/contacts/**", hasAuthority("SCOPE_contacts")) |             authorize("/contacts/**", hasScope("contacts")) | ||||||
|             authorize("/messages/**", hasAuthority("SCOPE_messages")) |             authorize("/messages/**", hasScope("messages")) | ||||||
|             authorize(anyExchange, authenticated) |             authorize(anyExchange, authenticated) | ||||||
|         } |         } | ||||||
|         oauth2ResourceServer { |         oauth2ResourceServer { | ||||||
|  | |||||||
| @ -211,6 +211,8 @@ Java:: | |||||||
| + | + | ||||||
| [source,java,role="primary"] | [source,java,role="primary"] | ||||||
| ---- | ---- | ||||||
|  | import static org.springframework.security.oauth2.core.authorization.OAuth2AuthorizationManagers.hasScope; | ||||||
|  | 
 | ||||||
| @Configuration | @Configuration | ||||||
| @EnableWebSecurity | @EnableWebSecurity | ||||||
| public class MyCustomSecurityConfiguration { | public class MyCustomSecurityConfiguration { | ||||||
| @ -218,7 +220,7 @@ public class MyCustomSecurityConfiguration { | |||||||
|     public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { |     public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { | ||||||
|         http |         http | ||||||
|             .authorizeHttpRequests(authorize -> authorize |             .authorizeHttpRequests(authorize -> authorize | ||||||
|                 .requestMatchers("/messages/**").hasAuthority("SCOPE_message:read") |                 .requestMatchers("/messages/**").access(hasScope("message:read")) | ||||||
|                 .anyRequest().authenticated() |                 .anyRequest().authenticated() | ||||||
|             ) |             ) | ||||||
|             .oauth2ResourceServer(oauth2 -> oauth2 |             .oauth2ResourceServer(oauth2 -> oauth2 | ||||||
| @ -235,6 +237,8 @@ Kotlin:: | |||||||
| + | + | ||||||
| [source,kotlin,role="secondary"] | [source,kotlin,role="secondary"] | ||||||
| ---- | ---- | ||||||
|  | import org.springframework.security.oauth2.core.authorization.OAuth2AuthorizationManagers.hasScope | ||||||
|  | 
 | ||||||
| @Configuration | @Configuration | ||||||
| @EnableWebSecurity | @EnableWebSecurity | ||||||
| class MyCustomSecurityConfiguration { | class MyCustomSecurityConfiguration { | ||||||
| @ -242,7 +246,7 @@ class MyCustomSecurityConfiguration { | |||||||
|     open fun filterChain(http: HttpSecurity): SecurityFilterChain { |     open fun filterChain(http: HttpSecurity): SecurityFilterChain { | ||||||
|         http { |         http { | ||||||
|             authorizeRequests { |             authorizeRequests { | ||||||
|                 authorize("/messages/**", hasAuthority("SCOPE_message:read")) |                 authorize("/messages/**", hasScope("message:read")) | ||||||
|                 authorize(anyRequest, authenticated) |                 authorize(anyRequest, authenticated) | ||||||
|             } |             } | ||||||
|             oauth2ResourceServer { |             oauth2ResourceServer { | ||||||
| @ -862,6 +866,8 @@ Java:: | |||||||
| + | + | ||||||
| [source,java,role="primary"] | [source,java,role="primary"] | ||||||
| ---- | ---- | ||||||
|  | import static org.springframework.security.oauth2.core.authorization.OAuth2AuthorizationManagers.hasScope; | ||||||
|  | 
 | ||||||
| @Configuration | @Configuration | ||||||
| @EnableWebSecurity | @EnableWebSecurity | ||||||
| public class DirectlyConfiguredJwkSetUri { | public class DirectlyConfiguredJwkSetUri { | ||||||
| @ -869,8 +875,8 @@ public class DirectlyConfiguredJwkSetUri { | |||||||
|     public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { |     public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { | ||||||
|         http |         http | ||||||
|             .authorizeHttpRequests(authorize -> authorize |             .authorizeHttpRequests(authorize -> authorize | ||||||
|                 .requestMatchers("/contacts/**").hasAuthority("SCOPE_contacts") |                 .requestMatchers("/contacts/**").access(hasScope("contacts")) | ||||||
|                 .requestMatchers("/messages/**").hasAuthority("SCOPE_messages") |                 .requestMatchers("/messages/**").access(hasScope("messages")) | ||||||
|                 .anyRequest().authenticated() |                 .anyRequest().authenticated() | ||||||
|             ) |             ) | ||||||
|             .oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt); |             .oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt); | ||||||
| @ -883,6 +889,8 @@ Kotlin:: | |||||||
| + | + | ||||||
| [source,kotlin,role="secondary"] | [source,kotlin,role="secondary"] | ||||||
| ---- | ---- | ||||||
|  | import org.springframework.security.oauth2.core.authorization.OAuth2AuthorizationManagers.hasScope; | ||||||
|  | 
 | ||||||
| @Configuration | @Configuration | ||||||
| @EnableWebSecurity | @EnableWebSecurity | ||||||
| class DirectlyConfiguredJwkSetUri { | class DirectlyConfiguredJwkSetUri { | ||||||
| @ -890,8 +898,8 @@ class DirectlyConfiguredJwkSetUri { | |||||||
|     open fun filterChain(http: HttpSecurity): SecurityFilterChain { |     open fun filterChain(http: HttpSecurity): SecurityFilterChain { | ||||||
|         http { |         http { | ||||||
|             authorizeRequests { |             authorizeRequests { | ||||||
|                 authorize("/contacts/**", hasAuthority("SCOPE_contacts")) |                 authorize("/contacts/**", hasScope("contacts")) | ||||||
|                 authorize("/messages/**", hasAuthority("SCOPE_messages")) |                 authorize("/messages/**", hasScope("messages")) | ||||||
|                 authorize(anyRequest, authenticated) |                 authorize(anyRequest, authenticated) | ||||||
|             } |             } | ||||||
|             oauth2ResourceServer { |             oauth2ResourceServer { | ||||||
|  | |||||||
| @ -239,6 +239,8 @@ Java:: | |||||||
| + | + | ||||||
| [source,java,role="primary"] | [source,java,role="primary"] | ||||||
| ---- | ---- | ||||||
|  | import static org.springframework.security.oauth2.core.authorization.OAuth2AuthorizationManagers.hasScope; | ||||||
|  | 
 | ||||||
| @Configuration | @Configuration | ||||||
| @EnableWebSecurity | @EnableWebSecurity | ||||||
| public class MyCustomSecurityConfiguration { | public class MyCustomSecurityConfiguration { | ||||||
| @ -246,7 +248,7 @@ public class MyCustomSecurityConfiguration { | |||||||
|     public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { |     public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { | ||||||
|         http |         http | ||||||
|             .authorizeHttpRequests(authorize -> authorize |             .authorizeHttpRequests(authorize -> authorize | ||||||
|                 .requestMatchers("/messages/**").hasAuthority("SCOPE_message:read") |                 .requestMatchers("/messages/**").access(hasScope("message:read")) | ||||||
|                 .anyRequest().authenticated() |                 .anyRequest().authenticated() | ||||||
|             ) |             ) | ||||||
|             .oauth2ResourceServer(oauth2 -> oauth2 |             .oauth2ResourceServer(oauth2 -> oauth2 | ||||||
| @ -263,6 +265,8 @@ Kotlin:: | |||||||
| + | + | ||||||
| [source,kotlin,role="secondary"] | [source,kotlin,role="secondary"] | ||||||
| ---- | ---- | ||||||
|  | import org.springframework.security.oauth2.core.authorization.OAuth2AuthorizationManagers.hasScope; | ||||||
|  | 
 | ||||||
| @Configuration | @Configuration | ||||||
| @EnableWebSecurity | @EnableWebSecurity | ||||||
| class MyCustomSecurityConfiguration { | class MyCustomSecurityConfiguration { | ||||||
| @ -270,7 +274,7 @@ class MyCustomSecurityConfiguration { | |||||||
|     open fun filterChain(http: HttpSecurity): SecurityFilterChain { |     open fun filterChain(http: HttpSecurity): SecurityFilterChain { | ||||||
|         http { |         http { | ||||||
|             authorizeRequests { |             authorizeRequests { | ||||||
|                 authorize("/messages/**", hasAuthority("SCOPE_message:read")) |                 authorize("/messages/**", hasScope("SCOPE_message:read")) | ||||||
|                 authorize(anyRequest, authenticated) |                 authorize(anyRequest, authenticated) | ||||||
|             } |             } | ||||||
|             oauth2ResourceServer { |             oauth2ResourceServer { | ||||||
| @ -547,6 +551,8 @@ Java:: | |||||||
| + | + | ||||||
| [source,java,role="primary"] | [source,java,role="primary"] | ||||||
| ---- | ---- | ||||||
|  | import static org.springframework.security.oauth2.core.authorization.OAuth2AuthorizationManagers.hasScope; | ||||||
|  | 
 | ||||||
| @Configuration | @Configuration | ||||||
| @EnableWebSecurity | @EnableWebSecurity | ||||||
| public class MappedAuthorities { | public class MappedAuthorities { | ||||||
| @ -554,8 +560,8 @@ public class MappedAuthorities { | |||||||
|     public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { |     public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { | ||||||
|         http |         http | ||||||
|             .authorizeHttpRequests(authorizeRequests -> authorizeRequests |             .authorizeHttpRequests(authorizeRequests -> authorizeRequests | ||||||
|                 .requestMatchers("/contacts/**").hasAuthority("SCOPE_contacts") |                 .requestMatchers("/contacts/**").access(hasScope("contacts")) | ||||||
|                 .requestMatchers("/messages/**").hasAuthority("SCOPE_messages") |                 .requestMatchers("/messages/**").access(hasScope("messages")) | ||||||
|                 .anyRequest().authenticated() |                 .anyRequest().authenticated() | ||||||
|             ) |             ) | ||||||
|             .oauth2ResourceServer(OAuth2ResourceServerConfigurer::opaqueToken); |             .oauth2ResourceServer(OAuth2ResourceServerConfigurer::opaqueToken); | ||||||
| @ -568,6 +574,8 @@ Kotlin:: | |||||||
| + | + | ||||||
| [source,kotlin,role="secondary"] | [source,kotlin,role="secondary"] | ||||||
| ---- | ---- | ||||||
|  | import org.springframework.security.oauth2.core.authorization.OAuth2AuthorizationManagers.hasScope | ||||||
|  | 
 | ||||||
| @Configuration | @Configuration | ||||||
| @EnableWebSecurity | @EnableWebSecurity | ||||||
| class MappedAuthorities { | class MappedAuthorities { | ||||||
| @ -575,8 +583,8 @@ class MappedAuthorities { | |||||||
|     open fun filterChain(http: HttpSecurity): SecurityFilterChain { |     open fun filterChain(http: HttpSecurity): SecurityFilterChain { | ||||||
|        http { |        http { | ||||||
|             authorizeRequests { |             authorizeRequests { | ||||||
|                 authorize("/contacts/**", hasAuthority("SCOPE_contacts")) |                 authorize("/contacts/**", hasScope("contacts")) | ||||||
|                 authorize("/messages/**", hasAuthority("SCOPE_messages")) |                 authorize("/messages/**", hasScope("messages")) | ||||||
|                 authorize(anyRequest, authenticated) |                 authorize(anyRequest, authenticated) | ||||||
|             } |             } | ||||||
|            oauth2ResourceServer { |            oauth2ResourceServer { | ||||||
|  | |||||||
| @ -1,56 +0,0 @@ | |||||||
| /* |  | ||||||
|  * Copyright 2002-2023 the original author or authors. |  | ||||||
|  * |  | ||||||
|  * Licensed under the Apache License, Version 2.0 (the "License"); |  | ||||||
|  * you may not use this file except in compliance with the License. |  | ||||||
|  * You may obtain a copy of the License at |  | ||||||
|  * |  | ||||||
|  *      https://www.apache.org/licenses/LICENSE-2.0 |  | ||||||
|  * |  | ||||||
|  * Unless required by applicable law or agreed to in writing, software |  | ||||||
|  * distributed under the License is distributed on an "AS IS" BASIS, |  | ||||||
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |  | ||||||
|  * See the License for the specific language governing permissions and |  | ||||||
|  * limitations under the License. |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| package org.springframework.security.oauth2.core; |  | ||||||
| 
 |  | ||||||
| import org.springframework.security.authorization.AuthorityAuthorizationManager; |  | ||||||
| 
 |  | ||||||
| /** |  | ||||||
|  * @author Mario Petrovski |  | ||||||
|  * @since 6.2 |  | ||||||
|  */ |  | ||||||
| public final class OAuth2AuthorizationManagers { |  | ||||||
| 
 |  | ||||||
| 	private OAuth2AuthorizationManagers() { |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	public static <T> AuthorityAuthorizationManager<T> hasScope(String scope) { |  | ||||||
| 		verifyScope(scope); |  | ||||||
| 		return AuthorityAuthorizationManager.hasAuthority("SCOPE_" + scope); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	public static <T> AuthorityAuthorizationManager<T> hasAnyScope(String... scopes) { |  | ||||||
| 		verifyScopes(scopes); |  | ||||||
| 		String[] mappedScopes = new String[scopes.length]; |  | ||||||
| 		for (int i = 0; i < scopes.length; i++) { |  | ||||||
| 			mappedScopes[i] = "SCOPE_" + scopes[i]; |  | ||||||
| 		} |  | ||||||
| 		return AuthorityAuthorizationManager.hasAnyAuthority(mappedScopes); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	private static void verifyScopes(String... scopes) throws IllegalArgumentException { |  | ||||||
| 		for (String scope : scopes) { |  | ||||||
| 			verifyScope(scope); |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	private static void verifyScope(String scope) { |  | ||||||
| 		if (scope.startsWith("SCOPE_")) { |  | ||||||
| 			throw new IllegalArgumentException("Scope '" + scope + "' start with 'SCOPE_' prefix."); |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| } |  | ||||||
| @ -0,0 +1,95 @@ | |||||||
|  | /* | ||||||
|  |  * Copyright 2002-2023 the original author or authors. | ||||||
|  |  * | ||||||
|  |  * Licensed under the Apache License, Version 2.0 (the "License"); | ||||||
|  |  * you may not use this file except in compliance with the License. | ||||||
|  |  * You may obtain a copy of the License at | ||||||
|  |  * | ||||||
|  |  *      https://www.apache.org/licenses/LICENSE-2.0 | ||||||
|  |  * | ||||||
|  |  * Unless required by applicable law or agreed to in writing, software | ||||||
|  |  * distributed under the License is distributed on an "AS IS" BASIS, | ||||||
|  |  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  |  * See the License for the specific language governing permissions and | ||||||
|  |  * limitations under the License. | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | package org.springframework.security.oauth2.core.authorization; | ||||||
|  | 
 | ||||||
|  | import org.springframework.security.authorization.AuthorityAuthorizationManager; | ||||||
|  | import org.springframework.security.authorization.AuthorizationManager; | ||||||
|  | import org.springframework.security.core.Authentication; | ||||||
|  | import org.springframework.util.Assert; | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * A convenience class for creating OAuth 2.0-specific {@link AuthorizationManager}s. | ||||||
|  |  * | ||||||
|  |  * @author Mario Petrovski | ||||||
|  |  * @author Josh Cummings | ||||||
|  |  * @since 6.2 | ||||||
|  |  * @see AuthorityAuthorizationManager | ||||||
|  |  */ | ||||||
|  | public final class OAuth2AuthorizationManagers { | ||||||
|  | 
 | ||||||
|  | 	private OAuth2AuthorizationManagers() { | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	/** | ||||||
|  | 	 * Create an {@link AuthorizationManager} that requires an {@link Authentication} to | ||||||
|  | 	 * have a {@code SCOPE_scope} authority. | ||||||
|  | 	 * | ||||||
|  | 	 * <p> | ||||||
|  | 	 * For example, if you call {@code hasScope("read")}, then this will require that each | ||||||
|  | 	 * authentication have a {@link org.springframework.security.core.GrantedAuthority} | ||||||
|  | 	 * whose value is {@code SCOPE_read}. | ||||||
|  | 	 * | ||||||
|  | 	 * <p> | ||||||
|  | 	 * This would equivalent to calling | ||||||
|  | 	 * {@code AuthorityAuthorizationManager#hasAuthority("SCOPE_read")}. | ||||||
|  | 	 * @param scope the scope value to require | ||||||
|  | 	 * @param <T> the secure object | ||||||
|  | 	 * @return an {@link AuthorizationManager} that requires a {@code "SCOPE_scope"} | ||||||
|  | 	 * authority | ||||||
|  | 	 */ | ||||||
|  | 	public static <T> AuthorizationManager<T> hasScope(String scope) { | ||||||
|  | 		assertScope(scope); | ||||||
|  | 		return AuthorityAuthorizationManager.hasAuthority("SCOPE_" + scope); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	/** | ||||||
|  | 	 * Create an {@link AuthorizationManager} that requires an {@link Authentication} to | ||||||
|  | 	 * have at least one authority among {@code SCOPE_scope1}, {@code SCOPE_scope2}, ... | ||||||
|  | 	 * {@code SCOPE_scopeN}. | ||||||
|  | 	 * | ||||||
|  | 	 * <p> | ||||||
|  | 	 * For example, if you call {@code hasAnyScope("read", "write")}, then this will | ||||||
|  | 	 * require that each authentication have at least a | ||||||
|  | 	 * {@link org.springframework.security.core.GrantedAuthority} whose value is either | ||||||
|  | 	 * {@code SCOPE_read} or {@code SCOPE_write}. | ||||||
|  | 	 * | ||||||
|  | 	 * <p> | ||||||
|  | 	 * This would equivalent to calling | ||||||
|  | 	 * {@code AuthorityAuthorizationManager#hasAnyAuthority("SCOPE_read", "SCOPE_write")}. | ||||||
|  | 	 * @param scopes the scope values to allow | ||||||
|  | 	 * @param <T> the secure object | ||||||
|  | 	 * @return an {@link AuthorizationManager} that requires at least one authority among | ||||||
|  | 	 * {@code "SCOPE_scope1"}, {@code SCOPE_scope2}, ... {@code SCOPE_scopeN}. | ||||||
|  | 	 * | ||||||
|  | 	 */ | ||||||
|  | 	public static <T> AuthorizationManager<T> hasAnyScope(String... scopes) { | ||||||
|  | 		String[] mappedScopes = new String[scopes.length]; | ||||||
|  | 		for (int i = 0; i < scopes.length; i++) { | ||||||
|  | 			assertScope(scopes[i]); | ||||||
|  | 			mappedScopes[i] = "SCOPE_" + scopes[i]; | ||||||
|  | 		} | ||||||
|  | 		return AuthorityAuthorizationManager.hasAnyAuthority(mappedScopes); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	private static void assertScope(String scope) { | ||||||
|  | 		Assert.isTrue(!scope.startsWith("SCOPE_"), | ||||||
|  | 				() -> scope + " should not start with SCOPE_ since SCOPE_" | ||||||
|  | 						+ " is automatically prepended when using hasScope and hasAnyScope. Consider using " | ||||||
|  | 						+ " AuthorityAuthorizationManager#hasAuthority or #hasAnyAuthority instead."); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | } | ||||||
| @ -0,0 +1,95 @@ | |||||||
|  | /* | ||||||
|  |  * Copyright 2002-2023 the original author or authors. | ||||||
|  |  * | ||||||
|  |  * Licensed under the Apache License, Version 2.0 (the "License"); | ||||||
|  |  * you may not use this file except in compliance with the License. | ||||||
|  |  * You may obtain a copy of the License at | ||||||
|  |  * | ||||||
|  |  *      https://www.apache.org/licenses/LICENSE-2.0 | ||||||
|  |  * | ||||||
|  |  * Unless required by applicable law or agreed to in writing, software | ||||||
|  |  * distributed under the License is distributed on an "AS IS" BASIS, | ||||||
|  |  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  |  * See the License for the specific language governing permissions and | ||||||
|  |  * limitations under the License. | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | package org.springframework.security.oauth2.core.authorization; | ||||||
|  | 
 | ||||||
|  | import org.springframework.security.authorization.AuthorityReactiveAuthorizationManager; | ||||||
|  | import org.springframework.security.authorization.AuthorizationManager; | ||||||
|  | import org.springframework.security.authorization.ReactiveAuthorizationManager; | ||||||
|  | import org.springframework.security.core.Authentication; | ||||||
|  | import org.springframework.util.Assert; | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * A convenience class for creating OAuth 2.0-specific {@link AuthorizationManager}s. | ||||||
|  |  * | ||||||
|  |  * @author Josh Cummings | ||||||
|  |  * @since 6.2 | ||||||
|  |  * @see AuthorityReactiveAuthorizationManager | ||||||
|  |  */ | ||||||
|  | public final class OAuth2ReactiveAuthorizationManagers { | ||||||
|  | 
 | ||||||
|  | 	private OAuth2ReactiveAuthorizationManagers() { | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	/** | ||||||
|  | 	 * Create a {@link ReactiveAuthorizationManager} that requires an | ||||||
|  | 	 * {@link Authentication} to have a {@code SCOPE_scope} authority. | ||||||
|  | 	 * | ||||||
|  | 	 * <p> | ||||||
|  | 	 * For example, if you call {@code hasScope("read")}, then this will require that each | ||||||
|  | 	 * authentication have a {@link org.springframework.security.core.GrantedAuthority} | ||||||
|  | 	 * whose value is {@code SCOPE_read}. | ||||||
|  | 	 * | ||||||
|  | 	 * <p> | ||||||
|  | 	 * This would equivalent to calling | ||||||
|  | 	 * {@code AuthorityReactiveAuthorizationManager#hasAuthority("SCOPE_read")}. | ||||||
|  | 	 * @param scope the scope value to require | ||||||
|  | 	 * @param <T> the secure object | ||||||
|  | 	 * @return an {@link ReactiveAuthorizationManager} that requires a | ||||||
|  | 	 * {@code "SCOPE_scope"} authority | ||||||
|  | 	 */ | ||||||
|  | 	public static <T> ReactiveAuthorizationManager<T> hasScope(String scope) { | ||||||
|  | 		assertScope(scope); | ||||||
|  | 		return AuthorityReactiveAuthorizationManager.hasAuthority("SCOPE_" + scope); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	/** | ||||||
|  | 	 * Create a {@link ReactiveAuthorizationManager} that requires an | ||||||
|  | 	 * {@link Authentication} to have at least one authority among {@code SCOPE_scope1}, | ||||||
|  | 	 * {@code SCOPE_scope2}, ... {@code SCOPE_scopeN}. | ||||||
|  | 	 * | ||||||
|  | 	 * <p> | ||||||
|  | 	 * For example, if you call {@code hasAnyScope("read", "write")}, then this will | ||||||
|  | 	 * require that each authentication have at least a | ||||||
|  | 	 * {@link org.springframework.security.core.GrantedAuthority} whose value is either | ||||||
|  | 	 * {@code SCOPE_read} or {@code SCOPE_write}. | ||||||
|  | 	 * | ||||||
|  | 	 * <p> | ||||||
|  | 	 * This would equivalent to calling | ||||||
|  | 	 * {@code AuthorityReactiveAuthorizationManager#hasAnyAuthority("SCOPE_read", "SCOPE_write")}. | ||||||
|  | 	 * @param scopes the scope values to allow | ||||||
|  | 	 * @param <T> the secure object | ||||||
|  | 	 * @return an {@link ReactiveAuthorizationManager} that requires at least one | ||||||
|  | 	 * authority among {@code "SCOPE_scope1"}, {@code SCOPE_scope2}, ... | ||||||
|  | 	 * {@code SCOPE_scopeN}. | ||||||
|  | 	 */ | ||||||
|  | 	public static <T> ReactiveAuthorizationManager<T> hasAnyScope(String... scopes) { | ||||||
|  | 		String[] mappedScopes = new String[scopes.length]; | ||||||
|  | 		for (int i = 0; i < scopes.length; i++) { | ||||||
|  | 			assertScope(scopes[i]); | ||||||
|  | 			mappedScopes[i] = "SCOPE_" + scopes[i]; | ||||||
|  | 		} | ||||||
|  | 		return AuthorityReactiveAuthorizationManager.hasAnyAuthority(mappedScopes); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	private static void assertScope(String scope) { | ||||||
|  | 		Assert.isTrue(!scope.startsWith("SCOPE_"), | ||||||
|  | 				() -> scope + " should not start with SCOPE_ since SCOPE_" | ||||||
|  | 						+ " is automatically prepended when using hasScope and hasAnyScope. Consider using " | ||||||
|  | 						+ " AuthorityReactiveAuthorizationManager#hasAuthority or #hasAnyAuthority instead."); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | } | ||||||
| @ -1,63 +0,0 @@ | |||||||
| /* |  | ||||||
|  * Copyright 2002-2023 the original author or authors. |  | ||||||
|  * |  | ||||||
|  * Licensed under the Apache License, Version 2.0 (the "License"); |  | ||||||
|  * you may not use this file except in compliance with the License. |  | ||||||
|  * You may obtain a copy of the License at |  | ||||||
|  * |  | ||||||
|  *      https://www.apache.org/licenses/LICENSE-2.0 |  | ||||||
|  * |  | ||||||
|  * Unless required by applicable law or agreed to in writing, software |  | ||||||
|  * distributed under the License is distributed on an "AS IS" BASIS, |  | ||||||
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |  | ||||||
|  * See the License for the specific language governing permissions and |  | ||||||
|  * limitations under the License. |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| package org.springframework.security.oauth2.core; |  | ||||||
| 
 |  | ||||||
| import org.junit.jupiter.api.Test; |  | ||||||
| 
 |  | ||||||
| import org.springframework.security.authorization.AuthorityAuthorizationManager; |  | ||||||
| 
 |  | ||||||
| import static org.assertj.core.api.Assertions.assertThat; |  | ||||||
| import static org.assertj.core.api.Assertions.assertThatExceptionOfType; |  | ||||||
| 
 |  | ||||||
| /** |  | ||||||
|  * Tests for {@link OAuth2AuthorizationManagers} |  | ||||||
|  * |  | ||||||
|  * @author Mario Petrovski |  | ||||||
|  */ |  | ||||||
| public class OAuth2AuthorizationManagersTests { |  | ||||||
| 
 |  | ||||||
| 	@Test |  | ||||||
| 	void hasScope_withInvalidScope_shouldThrowIllegalArgumentException() { |  | ||||||
| 		String scope = "SCOPE_invalid"; |  | ||||||
| 		assertThatExceptionOfType(IllegalArgumentException.class) |  | ||||||
| 				.isThrownBy(() -> OAuth2AuthorizationManagers.hasScope(scope)) |  | ||||||
| 				.withMessage("Scope 'SCOPE_invalid' start with 'SCOPE_' prefix."); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	@Test |  | ||||||
| 	void hasScopes_withInvalidScope_shouldThrowIllegalArgumentException() { |  | ||||||
| 		String[] scopes = { "read", "write", "SCOPE_invalid" }; |  | ||||||
| 		assertThatExceptionOfType(IllegalArgumentException.class) |  | ||||||
| 				.isThrownBy(() -> OAuth2AuthorizationManagers.hasAnyScope(scopes)) |  | ||||||
| 				.withMessage("Scope 'SCOPE_invalid' start with 'SCOPE_' prefix."); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	@Test |  | ||||||
| 	void hasScope_withValidScope_shouldPass() { |  | ||||||
| 		String scope = "read"; |  | ||||||
| 		AuthorityAuthorizationManager<Object> authorizationManager = OAuth2AuthorizationManagers.hasScope(scope); |  | ||||||
| 		assertThat(authorizationManager).isNotNull(); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	@Test |  | ||||||
| 	void hasScope_withValidScopes_shouldPass() { |  | ||||||
| 		String[] scopes = { "read", "write" }; |  | ||||||
| 		AuthorityAuthorizationManager<Object> authorizationManager = OAuth2AuthorizationManagers.hasAnyScope(scopes); |  | ||||||
| 		assertThat(authorizationManager).isNotNull(); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| } |  | ||||||
| @ -0,0 +1,76 @@ | |||||||
|  | /* | ||||||
|  |  * Copyright 2002-2023 the original author or authors. | ||||||
|  |  * | ||||||
|  |  * Licensed under the Apache License, Version 2.0 (the "License"); | ||||||
|  |  * you may not use this file except in compliance with the License. | ||||||
|  |  * You may obtain a copy of the License at | ||||||
|  |  * | ||||||
|  |  *      https://www.apache.org/licenses/LICENSE-2.0 | ||||||
|  |  * | ||||||
|  |  * Unless required by applicable law or agreed to in writing, software | ||||||
|  |  * distributed under the License is distributed on an "AS IS" BASIS, | ||||||
|  |  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  |  * See the License for the specific language governing permissions and | ||||||
|  |  * limitations under the License. | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | package org.springframework.security.oauth2.core.authorization; | ||||||
|  | 
 | ||||||
|  | import org.junit.jupiter.api.Test; | ||||||
|  | 
 | ||||||
|  | import org.springframework.security.access.AccessDeniedException; | ||||||
|  | import org.springframework.security.authentication.TestingAuthenticationToken; | ||||||
|  | import org.springframework.security.authorization.AuthorizationManager; | ||||||
|  | import org.springframework.security.core.Authentication; | ||||||
|  | 
 | ||||||
|  | import static org.assertj.core.api.Assertions.assertThatExceptionOfType; | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * Tests for {@link OAuth2AuthorizationManagers} | ||||||
|  |  * | ||||||
|  |  * @author Mario Petrovski | ||||||
|  |  * @author Josh Cummings | ||||||
|  |  */ | ||||||
|  | public class OAuth2AuthorizationManagersTests { | ||||||
|  | 
 | ||||||
|  | 	@Test | ||||||
|  | 	void hasScopeWhenInvalidScopeThenThrowIllegalArgument() { | ||||||
|  | 		String scope = "SCOPE_invalid"; | ||||||
|  | 		assertThatExceptionOfType(IllegalArgumentException.class) | ||||||
|  | 				.isThrownBy(() -> OAuth2AuthorizationManagers.hasScope(scope)) | ||||||
|  | 				.withMessageContaining("SCOPE_invalid should not start with SCOPE_"); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	@Test | ||||||
|  | 	void hasAnyScopeWhenInvalidScopeThenThrowIllegalArgument() { | ||||||
|  | 		String[] scopes = { "read", "write", "SCOPE_invalid" }; | ||||||
|  | 		assertThatExceptionOfType(IllegalArgumentException.class) | ||||||
|  | 				.isThrownBy(() -> OAuth2AuthorizationManagers.hasAnyScope(scopes)) | ||||||
|  | 				.withMessageContaining("SCOPE_invalid should not start with SCOPE_"); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	@Test | ||||||
|  | 	void hasScopeWhenValidScopeThenAuthorizationManager() { | ||||||
|  | 		String scope = "read"; | ||||||
|  | 		AuthorizationManager<Object> authorizationManager = OAuth2AuthorizationManagers.hasScope(scope); | ||||||
|  | 		authorizationManager.verify(() -> hasScope(scope), new Object()); | ||||||
|  | 		assertThatExceptionOfType(AccessDeniedException.class) | ||||||
|  | 				.isThrownBy(() -> authorizationManager.verify(() -> hasScope("wrong"), new Object())); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	@Test | ||||||
|  | 	void hasAnyScopeWhenValidScopesThenAuthorizationManager() { | ||||||
|  | 		String[] scopes = { "read", "write" }; | ||||||
|  | 		AuthorizationManager<Object> authorizationManager = OAuth2AuthorizationManagers.hasAnyScope(scopes); | ||||||
|  | 		for (String scope : scopes) { | ||||||
|  | 			authorizationManager.verify(() -> hasScope(scope), new Object()); | ||||||
|  | 		} | ||||||
|  | 		assertThatExceptionOfType(AccessDeniedException.class) | ||||||
|  | 				.isThrownBy(() -> authorizationManager.verify(() -> hasScope("wrong"), new Object())); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	Authentication hasScope(String scope) { | ||||||
|  | 		return new TestingAuthenticationToken("user", "pass", "SCOPE_" + scope); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | } | ||||||
| @ -0,0 +1,77 @@ | |||||||
|  | /* | ||||||
|  |  * Copyright 2002-2023 the original author or authors. | ||||||
|  |  * | ||||||
|  |  * Licensed under the Apache License, Version 2.0 (the "License"); | ||||||
|  |  * you may not use this file except in compliance with the License. | ||||||
|  |  * You may obtain a copy of the License at | ||||||
|  |  * | ||||||
|  |  *      https://www.apache.org/licenses/LICENSE-2.0 | ||||||
|  |  * | ||||||
|  |  * Unless required by applicable law or agreed to in writing, software | ||||||
|  |  * distributed under the License is distributed on an "AS IS" BASIS, | ||||||
|  |  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  |  * See the License for the specific language governing permissions and | ||||||
|  |  * limitations under the License. | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | package org.springframework.security.oauth2.core.authorization; | ||||||
|  | 
 | ||||||
|  | import org.junit.jupiter.api.Test; | ||||||
|  | import reactor.core.publisher.Mono; | ||||||
|  | 
 | ||||||
|  | import org.springframework.security.access.AccessDeniedException; | ||||||
|  | import org.springframework.security.authentication.TestingAuthenticationToken; | ||||||
|  | import org.springframework.security.authorization.ReactiveAuthorizationManager; | ||||||
|  | import org.springframework.security.core.Authentication; | ||||||
|  | 
 | ||||||
|  | import static org.assertj.core.api.Assertions.assertThatExceptionOfType; | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * Tests for {@link OAuth2ReactiveAuthorizationManagers} | ||||||
|  |  * | ||||||
|  |  * @author Josh Cummings | ||||||
|  |  */ | ||||||
|  | public class OAuth2ReactiveAuthorizationManagersTests { | ||||||
|  | 
 | ||||||
|  | 	@Test | ||||||
|  | 	void hasScopeWhenInvalidScopeThenThrowIllegalArgument() { | ||||||
|  | 		String scope = "SCOPE_invalid"; | ||||||
|  | 		assertThatExceptionOfType(IllegalArgumentException.class) | ||||||
|  | 				.isThrownBy(() -> OAuth2ReactiveAuthorizationManagers.hasScope(scope)) | ||||||
|  | 				.withMessageContaining("SCOPE_invalid should not start with SCOPE_"); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	@Test | ||||||
|  | 	void hasAnyScopeWhenInvalidScopeThenThrowIllegalArgument() { | ||||||
|  | 		String[] scopes = { "read", "write", "SCOPE_invalid" }; | ||||||
|  | 		assertThatExceptionOfType(IllegalArgumentException.class) | ||||||
|  | 				.isThrownBy(() -> OAuth2ReactiveAuthorizationManagers.hasAnyScope(scopes)) | ||||||
|  | 				.withMessageContaining("SCOPE_invalid should not start with SCOPE_"); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	@Test | ||||||
|  | 	void hasScopeWhenValidScopeThenAuthorizationManager() { | ||||||
|  | 		String scope = "read"; | ||||||
|  | 		ReactiveAuthorizationManager<Object> authorizationManager = OAuth2ReactiveAuthorizationManagers.hasScope(scope); | ||||||
|  | 		authorizationManager.verify(hasScope(scope), new Object()).block(); | ||||||
|  | 		assertThatExceptionOfType(AccessDeniedException.class) | ||||||
|  | 				.isThrownBy(() -> authorizationManager.verify(hasScope("wrong"), new Object()).block()); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	@Test | ||||||
|  | 	void hasAnyScopeWhenValidScopesThenAuthorizationManager() { | ||||||
|  | 		String[] scopes = { "read", "write" }; | ||||||
|  | 		ReactiveAuthorizationManager<Object> authorizationManager = OAuth2ReactiveAuthorizationManagers | ||||||
|  | 				.hasAnyScope(scopes); | ||||||
|  | 		for (String scope : scopes) { | ||||||
|  | 			authorizationManager.verify(hasScope(scope), new Object()).block(); | ||||||
|  | 		} | ||||||
|  | 		assertThatExceptionOfType(AccessDeniedException.class) | ||||||
|  | 				.isThrownBy(() -> authorizationManager.verify(hasScope("wrong"), new Object()).block()); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	Mono<Authentication> hasScope(String scope) { | ||||||
|  | 		return Mono.just(new TestingAuthenticationToken("user", "pass", "SCOPE_" + scope)); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | } | ||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user