Skip to content

Commit 4b04c70

Browse files
committed
Merge remote-tracking branch 'upstream/0.4.x' into main
2 parents a5e6b03 + ce0d1b7 commit 4b04c70

File tree

8 files changed

+59
-6
lines changed

8 files changed

+59
-6
lines changed

oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2ClientCredentialsAuthenticationProvider.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
*/
1616
package org.springframework.security.oauth2.server.authorization.authentication;
1717

18+
import java.util.Collections;
1819
import java.util.LinkedHashSet;
1920
import java.util.Set;
2021

@@ -87,7 +88,7 @@ public Authentication authenticate(Authentication authentication) throws Authent
8788
throw new OAuth2AuthenticationException(OAuth2ErrorCodes.UNAUTHORIZED_CLIENT);
8889
}
8990

90-
Set<String> authorizedScopes = registeredClient.getScopes(); // Default to configured scopes
91+
Set<String> authorizedScopes = Collections.emptySet();
9192
if (!CollectionUtils.isEmpty(clientCredentialsAuthentication.getScopes())) {
9293
for (String requestedScope : clientCredentialsAuthentication.getScopes()) {
9394
if (!registeredClient.getScopes().contains(requestedScope)) {

oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2ClientCredentialsAuthenticationProviderTests.java

+16
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,22 @@ public void authenticateWhenScopeRequestedThenAccessTokenContainsScope() {
211211
assertThat(accessTokenAuthentication.getAccessToken().getScopes()).isEqualTo(requestedScope);
212212
}
213213

214+
@Test
215+
public void authenticateWhenNoScopeRequestedThenAccessTokenDoesNotContainScope() {
216+
RegisteredClient registeredClient = TestRegisteredClients.registeredClient2().build();
217+
OAuth2ClientAuthenticationToken clientPrincipal = new OAuth2ClientAuthenticationToken(
218+
registeredClient, ClientAuthenticationMethod.CLIENT_SECRET_BASIC, registeredClient.getClientSecret());
219+
OAuth2ClientCredentialsAuthenticationToken authentication =
220+
new OAuth2ClientCredentialsAuthenticationToken(clientPrincipal, null, null);
221+
222+
when(this.jwtEncoder.encode(any()))
223+
.thenReturn(createJwt(Collections.singleton("mapped-scoped")));
224+
225+
OAuth2AccessTokenAuthenticationToken accessTokenAuthentication =
226+
(OAuth2AccessTokenAuthenticationToken) this.authenticationProvider.authenticate(authentication);
227+
assertThat(accessTokenAuthentication.getAccessToken().getScopes()).isEmpty();
228+
}
229+
214230
@Test
215231
public void authenticateWhenAccessTokenNotGeneratedThenThrowOAuth2AuthenticationException() {
216232
RegisteredClient registeredClient = TestRegisteredClients.registeredClient2().build();

samples/custom-consent-authorizationserver/src/main/java/sample/config/AuthorizationServerConfig.java

+10
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,17 @@
2828
import org.springframework.core.Ordered;
2929
import org.springframework.core.annotation.Order;
3030
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
31+
import org.springframework.security.config.annotation.web.configurers.oauth2.server.resource.OAuth2ResourceServerConfigurer;
3132
import org.springframework.security.oauth2.core.AuthorizationGrantType;
3233
import org.springframework.security.oauth2.core.ClientAuthenticationMethod;
3334
import org.springframework.security.oauth2.core.oidc.OidcScopes;
35+
import org.springframework.security.oauth2.jwt.JwtDecoder;
3436
import org.springframework.security.oauth2.server.authorization.InMemoryOAuth2AuthorizationConsentService;
3537
import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationConsentService;
3638
import org.springframework.security.oauth2.server.authorization.client.InMemoryRegisteredClientRepository;
3739
import org.springframework.security.oauth2.server.authorization.client.RegisteredClient;
3840
import org.springframework.security.oauth2.server.authorization.client.RegisteredClientRepository;
41+
import org.springframework.security.oauth2.server.authorization.config.annotation.web.configuration.OAuth2AuthorizationServerConfiguration;
3942
import org.springframework.security.oauth2.server.authorization.config.annotation.web.configurers.OAuth2AuthorizationServerConfigurer;
4043
import org.springframework.security.oauth2.server.authorization.settings.ClientSettings;
4144
import org.springframework.security.oauth2.server.authorization.settings.ProviderSettings;
@@ -72,6 +75,7 @@ public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity h
7275
.exceptionHandling(exceptions ->
7376
exceptions.authenticationEntryPoint(new LoginUrlAuthenticationEntryPoint("/login"))
7477
)
78+
.oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt)
7579
.apply(authorizationServerConfigurer);
7680
return http.build();
7781
}
@@ -89,6 +93,7 @@ public RegisteredClientRepository registeredClientRepository() {
8993
.redirectUri("http://127.0.0.1:8080/login/oauth2/code/messaging-client-oidc")
9094
.redirectUri("http://127.0.0.1:8080/authorized")
9195
.scope(OidcScopes.OPENID)
96+
.scope(OidcScopes.PROFILE)
9297
.scope("message.read")
9398
.scope("message.write")
9499
.clientSettings(ClientSettings.builder().requireAuthorizationConsent(true).build())
@@ -104,6 +109,11 @@ public JWKSource<SecurityContext> jwkSource() {
104109
return (jwkSelector, securityContext) -> jwkSelector.select(jwkSet);
105110
}
106111

112+
@Bean
113+
public JwtDecoder jwtDecoder(JWKSource<SecurityContext> jwkSource) {
114+
return OAuth2AuthorizationServerConfiguration.jwtDecoder(jwkSource);
115+
}
116+
107117
@Bean
108118
public ProviderSettings providerSettings() {
109119
return ProviderSettings.builder().issuer("http://localhost:9000").build();

samples/custom-consent-authorizationserver/src/main/java/sample/web/AuthorizationConsentController.java

+9-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2020-2021 the original author or authors.
2+
* Copyright 2020-2022 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -23,6 +23,7 @@
2323
import java.util.Set;
2424

2525
import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames;
26+
import org.springframework.security.oauth2.core.oidc.OidcScopes;
2627
import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationConsent;
2728
import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationConsentService;
2829
import org.springframework.security.oauth2.server.authorization.client.RegisteredClient;
@@ -66,6 +67,9 @@ public String consent(Principal principal, Model model,
6667
authorizedScopes = Collections.emptySet();
6768
}
6869
for (String requestedScope : StringUtils.delimitedListToStringArray(scope, " ")) {
70+
if (OidcScopes.OPENID.equals(requestedScope)) {
71+
continue;
72+
}
6973
if (authorizedScopes.contains(requestedScope)) {
7074
previouslyApprovedScopes.add(requestedScope);
7175
} else {
@@ -95,6 +99,10 @@ public static class ScopeWithDescription {
9599
private static final String DEFAULT_DESCRIPTION = "UNKNOWN SCOPE - We cannot provide information about this permission, use caution when granting this.";
96100
private static final Map<String, String> scopeDescriptions = new HashMap<>();
97101
static {
102+
scopeDescriptions.put(
103+
OidcScopes.PROFILE,
104+
"This application will be able to read your profile information."
105+
);
98106
scopeDescriptions.put(
99107
"message.read",
100108
"This application will be able to read your message."

samples/custom-consent-authorizationserver/src/test/java/sample/CustomConsentAuthorizationServerTests.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2020-2021 the original author or authors.
2+
* Copyright 2020-2022 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -95,7 +95,7 @@ public void whenUserConsentsToAllScopesThenReturnAuthorizationCode() throws IOEx
9595
assertThat(scope.isChecked()).isTrue();
9696
scopeIds.add(scope.getId());
9797
});
98-
assertThat(scopeIds).containsExactlyInAnyOrder("openid", "message.read", "message.write");
98+
assertThat(scopeIds).containsExactlyInAnyOrder("message.read", "message.write");
9999

100100
DomElement submitConsentButton = consentPage.querySelector("button[id='submit-consent']");
101101
this.webClient.getOptions().setRedirectEnabled(false);

samples/default-authorizationserver/src/main/java/sample/config/AuthorizationServerConfig.java

+10-1
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,11 @@
3232
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
3333
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
3434
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
35+
import org.springframework.security.config.annotation.web.configurers.oauth2.server.resource.OAuth2ResourceServerConfigurer;
3536
import org.springframework.security.oauth2.core.AuthorizationGrantType;
3637
import org.springframework.security.oauth2.core.ClientAuthenticationMethod;
3738
import org.springframework.security.oauth2.core.oidc.OidcScopes;
39+
import org.springframework.security.oauth2.jwt.JwtDecoder;
3840
import org.springframework.security.oauth2.server.authorization.JdbcOAuth2AuthorizationConsentService;
3941
import org.springframework.security.oauth2.server.authorization.JdbcOAuth2AuthorizationService;
4042
import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationConsentService;
@@ -63,7 +65,8 @@ public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity h
6365
http
6466
.exceptionHandling(exceptions ->
6567
exceptions.authenticationEntryPoint(new LoginUrlAuthenticationEntryPoint("/login"))
66-
);
68+
)
69+
.oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt);
6770
// @formatter:on
6871
return http.build();
6972
}
@@ -81,6 +84,7 @@ public RegisteredClientRepository registeredClientRepository(JdbcTemplate jdbcTe
8184
.redirectUri("http://127.0.0.1:8080/login/oauth2/code/messaging-client-oidc")
8285
.redirectUri("http://127.0.0.1:8080/authorized")
8386
.scope(OidcScopes.OPENID)
87+
.scope(OidcScopes.PROFILE)
8488
.scope("message.read")
8589
.scope("message.write")
8690
.clientSettings(ClientSettings.builder().requireAuthorizationConsent(true).build())
@@ -111,6 +115,11 @@ public JWKSource<SecurityContext> jwkSource() {
111115
return (jwkSelector, securityContext) -> jwkSelector.select(jwkSet);
112116
}
113117

118+
@Bean
119+
public JwtDecoder jwtDecoder(JWKSource<SecurityContext> jwkSource) {
120+
return OAuth2AuthorizationServerConfiguration.jwtDecoder(jwkSource);
121+
}
122+
114123
@Bean
115124
public ProviderSettings providerSettings() {
116125
return ProviderSettings.builder().issuer("http://localhost:9000").build();

samples/federated-identity-authorizationserver/src/main/java/sample/config/AuthorizationServerConfig.java

+9
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,11 @@
3434
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
3535
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
3636
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
37+
import org.springframework.security.config.annotation.web.configurers.oauth2.server.resource.OAuth2ResourceServerConfigurer;
3738
import org.springframework.security.oauth2.core.AuthorizationGrantType;
3839
import org.springframework.security.oauth2.core.ClientAuthenticationMethod;
3940
import org.springframework.security.oauth2.core.oidc.OidcScopes;
41+
import org.springframework.security.oauth2.jwt.JwtDecoder;
4042
import org.springframework.security.oauth2.server.authorization.JdbcOAuth2AuthorizationConsentService;
4143
import org.springframework.security.oauth2.server.authorization.JdbcOAuth2AuthorizationService;
4244
import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationConsentService;
@@ -62,6 +64,7 @@ public class AuthorizationServerConfig {
6264
@Order(Ordered.HIGHEST_PRECEDENCE)
6365
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
6466
OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http);
67+
http.oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt);
6568
http.apply(new FederatedIdentityConfigurer());
6669
return http.build();
6770
}
@@ -84,6 +87,7 @@ public RegisteredClientRepository registeredClientRepository(JdbcTemplate jdbcTe
8487
.redirectUri("http://127.0.0.1:8080/login/oauth2/code/messaging-client-oidc")
8588
.redirectUri("http://127.0.0.1:8080/authorized")
8689
.scope(OidcScopes.OPENID)
90+
.scope(OidcScopes.PROFILE)
8791
.scope("message.read")
8892
.scope("message.write")
8993
.clientSettings(ClientSettings.builder().requireAuthorizationConsent(true).build())
@@ -114,6 +118,11 @@ public JWKSource<SecurityContext> jwkSource() {
114118
return (jwkSelector, securityContext) -> jwkSelector.select(jwkSet);
115119
}
116120

121+
@Bean
122+
public JwtDecoder jwtDecoder(JWKSource<SecurityContext> jwkSource) {
123+
return OAuth2AuthorizationServerConfiguration.jwtDecoder(jwkSource);
124+
}
125+
117126
@Bean
118127
public ProviderSettings providerSettings() {
119128
return ProviderSettings.builder().issuer("http://localhost:9000").build();

samples/messages-client/src/main/resources/application.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ spring:
2222
client-secret: secret
2323
authorization-grant-type: authorization_code
2424
redirect-uri: "http://127.0.0.1:8080/login/oauth2/code/{registrationId}"
25-
scope: openid
25+
scope: openid, profile
2626
client-name: messaging-client-oidc
2727
messaging-client-authorization-code:
2828
provider: spring

0 commit comments

Comments
 (0)