Selaa lähdekoodia

Merge branch '1.4.x' into 1.5.x

Closes gh-2216
Joe Grandja 1 viikko sitten
vanhempi
commit
ceb75e3135

+ 3 - 2
docs/src/test/java/sample/jpa/JpaTests.java

@@ -1,5 +1,5 @@
 /*
- * Copyright 2020-2024 the original author or authors.
+ * Copyright 2020-2025 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.
@@ -63,6 +63,7 @@ import org.springframework.test.web.servlet.MockMvc;
 import org.springframework.util.StringUtils;
 
 import static org.assertj.core.api.Assertions.assertThat;
+import static sample.util.RegisteredClients.deviceMessagingClient;
 import static sample.util.RegisteredClients.messagingClient;
 
 /**
@@ -140,7 +141,7 @@ public class JpaTests {
 		assertThat(this.authorizationService).isInstanceOf(JpaOAuth2AuthorizationService.class);
 		assertThat(this.authorizationConsentService).isInstanceOf(JpaOAuth2AuthorizationConsentService.class);
 
-		RegisteredClient registeredClient = messagingClient();
+		RegisteredClient registeredClient = deviceMessagingClient();
 		this.registeredClientRepository.save(registeredClient);
 
 		DeviceAuthorizationGrantFlow deviceAuthorizationGrantFlow = new DeviceAuthorizationGrantFlow(this.mockMvc);

+ 5 - 2
docs/src/test/java/sample/redis/RedisTests.java

@@ -1,5 +1,5 @@
 /*
- * Copyright 2020-2024 the original author or authors.
+ * Copyright 2020-2025 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.
@@ -63,6 +63,8 @@ import static org.assertj.core.api.Assertions.assertThat;
 public class RedisTests {
 	private static final RegisteredClient TEST_MESSAGING_CLIENT = RegisteredClients.messagingClient();
 
+	private static final RegisteredClient TEST_DEVICE_MESSAGING_CLIENT = RegisteredClients.deviceMessagingClient();
+
 	@Autowired
 	private MockMvc mockMvc;
 
@@ -126,7 +128,7 @@ public class RedisTests {
 		assertThat(this.authorizationService).isInstanceOf(RedisOAuth2AuthorizationService.class);
 		assertThat(this.authorizationConsentService).isInstanceOf(RedisOAuth2AuthorizationConsentService.class);
 
-		RegisteredClient registeredClient = TEST_MESSAGING_CLIENT;
+		RegisteredClient registeredClient = TEST_DEVICE_MESSAGING_CLIENT;
 
 		DeviceAuthorizationGrantFlow deviceAuthorizationGrantFlow = new DeviceAuthorizationGrantFlow(this.mockMvc);
 		deviceAuthorizationGrantFlow.setUsername("user");
@@ -194,6 +196,7 @@ public class RedisTests {
 		void postConstruct() throws IOException {
 			this.redisServer.start();
 			this.registeredClientRepository.save(TEST_MESSAGING_CLIENT);
+			this.registeredClientRepository.save(TEST_DEVICE_MESSAGING_CLIENT);
 		}
 
 		@PreDestroy

+ 17 - 1
docs/src/test/java/sample/util/RegisteredClients.java

@@ -1,5 +1,5 @@
 /*
- * Copyright 2020-2023 the original author or authors.
+ * Copyright 2020-2025 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.
@@ -46,4 +46,20 @@ public class RegisteredClients {
 				.build();
 	}
 	// @formatter:on
+
+	// @formatter:off
+	public static RegisteredClient deviceMessagingClient() {
+		return RegisteredClient.withId(UUID.randomUUID().toString())
+				.clientId("device-messaging-client")
+				.clientSecret("{noop}secret")
+				.clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC)
+				.authorizationGrantType(AuthorizationGrantType.DEVICE_CODE)
+				.authorizationGrantType(AuthorizationGrantType.REFRESH_TOKEN)
+				.scope("message.read")
+				.scope("message.write")
+				.clientSettings(ClientSettings.builder().requireAuthorizationConsent(true).build())
+				.build();
+	}
+	// @formatter:on
+
 }

+ 5 - 1
oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2DeviceAuthorizationRequestAuthenticationProvider.java

@@ -1,5 +1,5 @@
 /*
- * Copyright 2020-2024 the original author or authors.
+ * Copyright 2020-2025 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.
@@ -39,6 +39,7 @@ import org.springframework.security.oauth2.core.OAuth2Error;
 import org.springframework.security.oauth2.core.OAuth2ErrorCodes;
 import org.springframework.security.oauth2.core.OAuth2UserCode;
 import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames;
+import org.springframework.security.oauth2.core.oidc.OidcScopes;
 import org.springframework.security.oauth2.server.authorization.OAuth2Authorization;
 import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationService;
 import org.springframework.security.oauth2.server.authorization.OAuth2TokenType;
@@ -120,6 +121,9 @@ public final class OAuth2DeviceAuthorizationRequestAuthenticationProvider implem
 					throwError(OAuth2ErrorCodes.INVALID_SCOPE, OAuth2ParameterNames.SCOPE);
 				}
 			}
+			if (requestedScopes.contains(OidcScopes.OPENID)) {
+				throwError(OAuth2ErrorCodes.INVALID_SCOPE, OAuth2ParameterNames.SCOPE);
+			}
 		}
 
 		if (this.logger.isTraceEnabled()) {

+ 19 - 1
oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2DeviceAuthorizationRequestAuthenticationProviderTests.java

@@ -1,5 +1,5 @@
 /*
- * Copyright 2020-2023 the original author or authors.
+ * Copyright 2020-2025 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.
@@ -34,6 +34,7 @@ import org.springframework.security.oauth2.core.OAuth2Error;
 import org.springframework.security.oauth2.core.OAuth2ErrorCodes;
 import org.springframework.security.oauth2.core.OAuth2UserCode;
 import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames;
+import org.springframework.security.oauth2.core.oidc.OidcScopes;
 import org.springframework.security.oauth2.server.authorization.OAuth2Authorization;
 import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationService;
 import org.springframework.security.oauth2.server.authorization.client.RegisteredClient;
@@ -165,6 +166,23 @@ public class OAuth2DeviceAuthorizationRequestAuthenticationProviderTests {
 		// @formatter:on
 	}
 
+	@Test
+	public void authenticateWhenOpenIdScopeThenThrowOAuth2AuthenticationException() {
+		RegisteredClient registeredClient = TestRegisteredClients.registeredClient()
+			.authorizationGrantType(AuthorizationGrantType.DEVICE_CODE)
+			.scope(OidcScopes.OPENID)
+			.build();
+		Authentication authentication = createAuthentication(registeredClient);
+		// @formatter:off
+		assertThatExceptionOfType(OAuth2AuthenticationException.class)
+				.isThrownBy(() -> this.authenticationProvider.authenticate(authentication))
+				.withMessageContaining(OAuth2ParameterNames.SCOPE)
+				.extracting(OAuth2AuthenticationException::getError)
+				.extracting(OAuth2Error::getErrorCode)
+				.isEqualTo(OAuth2ErrorCodes.INVALID_SCOPE);
+		// @formatter:on
+	}
+
 	@Test
 	public void authenticateWhenDeviceCodeIsNullThenThrowOAuth2AuthenticationException() {
 		@SuppressWarnings("unchecked")